Declare CSS style outside the "HEAD" element of an "HTML" page?

HtmlCssTemplatesTemplate Engine

Html Problem Overview


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.

Thanks all for your interest and participation.

Html Solutions


Solution 1 - Html

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.

Solution 2 - Html

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)?

Solution 3 - Html

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>

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" />

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPragmateekView Question on Stackoverflow
Solution 1 - HtmlzzzzBovView Answer on Stackoverflow
Solution 2 - HtmlDennis GView Answer on Stackoverflow
Solution 3 - HtmlloominadeView Answer on Stackoverflow