Внедрение CSS в HTML документ.
В этой главе речь пойдет о том, как внедрить CSS в документ HTML, то есть связать стилевое описание элемента непосредственно с самим элементом, каким либо HTML тегом.
Осуществить данную задачу можно тремя способами:
- Написать стилевое описание непосредственно в самом элементе. Такой способ хорош лишь в том случае если таковой элемент один единственный в HTML документе который нуждается в отдельном стилевом описании.
- Написать стилевое описание для всех идентичных элементов HTML документа. Такой способ оправдывает себя, если стиль страницы принципиально отличается от общего дизайна сайта (группы взаимосвязанных страниц).
- Вынести стилевое описание элементов HTML в отдельный файл CSS. Это позволит управлять дизайном всего сайта целиком, каждой страницей сайта в которой указанно обращение к CSS файлу. Этот способ является наиболее эффективным использованием таблицы каскадных стилей.
Давайте более подробно рассмотрим каждый вариант, а заодно познакомимся с правилами синтаксиса написания CSS.
Атрибут style.
Практически каждый HTML тег имеет атрибут style , который говорит о том, что к этому тегу применяется некое стилевое описание.
style=»»> это параграф с индивидуальным стилем
Всё что будет написано между кавычками атрибута style и будет являться стилевым описанием для данного элемента, в данном случае элемента
В данном случае мы указали, что этот параграф должен отображаться красным цветом и иметь размер шрифта в 12 пикселей. В последующих главах я подробно расскажу о том что написано в кавычках , сейчас же речь идет о том как применить CSS к какому либо HTML тегу.
По такому же принципу можно указать индивидуальный стиль практически для каждого HTML элемента.
style=»background-color: #c5ffa0″>
style=»color: #0000ff; font-size:18px»>Всё о слонах
style=»color: #ff0000; font-size:14px»>На этом сайте Вы найдёте любую информацию о слонах.
style=»color: #0000ff; font-size:16px»>Купить слона
style=»color: #ff0000; font-size:14px»>У нас Вы можете по выгодным ценам приобрести лучших слонов!!
style=»color: #0000ff; font-size:16px»>Взять слона на прокат
style=»color: #ff0000; font-size:14px»>Только у нас Вы можете взять любых слонов на прокат!!
!DOCTYPE>
Но еще раз повторюсь такой способ внедрения CSS хорош лишь в том случае если требуется задать определенный стиль малому числу HTML элементов.
Тег
Для того, что бы описать необходимые элементы одновременно на всей странице в заголовок HTML документа внедряют тег (не путайте с одноименным атрибутом) в котором и происходит описание нужных нам элементов.
Взгляните на пример, ниже к нему будут комментарии.
body
h1
h2
p
Всё о слонах
На этом сайте Вы найдёте любую информацию о слонах.
Купить слона
У нас Вы можете по выгодным ценам приобрести лучших слонов!!
Взять слона на прокат
Только у нас Вы можете взять любых слонов на прокат!!
!DOCTYPE>
Как видно из примера мы добились точно такого же результата что и в первом случае только теперь мы не прописываем каждому элементу стиль индивидуально, а вынесли его в «голову» документа тем самым указав что все заголовки , — будут синими а параграфы — красными. Представьте как мы облегчили бы себе работу будь на странице сотня таких параграфов и штук пятнадцать заголовков, да и сам документ стал меньше весить за счет «удаления» всех повторяющихся стилевых описаний для каждого отдельно взятого элемента.
Теперь обещанные комментарии:
Тег принято внедрять в заголовок HTML документа между тегами .
Атрибут тега type — сообщает браузеру, какой синтаксис использовать для правильной интерпретации стилей. Для правильной интерпретации браузерами CSS значение type (MIME тип данных) должно равняться text/css .
Внутри тега идет непосредственное объявление стилей тех или иных HTML элементов согласно следующему синтаксису:
Если в блоке объявления стилей указывается несколько свойств элемента, то они между собой разделяются точкой с запятой.
CSS в отдельном внешнем файле.
Долго ли коротко ли, подошли мы к главному, на мой взгляд, достоинству CSS, а именно возможности выносить все сведения касающиеся дизайна сайта в отдельный внешний файл.
Итак, открываем блокнот (или другой редактор) и пишем в нем следующий текст:
body
a
a:hover
h1
h2
p
О том, что это такое странное мы написали, постараюсь подробно рассказать в последующих главах этого учебника.
Далее сохраняем этот небольшой файлик с расширением *.css (обычно файл со стилями называют style.css).
Все! файл со стилевым описанием создан! Теперь осталось совсем чуть чуть, а именно заставить нужные страницы нашего сайта черпать информацию с этого файла.
Делается это с помощью тега (связь). Тег многоцелевой и служит для «связывания» HTML документа с дополнительными внешними файлами, обеспечивающими его должную работу. Тег является своего рода ссылкой, только предназначенной не для пользователей, а для программ обозревателей (браузеров). Так как несёт в себе исключительно служебную информацию он располагается в заголовке HTML документа между тегами и не выводится браузерами на экран.
Тег имеет атрибуты:
- shortcut icon — Определяет, что подключаемый файл является иконкой.
- stylesheet — Определяет, что подключаемый файл содержит таблицу стилей.
- application/rss+xml — Файл в формате XML для описания ленты новостей.
Так как мы подключаем в качестве внешнего файла каскадную таблицу стилей, то наша служебная ссылка приобретает следующий вид:
Повторюсь, что бы уж точно развеять возможные недопонимания. Атрибуту rel присваиваем значение stylesheet так как подключаем в качестве внешнего файла каскадную таблицу стилей, указываем путь к файлу css (в этом примере файл называется mystyle.css и лежит рядом с документом HTML в котором прописывается данная ссылка) так же указываем, что данный файл текстовый и содержит в себе стилевое описание type=»text/css»
Теперь вставляем эту строчку в заголовки страниц нашего сайта и наслаждаемся результатом..
Файл mystyle.css
body
a
a:hover
h1
h2
p
Файл index.html
Меню:
Всё о слонах.
Купить слона.
Взять слона на прокат.
Всё о слонах
На этом сайте Вы найдёте любую информацию о слонах.
Файл elephant.html
Меню:
Всё о слонах.
Купить слона.
Взять слона на прокат.
Купить слона
У нас Вы можете по выгодным ценам приобрести лучших слонов!!
Файл elephant1.html
Меню:
Всё о слонах.
Купить слона.
Взять слона на прокат.
Взять слона на прокат
Только у нас Вы можете взять любых слонов на прокат!!
В примере выше, «сайт о слонах», на данный момент, имеется три страницы, каждая из которых связана с одним единственным внешним css файлом — mystyle.css. Таким образом, мы значительно его «разгрузили» и сделали дизайн всего сайта «мобильным». Представьте сколько б килобайт мы выиграли, будь на этом сайте сотня полноценных страниц!? А также, сколько б времени сэкономили, если бы нам понадобилось изменить что-либо в его дизайне!?
О том как присвоить какой либо группе идентичных элементов стиль отличающийся от основного стиля данного элемента, сделать отдельный класс элементов, читайте в главе Классы и идентификаторы.
Полезные советы:
В этой главе мы рассмотрели три способа внедрения CSS в HTML документ. Какой же лучше использовать?
- Используйте атрибут style для какого либо элемента если этот элемент с отличным от других элементов стилем один единственный на всём сайте.
- Используйте тег со стилевым описанием, в том случае, если страница должна иметь индивидуальный дизайн в корни отличный от других страниц сайта.
- В большинстве случаев разумно выносить каскадную таблицу стилей в отдельный css файл.
How to apply CSS to iframe?
I have a simple page that has some iframe sections (to display RSS links). How can I apply the same CSS format from the main page to the page displayed in the iframe?
1,735 9 9 silver badges 22 22 bronze badges
asked Oct 20, 2008 at 8:27
It is possible but only if the iframe’s domain is the same as the parent
Jun 30, 2010 at 23:50
gawpertron, just to clarify, are you saying if I use iFrame content from some other domain that I don’t control, there is no way for me to control the CSS for that content?
Dec 14, 2010 at 0:19
Can you list a link to the page so that we might just be able to view our changes.
– user3376708
Jul 15, 2014 at 13:21
The domain, port and protocol have to be the same, doesn’t work with subdomains either.
Nov 11, 2014 at 22:19
28 Answers 28
Edit: This does not work cross domain unless the appropriate CORS header is set.
There are two different things here: the style of the iframe block and the style of the page embedded in the iframe. You can set the style of the iframe block the usual way:
The style of the page embedded in the iframe must be either set by including it in the child page:
Or it can be loaded from the parent page with Javascript:
var cssLink = document.createElement("link"); cssLink.href = "style.css"; cssLink.rel = "stylesheet"; cssLink.type = "text/css"; frames['iframe1'].document.head.appendChild(cssLink);
6,010 4 4 gold badges 29 29 silver badges 35 35 bronze badges
answered Oct 20, 2008 at 9:07
Tamas Czinege Tamas Czinege
119k 40 40 gold badges 151 151 silver badges 176 176 bronze badges
Please note, it seems to me like some of the examples posted before are now invalid for html5. You can access the frame’s contents as follows: document.getElementById(«myframe»).contentDocument . Embedding the css still doesn’t seem to work for me though.
Feb 2, 2011 at 19:54
link may only appear in the HEAD
May 23, 2011 at 19:05
Worked for me only when I did . document.head.appendChild(cssLink) — Firefox and Safari.
Sep 26, 2011 at 12:47
Does this actually work cross-domain? I don’t think it would.
Nov 4, 2011 at 0:52
Just so no1 else has to test it to find out: correct, it doesn’t work cross-domain. Immediately upon doing frames[‘name’] you get «Unsafe JavaScript attempt to access frame with URL blah from frame with URL blah. Domains, protocols and ports must match.»
Nov 27, 2011 at 17:37
I met this issue with Google Calendar. I wanted to style it on a darker background and change font.
Luckily, the URL from the embed code had no restriction on direct access, so by using PHP function file_get_contents it is possible to get the entire content from the page. Instead of calling the Google URL, it is possible to call a php file located on your server, ex. google.php , which will contain the original content with modifications:
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
Adding the path to your stylesheet:
$content = str_replace('','', $content);
(This will place your stylesheet last just before the head end tag.)
Specify the base url form the original url in case css and js are called relatively:
$content = str_replace('','', $content);
The final google.php file should look like this:
','', $content); $content = str_replace('','', $content); echo $content;
Then you change the iframe embed code to:
1,093 2 2 gold badges 18 18 silver badges 29 29 bronze badges
answered Sep 20, 2012 at 22:21
SequenceDigitale.com SequenceDigitale.com
4,048 1 1 gold badge 25 25 silver badges 23 23 bronze badges
You can call that hacking by definition if you want. But you didn’t offer any better solution. This solution is not a way to dammage Google service or to trick people in a way to exploit their weakness.
Aug 12, 2014 at 16:58
I would kill for a way to make this solution work with google docs. Its throwing all sorts of javascript errors. «Uncaught TypeError: Cannot read property ‘a’ of undefined «
Aug 19, 2014 at 23:52
@ChrisHoughton FYI, it basically isn’t. It might, however, render the entire iframe pointless (one reason for using iframes, for instance, is for security purposes, e.g. with card payments, and if you do what is suggested here you’ll probably cause yourself problems).
Feb 5, 2015 at 16:31
By doing this you are always getting the calendar as a non-logged in user. With the normal html iframe the user would see their own personal calendar if they were logged into google, but since your PHP code can’t know the users Google session ID it can’t fetch their personal calendar.
Jan 10, 2017 at 15:10
If the content of the iframe is not completely under your control or you want to access the content from different pages with different styles you could try manipulating it using JavaScript.
var frm = frames['frame'].document; var otherhead = frm.getElementsByTagName("head")[0]; var link = frm.createElement("link"); link.setAttribute("rel", "stylesheet"); link.setAttribute("type", "text/css"); link.setAttribute("href", "style.css"); otherhead.appendChild(link);
Note that depending on what browser you use this might only work on pages served from the same domain.
764 4 4 silver badges 20 20 bronze badges
answered Oct 20, 2008 at 8:58
Horst Gutmann Horst Gutmann
11k 2 2 gold badges 29 29 silver badges 31 31 bronze badges
Might be worth noting that the same origin policy will stop this working if the page is on a different domain.
Oct 20, 2008 at 9:00
In the same line of thinking but more succinct:
Sep 26, 2016 at 12:35
Even Firefox has gone CORS
– user985399
Dec 25, 2019 at 8:04
The snippet worked for me.
Sep 30, 2020 at 9:30
var frm = frames[‘frame’].document; should be var frm = window.frames[‘frame’].document; . Nevertheless, still doesn’t work, document comes back as undefined.
Jan 17, 2021 at 13:52
var $head = $("#eFormIFrame").contents().find("head"); $head.append($("", < rel: "stylesheet", href: url, type: "text/css" >));
596 1 1 gold badge 6 6 silver badges 18 18 bronze badges
answered Nov 21, 2012 at 16:17
Rami Sarieddine Rami Sarieddine
5,404 35 35 silver badges 41 41 bronze badges
Here is how to apply CSS code directly without using to load an extra stylesheet.
var head = jQuery("#iframe").contents().find("head"); var css = ''; jQuery(head).append(css);
This hides the banner in the iframe page. Thank you for your suggestions!
596 1 1 gold badge 6 6 silver badges 18 18 bronze badges
answered Oct 15, 2013 at 22:47
1,480 18 18 silver badges 20 20 bronze badges
Does this also get around the CORS restrictions?
Oct 29 at 21:47
If you control the page in the iframe, as hangy said, the easiest approach is to create a shared CSS file with common styles, then just link to it from your html pages.
Otherwise it is unlikely you will be able to dynamically change the style of a page from an external page in your iframe. This is because browsers have tightened the security on cross frame dom scripting due to possible misuse for spoofing and other hacks.
This tutorial may provide you with more information on scripting iframes in general. About cross frame scripting explains the security restrictions from the IE perspective.
answered Oct 20, 2008 at 8:52
61.2k 31 31 gold badges 152 152 silver badges 169 169 bronze badges
An iframe is universally handled like a different HTML page by most browsers. If you want to apply the same stylesheet to the content of the iframe, just reference it from the pages used in there.
30.7k 22 22 gold badges 106 106 silver badges 131 131 bronze badges
answered Oct 20, 2008 at 8:37
10.8k 6 6 gold badges 44 44 silver badges 63 63 bronze badges
@hangry but. how?
Jan 17, 2018 at 17:45
The above with a little change works:
var cssLink = document.createElement("link") cssLink.href = "pFstylesEditor.css"; cssLink.rel = "stylesheet"; cssLink.type = "text/css"; //Instead of this //frames['frame1'].document.body.appendChild(cssLink); //Do this var doc=document.getElementById("edit").contentWindow.document; //If you are doing any dynamic writing do that first doc.open(); doc.write(myData); doc.close(); //Then append child doc.body.appendChild(cssLink);
Works fine with ff3 and ie8 at least
596 1 1 gold badge 6 6 silver badges 18 18 bronze badges
answered Jul 28, 2009 at 22:53
Tom Merchant Tom Merchant
The following worked for me.
var iframe = top.frames[name].document; var css = '' + ''; iframe.open(); iframe.write(css); iframe.close();
596 1 1 gold badge 6 6 silver badges 18 18 bronze badges
answered May 23, 2011 at 16:22
159 1 1 silver badge 2 2 bronze badges
Expanding on the above jQuery solution to cope with any delays in loading the frame contents.
$('iframe').each(function()< function injectCSS()< $iframe.contents().find('head').append( $('', < rel: 'stylesheet', href: 'iframe.css', type: 'text/css' >) ); > var $iframe = $(this); $iframe.on('load', injectCSS); injectCSS(); >);
answered Jun 24, 2013 at 11:14
David Bradshaw David Bradshaw
12.1k 3 3 gold badges 41 41 silver badges 70 70 bronze badges
use can try this:
$('iframe').load( function() < $('iframe').contents().find("head") .append($(".my-class ")); >);
answered Sep 1, 2017 at 10:15
Therichpost Therichpost
1,769 2 2 gold badges 14 14 silver badges 19 19 bronze badges
If your iframe comes from different origin, the CORS mechanism will not allow this workarround.
Nov 9, 2017 at 13:14
If you want to reuse CSS and JavaScript from the main page maybe you should consider replacing with a Ajax loaded content. This is more SEO friendly now when search bots are able to execute JavaScript.
This is jQuery example that includes another html page into your document. This is much more SEO friendly than iframe . In order to be sure that the bots are not indexing the included page just add it to disallow in robots.txt
You could also include jQuery directly from Google: http://code.google.com/apis/ajaxlibs/documentation/ — this means optional auto-inclusion of newer versions and some significant speed increase. Also, means that you have to trust them for delivering you just the jQuery 😉
24.3k 16 16 gold badges 69 69 silver badges 69 69 bronze badges
answered Mar 2, 2010 at 7:16
163k 182 182 gold badges 541 541 silver badges 807 807 bronze badges
My compact version:
However, sometimes the iframe is not ready on window loaded, so there is a need of using a timer.
Ready-to-use code (with timer):
. and jQuery link:
6,580 5 5 gold badges 44 44 silver badges 68 68 bronze badges
answered Mar 21, 2013 at 9:07
1,582 21 21 silver badges 27 27 bronze badges
As many answers are written for the same domains, I’ll write how to do this in cross domains.
First, you need to know the Post Message API. We need a messenger to communicate between two windows.
Here’s a messenger I created.
/** * Creates a messenger between two windows * which have two different domains */ class CrossMessenger < /** * * @param otherWindow - window object of the other * @param targetDomain - domain of the other window * @param eventHandlers - all the event names and handlers */ constructor(otherWindow, targetDomain, eventHandlers = <>) < this.otherWindow = otherWindow; this.targetDomain = targetDomain; this.eventHandlers = eventHandlers; window.addEventListener("message", (e) =>this.receive.call(this, e)); > post(event, data) < try < // data obj should have event name var json = JSON.stringify(< event, data >); this.otherWindow.postMessage(json, this.targetDomain); > catch (e) <> > receive(e) < var json; try < json = JSON.parse(e.data ? e.data : "<>"); > catch (e) < return; >var eventName = json.event, data = json.data; if (e.origin !== this.targetDomain) return; if (typeof this.eventHandlers[eventName] === "function") this.eventHandlers[eventName](data); > >
Using this in two windows to communicate can solve your problem.
In the main windows,
var msger = new CrossMessenger(iframe.contentWindow, "https://iframe.s.domain"); var cssContent = Array.prototype.map.call(yourCSSElement.sheet.cssRules, css_text).join('\n'); msger.post("cssContent", < css: cssContent >)
Then, receive the event from the Iframe.
var msger = new CrossMessenger(window.parent, "https://parent.window.domain", < cssContent: (data) => < var cssElem = document.createElement("style"); cssElem.innerHTML = data.css; document.head.appendChild(cssElem); >>)
See the Complete Javascript and Iframes tutorial for more details.
