简体   繁体   中英

Shouldn't this span color be green?

Shouldn't the span color should be green, it is red in Chrome.

HTML spec says it should be green, it is green in Firefox.

The HTML spec uses fetch to get the resources referenced by elements (see this and fetch is always an async operation. So the computed style is gotten before the new stylesheet has loaded, and hence the color should be green.

 var div = document.createElement("div"); document.body.appendChild(div); var link = document.createElement("link"); link.href = "data:text/css,div { color: red }"; link.rel = "stylesheet"; var div = document.createElement("div"); document.body.appendChild(div); var link = document.createElement("link"); link.href = "data:text/css,div { color: red }"; link.rel = "stylesheet"; document.head.appendChild(link); document.querySelector("span").style.color = getComputedStyle(div).color; link.remove(); div.remove();
 div { color: green }
 <span>This should be green</span>

To make this easier to analyze, I've reduced your sample to remove the duplicate and irrelevant lines; the following is enough to reproduce the issue:

 var div = document.createElement("div"); document.body.appendChild(div); var link = document.createElement("link"); link.href = "data:text/css,div { color: red }"; link.rel = "stylesheet"; document.head.appendChild(link); document.querySelector("span").style.color = getComputedStyle(div).color;
 div {color:green}
 <span>This is a span</span> <div>this is a div</div>

So what's going on here is, there's inline CSS that says divs should be green; you generate a text/css link that sets divs to red, and append that to the document head. Then you use getComputedStyle to copy the color from the div onto the span.

In Safari, Chrome, and Edge, both lines end up red; in Firefox the span is green and the div is red.

BUT! on first load, or if you load this page in Safari or Chrome with a clean, empty cache * you'll see the same behavior as in Firefox: green span and red div. Edge never behaves like FF, it's always red for both even on first load.

* (In Safari you can just use a private browsing window. I could swear I was seeing the same in Chrome at one point but am no longer able to reproduce; possibly I was mistaken.)

Therefore, here's my hypothesis for what's going on:

  • In Safari, when the generated stylesheet link has never been used before, it's async, so getComputedStyle picks up the color from the inline style. On later loads, the generated stylesheet is already in cache when getComputedStyle runs, so its rule takes over.
  • In Firefox, stylesheet links are always treated as async, so getComputedStyle always picks up the inline rule.
  • In other browsers, the stylesheet link is interpreted synchronously (possibly because the browser can tell that a data URI doesn't need network time?) so is handled before getComputedStyle runs.

This is a weird enough edge case that I'm not certain which behavior could be described as "according to spec".

尝试 HTML 或 HTML5(这是 Chrome):

<span type="color:green">shouldn't this be green</span>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM