my use-case is the following :
I'm composing an HTML page by using parts that are valid HTML fragments but not valid pages,
like Divs; these elements are using CSS to manage their style.
I'd like to allow each fragment to be responsible for its own styling requirements and to not rely on the declarations of style-sheets in the main fragment (the one with the "HTML" tag).
So here come the question : is there any (standard) way to add some CSS styling outside the HEAD element (excluding the inline styling via the "style" attribute) ?
I guess I could use frames but I'd prefer to avoid this solution.
Thanks in advance for your help.
FINAL EDIT :
Thanks to the propositions of zzzzBov, JMC Creative and moontear, and after some testing, here is the answer :
use JavaScript to dynamically load some CSS style-sheets : HTML4/XHTML and HTML5 compliant,
embed "style" elements directly inside the fragments : non-compliant with HTML4/XHTML but seems to be broadly supported, and is HTML5 compliant.
As I must support email clients I've used the second solution which moreover is more simple.
tl;dr:
If you're not comfortable using HTML features that haven't reached a maturity level of W3C Recommendation, there isn't a standard way of adding <style> to the <body> of a page.
If you're comfortable using less mature features, HTML5.2 appears to be standardizing <style> elements to be allowed anywhere flow content is expected (i.e. the <body> and most of its elements).
If you're already using the [scoped] attribute, stop using the [scoped] attribute, as it was never standardized and is losing browser support.
History:
HTML 4.01
In HTML4.01 the style element was allowed in the <head> only. Browsers, being diligent about attempting to render what the author wants rather than what the author wrote have respected <style> elements in the <body> despite those pages technically being invalid.
HTML 5
The <style> element continued to be invalid in the <body>
HTML 5.1
In some working drafts of the HTML5.1 spec the <style> element was to allow for a [scoped] attribute, which would allow the <style> element to be used in flow content (i.e. in the <body>).
As an example of how that could have been used would be:
<!DOCTYPE html>
<title>Example of using the scoped attribute</title>
<div>
<style scoped>
p {
color: darkred;
}
</style>
<p>this text would be dark red</p>
</div>
<p>this text would be black</p>
Support for the scoped feature was added to Firefox in version 21 and added in Chrome behind a flag in version 20. The feature didn't receive enough support, so it was later removed from the HTML5.1 working draft.
Chrome was first to remove the feature in version 36. Firefox has since set the feature to be behind a flag in version 55.
HTML 5.2
In the July 2017 working draft of the HTML5.2 spec, support was added for the <style> element to be allowed in flow content:
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.
Emphasis mine
At the time of writing this addition has remained in the HTML5.2 spec, which is currently at the Candidate Recommendation maturity level.
While this makes using <style> elements in the <body> still somewhat of a risk, this particular change is standardizing something that browsers have supported for many years.
There is no standard way (EDIT: as of HTML5 there apparently is!) of adding a <style> element outside of the <head> tag - it is only allowed there and NOT within the <body> tag (See the DTD here).
If you want to style your HTML fragments individually and not use CSS styles in your head, you will need to resort to inline styling. However: Most browsers understand <style> tags within the body, so you may as well use them, but your page won't be standards compliant.
In any way:
You should not use inline styling
You should adhere to standards
You should put the CSS in the head where it belongs
From what I understand you use some kind of templating, where you insert different HTML snippets into the page with different designs. Is it so bad if you put all styles within one big CSS file?
Would it be impossible for you to dynamically load a another CSS file (via JS or server side scripting), when your HTML fragment gets inserted in the page (this would be the preferred method)?
I've found two hacks to do that. Both of which should be perfectly valid html.
The SVG way
Wrap your <style /> element inside a <svg /> element.
<div class="foo">Red text</div>
<svg><style>.foo { color: red }</style></svg>
The Data-Uri Link
Format your css as a data uri and use that in a <link /> element.
<div class="foo">Red text</div>
<link rel="stylesheet" href="data:text/css,.foo%20%7B%20color%3A%20red%20%7D" />
Related
After reading this question I am confused:
Using <style> tags in the <body> with other HTML
Most people in there say it is bad practice to have style tags in the body section, and that it does not adhere to W3 standards, however I read this differently:
http://www.w3.org/TR/html-markup/style.html#style
Above link says:
Permitted parent elements:
Any element that can contain metadata elements, div, noscript, section, article, aside
The body element allows all these apart from 'metadata elements', but this list does not state that all of these elements need to be accepted in order for the style tag to be allowed. So surely it is OK by W3 standards to have the style tag within the body simply because for example the body element allows the use of div?
Maybe I'm reading this much later (5 years on) and this rule has been changed because of the 'scoped' attribute for style tags, so I wanted to ask to see if I was wrong in my interpretation of their standard or not.
From the front page of the document you linked to:
This document has been discontinued and is only made available for historical purposes. For an up to date reference on HTML elements (and more) please consult Web Platform Docs.
Some draft versions of HTML 5 allowed style elements in the body under certain conditions.
There were various problems with the design of that functionality and it did not make it into the final version of HTML 5.
I've tried every possible combination right now. Theoretically, it can be placed anywhere within the <body>, <head> and even inside <table> or <select> elements, but if I place a simple <template></template> tag pair without anything else inside, the W3C validator (the tool I base all my HTML5 and CSS3 validation on) gives me the finger.
Can someone give me a rough example of where does the <template> tag goes in practical reality? I find no solution (or maybe the W3C validator doesn't validate the <template> tag correctly yet, don't know...).
The <template> tag currently has the status of an editors draft. That means it is not part of the W3C standard yet, so the W3C validator doesn't recognize it. The current draft says:
The <template> element can be placed anywhere within the <head>,
<body>, and <frameset> elements, and its contents can contain any
content which could otherwise occur at any location within the <head>,
<body>, and <frameset> elements.
So unless the draft changes in the future, you can place templates wherever you want in your code.
Keep in mind that using features which are still in draft state is dangerous. Before it is an official standard which is supported by all browsers, I would recommend you to use <div style="display:none"> instead of <template>.
Does placement of:
<style type="text/css">
...
</style>
matter? Is there any difference if I place it inside page div, or inside body? I recently found out it matters with javascript. I had some problems with my CSS also (jQuery Mobile). Could it be the reason?
The style element should apply to the whole document, wherever it is placed, however it is common practice to always put it in the head element. I would not be surprised if browser handling is a bit flaky if you put it in other places.
Note that html5 allows you to specify the scoped attribute for the style element, which means that it will only apply to the parent element of the style element and all its children.
By the way, usual practice is to put the css in a separate file and use the <link> tag to include the CSS in your document. This way you can share the css across multiple pages.
The placement matters as regards to order of style sheets. When resolving conflicts between style sheets, then at the last step, when other things are equal, the rule that comes last wins. Thus, it matters how the style element is placed relative to other style element and to link elements that refer to style sheets. (It does not matter as regards to style attributes in elements, since other things can’t be equal: the attributes win, by specificity.)
It also matters in validation: a style element is not valid except within a head element. Browsers don’t care about this, though.
JavaScript code can of course be dependent on the placement of the elements it processes. It’s all up to the code.
Ideally it should not, but don't do it, it is just bad practice, plus makes your code looks messy
To answer the question directly, usually if you're placing your code straight in the page, you'll be placing it in the <head> of the page. Should work regardless of where you put it, but <head> is common practice. Not sure what exactly your goal is, but for email, I typically split it up into inline styling (placing relevant code in the HTML tags themselves, like <p style="line-height:1.4em;">).
If you're working on webpages, though, unless there's a particular reason to have the CSS embedded in the code of the page itself, it's almost always better (and it considered best practice) to link to an external stylesheet in between your <head> tags (<head> <link rel="stylesheet" href="[YOUR STYLESHEET]" type="text/css"> </head>). It keeps your HTML cleaner, and helps with the separation of markup (HTML), styling (CSS), and functionality (JavaScript).
Hope that answers your question somewhat, haha.
I would like to define a snippet of CSS in my page like this:
<style type="text/css">
hr {color:sienna;}
p {margin-left:20px;}
</style>
I keep reading that it should be defined within the <head> element, but it seems to work fine when inline. Can someone confirm if this is okay?
For HTML 4 the spec says:
The STYLE element allows authors to put style sheet rules in the head of the document. HTML permits any number of STYLE elements in the HEAD section of a document.
Reference: http://www.w3.org/TR/html4/present/styles.html#h-14.2.3.
Their specification of "head of the document", rather than simply 'document' strongly suggests that elsewhere is inappropriate.
For HTML 5, however, this is relaxed and the style element can be placed within the document itself:
The style element allows authors to embed style information in their documents. The style element is one of several inputs to the styling processing model. The element does not represent content for the user.
Reference: http://www.w3.org/TR/html5/semantics.html#the-style-element.
Most browsers put it anywhere in the page, but just be aware that it only takes effect from that point onwards. Also, it's not valid HTML if you don't put it in the head element.
Also, it's considered best practise to put it in the head element as it improves page render times.
It is not strictly valid unless you are using HTML5 and the scoped attribute.
https://www.w3schools.com/tags/tag_style.asp
https://www.w3schools.com/tags/att_scoped.asp
Although all browsers that I know of will accept the tag anywhere in the document.
It is not OK.
While some browsers might (mistakenly) care about it when not in the HEAD element, this is not behavior you should rely on, as it is counter to the HTML standard and may or may not work in the future for any given browser.
Edit: Update: In HTML 5, style elements can be scoped to only apply to a subtree, in which case they don't need to be in the head element.
They still, however, need to be in front of any other content they apply to, so the same principle applies.
I see something like this:
<div>
<style type="text/css">
...
</style>
</div>
It's very strange,but still work.
Is this against the standard?
It's worth pointing out that although it's invalid HTML, it's also extremely common, and any browser that didn't support it would fail to render properly a significant portion of the web.
Mash-ups in particular, need use of this feature, and HTML 5 defines <style scoped> to deal with this use case. <style scoped> can appear in the body, though styles so defined do not apply to the whole document, only to the section in which <style scoped> appears.
WARNING: HTML 5 is a draft, and there is no guarantee that <style scoped> or any other HTML 5 feature that is not already implemented will ever be implemented.
Yes, it violates the HTML specification.
<!ELEMENT DIV - - (%flow;)* -- generic language/style container -->
(from the div section of the specification)
Follow the hyperlinks in the live version if you want to see exactly how %flow; expands (it doesn't include style).
Browsers just tend to do huge amounts of error recovery because so many authors do stupid things.
Don't depend on error recovery — there are lots of browsers out there, and they don't all behave the same way when the HTML doesn't conform to spec.
The STYLE element is only allowed as child of the HEAD element. See this explanation for further details.
In HTML5, a <style> tag is allowed to appear under anything in <body> or <head>.
Mostly you are not allowed to put blocking elements into inline elements but meta elements like style, script, meta may appear wherever you want.
I found an example where the tag inside a div is not read correctly by IE8 (it works fine in Firefox and Chrome)
I can't reproduce it with a simple example because I don't know where the problem is. But if I move the outside the div everything works again.
Why I'm using a tag inside a div? because I'm loading external data with AJAX inside that div, and I don't know other way to add the styles in that situation.