Iris
Iris

Reputation:

Using CSS to affect div style inside iframe

Is it possible to change styles of a div that resides inside an iframe on the page using CSS only?

Upvotes: 343

Views: 645830

Answers (14)

Riyaz Hameed
Riyaz Hameed

Reputation: 1103

If it is loaded from the same host (since CORS became standard), you can retrieve the contents of an iframe first and then use jQuery selectors against them as usual.

$("#iframe-id").contents().find("img").attr("style","width:100%;height:100%")

$("#iframe-id").contents().find("img").addClass("fancy-zoom")

$("#iframe-id").contents().find("img").onclick(function(){ zoomit($(this)); });

Good Luck!

Upvotes: 12

Aris
Aris

Reputation: 5055

If the iframe comes from another server, you will have CORS ERRORS like:

Uncaught DOMException: Blocked a frame with origin "https://your-site.com" from accessing a cross-origin frame.

Only in the case you have control of both pages, you can use https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage to safely send messages like this:

On you main site(one that loads the iframe):

const iframe = document.querySelector('#frame-id');
iframe.contentWindow.postMessage(/*any variable or object here*/, 'https://iframe-site.example.com');

on the iframe site:

// Called sometime after postMessage is called
window.addEventListener("message", (event) => {
  // Do we trust the sender of this message?
  if (event.origin !== "http://your-main-site.com")
    return;
...
...
  
});

Upvotes: 3

Eugene Rosenfeld
Eugene Rosenfeld

Reputation: 780

Yes. Take a look at this other thread for details: How to apply CSS to iframe?

const cssLink = document.createElement("link");
cssLink.href  = "style.css";  
cssLink.rel   = "stylesheet";  
cssLink.type  = "text/css";  
frames['frame1'].contentWindow.document.body.appendChild(cssLink); 
//     ^frame1 is the #id of the iframe: <iframe id="frame1">

Upvotes: 54

Rami Alloush
Rami Alloush

Reputation: 2636

Combining the different solutions, this is what worked for me.

$(document).ready(function () {
    $('iframe').on('load', function() {
        $("iframe").contents().find("#back-link").css("display", "none");
    }); 
});

Upvotes: 6

Wahab Ahmed
Wahab Ahmed

Reputation: 197

Just add this and all works well:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

Upvotes: 0

mmattax
mmattax

Reputation: 27710

In short no.

You can not apply CSS to HTML that is loaded in an iframe, unless you have control over the page loaded in the iframe due to cross-domain resource restrictions.

Upvotes: 156

adamj
adamj

Reputation: 4792

Apparently it can be done via jQuery:

$('iframe').load( function() {
    $('iframe').contents().find("head")
      .append($("<style type='text/css'>  .my-class{display:none;}  </style>"));
});

https://stackoverflow.com/a/13959836/1625795

Upvotes: 6

Cole Busby
Cole Busby

Reputation: 408

A sort of hack-ish way of doing things is like Eugene said. I ended up following his code and linking to my custom Css for the page. The problem for me was that, With a twitter timeline you have to do some sidestepping of twitter to override their code a smidgen. Now we have a rolling timeline with our css to it, I.E. Larger font, proper line height and making the scrollbar hidden for heights larger than their limits.

var c = document.createElement('link');
setTimeout(frames[0].document.body.appendChild(c),500); // Mileage varies by connection. Bump 500 a bit higher if necessary

Upvotes: 1

Chdid
Chdid

Reputation: 290

Not possible from client side . A javascript error will be raised "Error: Permission denied to access property "document"" since the Iframe is not part of your domaine. The only solution is to fetch the page from the server side code and change the needed CSS.

Upvotes: 1

Priyank Gupta
Priyank Gupta

Reputation: 803

Use Jquery and wait till the source is loaded, This is how I have achieved(Used angular interval, you can use javascript setInterval method):

var addCssToIframe = function() {
    if ($('#myIframe').contents().find("head") != undefined) {
        $('#myIframe')
                .contents()
                .find("head")
                .append(
                        '<link rel="stylesheet" href="app/css/iframe.css" type="text/css" />');
        $interval.cancel(addCssInterval);
    }
};
var addCssInterval = $interval(addCssToIframe, 500, 0, false);

Upvotes: 9

Diodeus - James MacFarlane
Diodeus - James MacFarlane

Reputation: 114447

You need JavaScript. It is the same as doing it in the parent page, except you must prefix your JavaScript command with the name of the iframe.

Remember, the same origin policy applies, so you can only do this to an iframe element which is coming from your own server.

I use the Prototype framework to make it easier:

frame1.$('mydiv').style.border = '1px solid #000000'

or

frame1.$('mydiv').addClassName('withborder')

Upvotes: 153

eric wiedemann
eric wiedemann

Reputation: 25

Yes, it's possible although cumbersome. You would need to print/echo the HTML of the page into the body of your page then apply a CSS rule change function. Using the same examples given above, you would essentially be using a parsing method of finding the divs in the page, and then applying the CSS to it and then reprinting/echoing it out to the end user. I don't need this so I don't want to code that function into every item in the CSS of another webpage just to aphtply.

References:

Upvotes: 0

Justin Lucente
Justin Lucente

Reputation: 1171

The quick answer is: No, sorry.

It's not possible using just CSS. You basically need to have control over the iframe content in order to style it. There are methods using javascript or your web language of choice (which I've read a little about, but am not to familiar with myself) to insert some needed styles dynamically, but you would need direct control over the iframe content, which it sounds like you do not have.

Upvotes: 13

Al W
Al W

Reputation: 7713

probably not the way you are thinking. the iframe would have to <link> in the css file too. AND you can't do it even with javascript if it's on a different domain.

Upvotes: 3

Related Questions