[html] Using <style> tags in the <body> with other HTML

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:

  1. these not-programmers users don't have an open channel with the system admins (or institution's webdevs), to ask for including some CSS rules at the system's stylesheets. Actually, it would be impractical for the admins (or webdevs), considering the number of requests in that sense that they would have.
  2. this system is legacy and still doesn't support newer versions of HTML.

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:


1st option: ask your sysadm

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.


2nd option: <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, the stylesheet 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.

Testing

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.


3rd option: <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.


4th, 5th and 6th options: JS ways

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.

4th option: new <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.

Testing

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.

5th option: new <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.

Testing

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

6th option: using an existing <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.

Testing

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.


7th option: inline 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.

Testing

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>

Answering strictly the question asked by Gagan

How is a browser supposed to render css which is non contiguous?

  1. Is it supposed to generate some data structure using all the css styles on a page and use that for rendering?
  2. Or does it render using style information in the order it sees?

(quote adapted)

For a more accurate answer, I suggest Google these articles:

  • How Browsers Work: Behind the scenes of modern web browsers
  • Render-tree Construction, Layout, and Paint
  • What Does It Mean To “Render” a Webpage?
  • How browser rendering works — behind the scenes
  • Rendering - HTML Standard
  • 10 Rendering — HTML5