<html>
<body>
<style type="text/css">
p.first {color:blue}
p.second {color:green}
</style>
<p class="first">Hello World</p>
<p class="second">Hello World</p>
<style type="text/css">
p.first {color:green}
p.second {color:blue}
</style>
<p class="first">Hello World</p>
<p class="second">Hello World</p>
</body>
</html>
How is a browser supposed to render css which is non contiguous? Is it supposed to generate some data structure using all the css styles on a page and use that for rendering?
Or does it render using style information in the order it sees?
Because this is HTML is not valid does not have any affect on the outcome ... it just means that the HTML does adhere to the standard (merely for organizational purposes). For the sake of being valid it could have been written this way:
<html>
<head>
<style type="text/css">
p.first {color:blue}
p.second {color:green}
</style>
</head>
<body>
<p class="first" style="color:green;">Hello World</p>
<p class="second" style="color:blue;">Hello World</p>
My guess is that the browser applies the last style it comes across.
I guess this may be an issue about limited contexts, e.g. WYIWYG editors on a web system used by not-programmers users, that limits the possibilities of follow the standards. Sometimes (like TinyMCE), it's a lib that puts your content/code inside a textarea
tag, that is rendered by the editor as a big div
tag. And sometimes, it may be an old version of these editors.
I'm supposing that:
stylesheets
. Actually, it would be impractical for the admins (or webdevs), considering the number of requests in that sense that they would have.In some cases, without use style
rules, it may be a very poor design experience. So, yes, these users need customization. Okay, but what would be the solutions, in this scenario? Considering the different ways to insert CSS in a html
page, I suppose these solutions:
Ask to your system adm for including some CSS rules at the system's stylesheets
. This will be an external or internal CSS solution. As already said, it might be not possible.
<link>
on <body>
Use external style sheet on the body
tag, i.e., use of the link
tag inside the area you have access (that will be, on the site, inside the body
tag and not in the head
tag). Some sources says this is okay, but "not a good practice", like MDN:
A
<link>
element can occur either in the<head>
or<body>
element, depending on whether it has a link type that is body-ok. For example, thestylesheet
link type is body-ok, and therefore<link rel="stylesheet">
is permitted in the body. However, this isn't a good practice to follow; it makes more sense to separate your<link>
elements from your body content, putting them in the<head>
.
Some others, restrict it to the <head>
section, like w3schools:
Note: This element goes only in the head section, but it can appear any number of times.
I tested it here (desktop environment, on a browser) and it works for me.
Create a file foo.html
:
<!DOCTYPE html>
<html>
<head></head>
<body>
<link href="bar.css" type="text/css" rel="stylesheet">
<h1 class="test1">Hello</h1>
<h1 class="test2">World</h1>
</body>
</html>
And then a CSS file, at the same directory, called bar.css
:
.test1 {
color: green;
};
Well, this will just looks possible if you have how upload an CSS file somewhere at the institution system. Maybe this would be the case.
<style>
on <body>
Use internet style sheet on the body
tag, i.e., use of the style
tag inside the area you have access (that will be, on the site, inside the body
tag and not in the head
tag). This is what Charles Salvia's and Sz's answers here are about. Choosing this option, consider their concerns.
Alert
These ones are related to modifying the <head>
element of the page. Maybe this will not be allowed by the institution's system administrators. So, it's recommended to ask them permission first.
Okay, supposing permission granted, the strategy is access the <head>
. How? JavaScript methods.
<link>
on <head>
This is another version of the 2nd option. Use external style sheet on the <head>
tag, i.e., use of the <link>
element outside the area you have access (that will be, on the site, not inside the body
tag and yes inside the head
tag). This solution complies with the recommendations of MDN and w3schools, as cited above, on 2nd option solution. A new Link
object will be created.
To solve the matter through JS, there are many ways but at the following codelines I demonstrate one simple.
I tested it here (desktop environment, on a browser) and it works for me.
Create a file f.html
:
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1 class="test1">Hello</h1>
<h1 class="test2">World</h1>
<script>
// JS code here
</script>
</body>
</html>
Inside the script
tag:
var newLink = document.createElement("link");
newLink.href = "bar.css";
newLink.rel = "stylesheet";
newLink.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(newLink);
And then at the CSS file, at the same directory, called bar.css
(as at the 2nd option):
.test1 {
color: green;
};
As I already said: this will just looks possible if you have how upload an CSS file somewhere at the institution system.
<style>
on <head>
Use new internal style sheet on the <head>
tag, i.e., use of a new <style>
element outside the area you have access (that will be, on the site, not inside the body
tag and yes inside the head
tag). A new Style
object will be created.
This is solved through JS. One simple way is demonstrated following.
I tested it here (desktop environment, on a browser) and it works for me.
Create a file foobar.html
:
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1 class="test1">Hello</h1>
<h1 class="test2">World</h1>
<script>
// JS code here
</script>
</body>
</html>
Inside the script
tag:
var newStyle = document.createElement("style");
newStyle.innerHTML =
"h1.test1 {"+
"color: green;"+
"}";
document.getElementsByTagName("head")[0].appendChild(newStyle);
<style>
on <head>
Use an existing internal style sheet on the <head>
tag, i.e., use of a <style>
element outside the area you have access (that will be, on the site, not inside the body
tag and yes inside the head
tag), if some exists. A new Style
object will be created or a CSSStyleSheet
object will be used (in the code of the solution adopted here).
This is at some point of view risky.
First, because it may not exists some <style>
object. Depending of the way you implement this solution, you may get undefined
return (the system may use external style sheet).
Second, because you will be editing the system design author's work (authorship issues).
Third, because it may not be allowed at your institution's IT politics of safety.
So, do ask permission to do this (as at in other JS solutions).
Supposing, again, permission was granted:
You will need to consider some restrictions of the method available to this way: insertRule()
. The solution proposed uses the default scenario, and a operation at the first stylesheet
, if some exists.
I tested it here (desktop environment, on a browser) and it works for me.
Create a file foo_bar.html
:
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1 class="test1">Hello</h1>
<h1 class="test2">World</h1>
<script>
// JS code here
</script>
</body>
</html>
Inside the script
tag:
function demoLoop(){ // remove this line
var elmnt = document.getElementsByTagName("style");
if (elmnt.length === 0) {
// there isn't style objects, so it's more interesting create one
var newStyle = document.createElement("style");
newStyle.innerHTML =
"h1.test1 {" +
"color: green;" +
"}";
document.getElementsByTagName("head")[0].appendChild(newStyle);
} else {
// Using CSSStyleSheet interface
var firstCSS = document.styleSheets[0];
firstCSS.insertRule("h1.test2{color:blue;}"); // at this way (without index specified), will be like an Array unshift() method
}
} // remove this too
demoLoop(); // remove this too
demoLoop(); // remove this too
Another approach to this solution it's using CSSStyleDeclaration
object (docs at w3schools and MDN). But it may not be interesting, considering the risk to override existing rules on the system's CSS.
Use inline CSS. This solve the problem, although depending of the page size (in code lines), the maintenance (by the author itself or other assigned person) of code can be very difficult.
But depending of the context of your role at the institution, or its web system security policies, this might be the unique available solution to you.
Create a file _foobar.html
:
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1 style="color: green;">Hello</h1>
<h1 style="color: blue;">World</h1>
</body>
</html>
How is a browser supposed to render css which is non contiguous?
- Is it supposed to generate some data structure using all the css styles on a page and use that for rendering?
- Or does it render using style information in the order it sees?
(quote adapted)
For a more accurate answer, I suggest Google these articles:
BREAKING BAD NEWS for "style in body" lovers: W3C has recently lost the HTML war against WHATWG, whose versionless HTML "Living Standard" has now become the official one, which, alas, does not allow STYLE
in the BODY
. The short-lived happy days are over. ;) The W3C validator also works by the WHATWG specs now. (Thanks @FrankConijn for the heads-up!)
(Note: this is the case "as of today", but since there's no versioning, links can become invalid at any moment without notice or control. Unless you're willing to link to its individual source commits at GitHub, you basically can no longer make stable references to the new official HTML standard, AFAIK. Please correct me if there's a canonical way of doing this properly.)
OBSOLETED GOOD NEWS:
Yay, STYLE
is finally valid in BODY
, as of HTML5.2!
(And scoped
is gone, too.)
From the W3C specs (relish the last line!):
4.2.6. The style element
...
Contexts in which this element can be used:
Where metadata content is expected.
In a noscript element that is a child of a head element.
In the body, where flow content is expected.
META SIDE-NOTE:
The mere fact that despite the damages of the "browser war" we still had to keep developing against two ridiculously competing "official" HTML "standards" (quotes for 1 standard + 1 standard < 1 standard
) means that the "fallback to in-the-trenches common sense" approach to web development has never really ceased to apply.
This may finally change now, but citing the conventional wisdom: web authors/developers and thus, in turn, browsers should ultimately decide what should (and shouldn't) be in the specifications, when there's no good reason against what's already been done in reality. And most browsers have long supported STYLE
in BODY
(in one way or another; see e.g. the scoped
attr.), despite its inherent performance (and possibly other) penalties (which we should decide to pay or not, not the specs.). So, for one, I'll keep betting on them, and not going to give up hope. ;) If WHATWG has the same respect for reality/authors as they claim, they may just end up doing here what the W3C did.
When I see that the big-site Content Management Systems routinely put some <style> elements (some, not all) close to the content that relies on those classes, I conclude that the horse is out of the barn.
Go look at page sources from cnn.com, nytimes.com, huffingtonpost.com, your nearest big-city newspaper, etc. All of them do this.
If there's a good reason to put an extra <style> section somewhere in the body -- for instance if you're include()ing diverse and independent page elements in real time and each has an embedded <style> of its own, and the organization will be cleaner, more modular, more understandable, and more maintainable -- I say just bite the bullet. Sure it would be better if we could have "local" style with restricted scope, like local variables, but you go to work with the HTML you have, not the HTML you might want or wish to have at a later time.
Of course there are potential drawbacks and good (if not always compelling) reasons to follow the orthodoxy, as others have elaborated. But to me it looks more and more like thoughtful use of <style> in <body> has already gone mainstream.
As others have already mentioned, HTML 4 requires the <style>
tag to be placed in the <head>
section (even though most browsers allow <style>
tags within the body
).
However, HTML 5 includes the scoped
attribute (see update below), which allows you to create style sheets that are scoped within the parent element of the <style>
tag. This also enables you to place <style>
tags within the <body>
element:
<!DOCTYPE html>
<html>
<head></head>
<body>
<div id="scoped-content">
<style type="text/css" scoped>
h1 { color: red; }
</style>
<h1>Hello</h1>
</div>
<h1>
World
</h1>
</body>
</html>
If you render the above code in an HTML-5 enabled browser that supports scoped
, you will see the limited scope of the style sheet.
There's just one major caveat...
At the time I'm writing this answer (May, 2013) almost no mainstream browser currently supports the scoped
attribute. (Although apparently developer builds of Chromium support it.)
HOWEVER, there is an interesting implication of the scoped
attribute that pertains to this question. It means that future browsers are mandated via the standard to allow <style>
elements within the <body>
(as long as the <style>
elements are scoped.)
So, given that:
scoped
attribute<style>
tags within the <body>
<style>
tags within the <body>
...then there is literally no harm * in placing <style>
tags within the body, as long as you future proof them with a scoped
attribute. The only problem is that current browsers won't actually limit the scope of the stylesheet - they'll apply it to the whole document. But the point is that, for all practical purposes, you can include <style>
tags within the <body>
provided that you:
scoped
attribute<body>
will not actually be scoped (because no mainstream browser support exists yet)
* except of course, for pissing off HTML validators...
Finally, regarding the common (but subjective) claim that embedding CSS within HTML is poor practice, it should be noted that the whole point of the scoped
attribute is to accommodate typical modern development frameworks that allow developers to import chunks of HTML as modules or syndicated content. It is very convenient to have embedded CSS that only applies to a particular chunk of HTML, in order to develop encapsulated, modular components with specific stylings.
Update as of Feb 2019, according to the Mozilla documentation, the scoped
attribute is deprecated. Chrome stopped supporting it in version 36 (2014) and Firefox in version 62 (2018). In both cases, the feature had to be explicitly enabled by the user in the browsers' settings. No other major browser ever supported it.
As others have said, this isn't valid html as the style tags belong in the head.
However, most browsers dont' really enforce that validation. Instead, once the document is loaded then the styles are merged and applied. In this case the second set of styles will always override the first because they were the last definitions encountered.
I guess this will vary from browser to browser: The global display rules will probably be updated as the browser goes along through the code.
You can see such changes in the global display rules sometimes when an external style sheet is loaded with a delay. Something similar might happen here but in such short succession that it doesn't actually get rendered.
It's not valid HTML anyway, so I'd say that it is a futile thing to think about. <style>
tags belong in the head
section of the page.
Not valid HTML, anyway pretty much every browser seems to consider just the second instance.
Tested under the last versions of FF and Google Chrome under Fedora, and FF, Opera, IE, and Chrome under XP.
Yes it can. I checked on Mozilla's page. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style
In your example, a browser isn't "supposed" to do anything. The HTML is invalid. Either error recovery is triggered, or the parser makes of it as it will.
In a valid instance, multiple stylesheets are just treated as appearing one after the other, the cascade is calculated as normal.
Source: Stackoverflow.com