Html: style tag should be allowed in body

Created on 28 Jul 2016  Â·  31Comments  Â·  Source: whatwg/html

This is a follow up on the issue on style scoped

We allow <link rel=stylesheet> in the body, we should allow <style> tags as well.

It's already supported in all the browsers and will be in the future, what is the benefit in making it invalid markup if it's often the best or even only solution to a problem and is widely used on many websites and CMS's?

This would also serve as a half functioning replacement for <style scoped> where you can work around the scoping issue using custom classes.

Also, I've seen some people ask, why not use inline styles? like <span style="color:red"></span>?
Well, you can't apply inline styles for hover states or pseudo elements, it also means a lot of repeated css most of the time.

Is it good to use it in the body instead of the head? No if you can help it, yes if you can't.

Edit:
Also many people like the convenience of doing ajax requests that come with html and their own style tags.

document conformance normative change

Most helpful comment

Including style in the AJAX response for pages that can be rendered either directly embedded (causing style in body warnings in the HTML 5 validator) or fetched via AJAX requests is pretty common practice in my opinion.

I agree with making style in body valid HTML 5.

It shouldn't require a HTML 5 conformance checker to make devs realize that this is bad practice _in general_. Every web dev knows that style is usually part of the head. However sometimes it can't be avoided. It should be valid.

All 31 comments

Thanks, this is nice.

(But I disagree with this being a “half functioning replacement for <style scoped>”.)

@prlbr That's fine, it's not really a replacement for scoped but can be worked with. :)

I'm just going to point out that the obvious case for a style tag, over using inline styles, would be table cells.

I don't think we should change this.

<link> is very different from <style>, in that the former causes a fetch. As such, in the original bug https://www.w3.org/Bugs/Public/show_bug.cgi?id=27303, the arguments were about delaying this fetch. They're performance arguments, in other words.

<style> in body has a number of negative consequences, such as the famous "flash of unstyled content" (FOUC) and the re-paint and re-layout required. There are good reasons for keeping all styling in the head. For <link>-based styling, it turns out there are even better reasons for allowing it in the body (although doing so would require careful performance measurement). But I have seen no evidence of that for <style>.

I'd like to hear from @igrigorik, who initiated the push for <link> in body.

Also, just to be very clear: this entire issue is not about changing browser behavior. The spec already requires, and browsers already implement, processing for <style> in body. It works, albeit with the negative effects I discussed above.

This issue is entirely about what conformance checkers like https://checker.html5.org/ will do if you include <style> in body. Will they tell you that's bad practice and disallowed by the spec's authoring requirements? Or will they let it happen silently?

<style> in body has a number of negative consequences, such as the famous "flash of unstyled content" (FOUC) and the re-paint and re-layout required. There are good reasons for keeping all styling in the head.

I strongly agree that if in practice <style> in body results in significant cases of things that are bad for end users—like FOUC and slower performance—then that should be a sufficient reason to continue to make it non-conforming. Because we want to be helping developers to avoid making authoring mistakes that cause actual bad user experience.

That said, I wonder how we can assess how many such cases of FOUC and slowed performance the existing uses of <style> in body in documents on the Web are causing for users.

I added a <style>-in-body use counter to statistics collected by the W3C HTML checker:

https://validator.w3.org/nu/stats.html

I just now added it but the initial results indicate that about 14% of the documents it checks have <style> in body. [Update 2017-02-07: The long-term data from the use counter indicates that about 17% of documents the HTML checker processes have <style> in body.]

Some more well-known sites with <style> in body that I’ve come across so far in the logs for the checker include www.amazon.com www.pinterest.com www.bing.com/search?q=foo www.ebay.com www.gettyimages.co.uk www.weightwatchers.com www.quora.com & www.google.de www.google.it www.google.pl www.google.co.in www.google.com.hk www.google.bg & other Google search sites.

The HTML checker and legacy W3C validator have always reported an error for <style> in body—for 20 years or whatever now—so if in spite of that we still have 14% of sites being run through the checker that are using <style> in body anyway, that means a lot of developers are just ignoring the error message and not considering it a mistake. So this might be a case where making something non-conforming is in practice not actually having much effect on preventing its use.

But it would be good to look at more relatively widely-used sites and see what evidence can be found of FOUC or re-paint/re-layout affecting users of those sites.

In the end not matter what the numbers are, if it seems like keeping <style> in body non-conforming is the right way to try to ensure the best user experience for users, then I support continuing to make it non-conforming.

@sideshowbarker I think the validators should give out a warning as a potential error and not as an actual error, that is the key difference here.

Just a fun link from stackoveflow, I like the top answer being "Doesn't matter"... http://stackoverflow.com/questions/4803518/why-can-t-style-tags-within-the-html-body-tag-validate-on-w3c
http://stackoverflow.com/questions/1303416/does-style-have-to-be-in-the-head-of-an-html-document

I think standards matter and should not be implemented in a way that promotes them to be ignored.

The w3c validator is seen as an authority and often means that if it says that something is not allowed then it must never be done, and some systems actually penalize you for not having it valid and I find that silly in the case of the <style> tag in the body because it works reliably and people use it.

If the flash is the only issue here, then the validator should warn about it, but not prohibit the usage...

@sideshowbarker I think the validators should give out a warning as a potential error and not as an actual error, that is the key difference here.

My experience in dealing with issue reports from users of the validator is that many or most users don’t actually care about the difference between a validator message flagged as an error and one flagged as a warning. Regardless of what category the message is, they just want it to go away.

I find that silly in the case of the <style> tag in the body because it works reliably and people use it… If the flash is the only issue here, then the validator should warn about it, but not prohibit the usage

There are a number of existing cases where we have made a particular markup case non-conforming in the spec because even though it can be made to work reliably, it also carries a high risk of being used wrongly and resulting in degraded user experience.

The rationale is to attempt to help prevent developer-authors from shooting themselves in the foot by unknowingly using something that ends up making the user experience of their content worse at least for some portion of users (whether it be users of older browsers, browsers on older devices, screen-reader users, users on networks with very limited bandwidth, etc.)

A few other well-known sites I’ve come across with style in body: www.nytimes.com www.newyorker.com www.reddit.com www.wikipedia.org www.flickr.com https://support.microsoft.com https://search.yahoo.com www.huffingtonpost.com

With that I’ll stop adding any comments listing other sites that have it. I think it’s sufficiently illustrated that for better or worse, use of style in body is not uncommon in practice.

That is pretty compelling, I just wish we had some web perf or rendering engine folks to tell us if they're doing this because of perf or in spite of it. I can try to ask around.

Including style in the AJAX response for pages that can be rendered either directly embedded (causing style in body warnings in the HTML 5 validator) or fetched via AJAX requests is pretty common practice in my opinion.

I agree with making style in body valid HTML 5.

It shouldn't require a HTML 5 conformance checker to make devs realize that this is bad practice _in general_. Every web dev knows that style is usually part of the head. However sometimes it can't be avoided. It should be valid.

Another use case for <style> in the body of a document would be User/CMS-generated content. For example, a client would like to control the background image for a hero container,.. they upload an image to a CMS and the server generates background images automatically and dynamically outputs the content in the <style> tag to support multiple background images appropriate for certain screen sizes.

<div class="hero-a">...</div>
<style>
.hero-a {
  background: url('/some-path/small-bg.jpg');
}
@media(min-width: 48em){
  .hero-a {
    background: url('/some-path/large-bg.jpg');
  }
}
</style>

Since breakpoints won't work for inline styles and CMS generated content can't be part of the site's CSS this is a workaround but not valid markup at this point.

Pro:

  • It is often required to specify styles alongside HTML "components".

Contra:

  • Could force a repaint in the browser (even for styles defined before the HTML it applies to?).
  • Potential security vulnerability (see XSS / CSP).

Solutions:

  • Make style in body valid HTML (doesn't solve any of the contra points, though).
  • Shadow DOM might solve the problem in some cases but requires JS (why do we need JS for styles?). Isn't this extremely bad for first-paint performance?
  • Compile all styles of all pages and serve it to the user in the head of every single page.

    • Advantage: Best rendering performance.

    • Disadvantage: Worst loading performance (potentially huge file size because all styles are included instead of only the required ones).

I've posted https://groups.google.com/a/chromium.org/forum/#!topic/style-dev/mRWH2J871mc to get a sense from Chrome engineers whether style-in-body is harmful or not. It'd be great to get input from other teams. Maybe @pcwalton from Servo and @dbaron from Gecko?

https://github.com/whatwg/html/issues/1605#issuecomment-235956455 seems about right from a Gecko perspective; it can (depending on position relative to scripts, slow-to-load markup, etc.) lead to expensive restyling, relayout, and repainting.

Does the future of HTTP2 factor into any of this story?
https://jakearchibald.com/2016/link-in-body/

No; that is entirely unrelated to <style>-in-body.

Based on @dbaron's response and the response from Blink engineers at https://groups.google.com/a/chromium.org/d/msg/style-dev/mRWH2J871mc/jvDyR2XKBAAJ, I think we should close this in favor of the current spec. My takeaway is that under ideal circumstances (including a fast network connection and small page), with carefully-crafted markup, style-in-body can be made to work. But in the general case, it is error-prone and likely to lead to expensive restyling, relayout, and repainting. As such we should continue to recommend against it.

If people disagree, I'm happy to reopen. Perhaps we could soften the advice from a content-model-level restriction to a "should not" explaining the pitfalls. But I think it's probably better for such pages to just be nonconformant.

I’ve checked the the top 13 domains according to alexa.com and most of these use <style> in body:

1. www.google.com
5. www.yahoo.com
6. www.wikipedia.org*
7. www.google.co.in
8. www.qq.com
9. www.tmall.com
10. www.sohu.com
11. www.google.co.jp
12. world.taobao.com
13. www.amazon.com

*(that’s due to a malformed IE conditional comment though, we may not want to count this)

So <style> in body works in browsers and is a deliberately used reality on major (and minor websites). Therefore I’ve got two questions:

  • Shouldn’t the spec reflect reality?
  • If <style> in body is as bad as you say, performance-wise, then why do top websites use it anyway? Do the benefits outweigh the disadvantages after all?

Shouldn’t the spec reflect reality?

That's phrased kind of strangely. "reflecting reality" is usually a question about the spec reflecting the reality of browser implementations, in its implementation specifications. It's not a question about the spec sanctioning any bad markup, in its author-facing markup guidelines.

If we just specced any sufficiently-popular markup, we'd do lots of weird things, like speccing <i> to mean "icon".

So I don't think "reflecting reality" is relevant here.

If <style> in body is as bad as you say, performance-wise, then why do top websites use it anyway? Do the benefits outweigh the disadvantages after all?

That's a good question. You'd have to ask them to be sure, but we have to note that in general the top websites are not very good at performance. This leads to lots of railing against them on Twitter by certain devrel people, of course, which is a whole other situation. Often these websites choose to sacrifice performance and user experience for the sake of advertising revenue, or developer experience, or their CMS tooling... you'd have to ask each individual site to see why. In some cases they might have made a calculated business decision that other factors are more important than writing conformant documents. (How many of those websites also pass the other checks on https://checker.html5.org?)

Perhaps we could soften the advice from a content-model-level restriction
to a "should not" explaining the pitfalls

I agree with this statement, but as I said before, if the spec says that
you must not do something and then looks the other way when people do it,
then it's the spec at fault here.

Let's create some scenarios:

  1. Spec says that style in body is forbidden (yet allows to do the same
    thing with the same re-rendering consequences using other means as
    mentioned before)

    • lots of big websites don't comply with the spec
    • big websites or cms creators use it anyway because the benefits outweigh
      the drawbacks
    • evangelists or badly knowledgeable people call the big websites or cms
      creators stupid, the big websites / cms creators call the spec irrelevant
      as it works fine anyway.
    • lots of professionally made cms's or apps don't comply with the spec
  2. Spec says that style in body should not be used in general, but it's ok
    overall.

    • lots of big websites don't comply with the spec
    • big websites or cms creators use it anyway because the benefits outweigh
      the drawbacks
    • evangelists or badly knowledgeable people call the big websites stupid,
      the big websites call the spec irrelevant as it works fine anyway.
    • most of the professionally made cms's or apps almost comply with the spec
  3. Spec says that style in body is ok

    • lots of big websites don't comply with the spec
    • evangelists or badly knowledgeable people call the big websites stupid,
      the big websites call the spec irrelevant.
    • the spec is more consistent with itself and the browsers (think:
      post-page load style linking, and the browser support/history)
    • most of the professionally made cms's or apps comply with the spec

Because of the above, imho the big websites argument is irrelevant.
Don't forget that with ajax styles can be added to pages after the fact a
lot more than before, meaning that the re-rendering issue is happening in
many more cases which should be handled too to keep things consistent and
organized.

I personally think that style in body should be allowed with a warning for
those that don't know that it causes a refresh, although in today's
hardware the refresh is negligible.

On 25 February 2017 at 18:11, Domenic Denicola notifications@github.com
wrote:

Shouldn’t the spec reflect reality?

That's phrased kind of strangely. "reflecting reality" is usually a
question about the spec reflecting the reality of browser implementations,
in its implementation specifications. It's not a question about the spec
sanctioning any bad markup, in its author-facing markup guidelines.

If we just specced any sufficiently-popular markup, we'd do lots of weird
things, like speccing to mean "icon".

So I don't think "reflecting reality" is relevant here.

If