Finally I had some time to test Internet Explorer 8 beta 2, so first of all I ran all the test I had previously done to check if bugs were fixed.
Here’s the list:
:first-childselector to dynamically added element still doesn’t work, see the testcase. When you click on “Add first child” button, a new paragraph is added which then becomes the actual first-child of the parent div and only this new paragraph should apply CSS rules defined for the corresponding
:first-childselector. In IE8b2 new element gets the CSS applied, but the element that previously was first-child doesn’t lose CSS as if it still was the first child (see IE8b2 screenshot and Google Chrome screenshot).
:last-childis still not supported. Of course, it’s CSS3, but it would be really handy to have this supported and most browsers already support
:last-child. See testcase.
- Now about bugs that I blogged about here and here:
- position: relative for the generated content rule — fixed — now the testcase doesn’t kill the tab where it’s been opened.
- generated content is created after window.onload — fixed — now all the generated content is created right at the stage of applying CSS rules which can be clearly seen here.
null— fixed — now IE8b2 correctly shows the value of class attribute.
content: attr(className)results as an empty string, right as it’s defined in the CSS spec for non-existing attributes. Here’s the testcase.
- expressions don’t work in generated content — expressions don’t work in standards compliancy mode any more at all, so this bug is outdated
text-transformdoesn’t work for generated content — fixed — see testcase.
text-indentdoesn’t work for generated content — fixed — see testcase.
While writing the post about forms values persistence, I noticed that browsers handle back button in different HTTP situations differently.
HTTP 1.1 spec says the following:
13.13 History Lists User agents often have history mechanisms, such as "Back" buttons and history lists, which can be used to redisplay an entity retrieved earlier in a session. History mechanisms and caches are different. In particular history mechanisms SHOULD NOT try to show a semantically transparent view of the current state of a resource. Rather, a history mechanism is meant to show exactly what the user saw at the time when the resource was retrieved. By default, an expiration time does not apply to history mechanisms. If the entity is still in storage, a history mechanism SHOULD display it even if the entity has expired, unless the user has specifically configured the agent to refresh expired history documents. This is not to be construed to prohibit the history mechanism from telling the user that a view might be stale.
So it clearly recommends UA authors to separate history list and cache behaviour. So if user navigates through the history list (using Back or Forward buttons), HTTP spec recommends to show the exact response that the user saw before, regardless if it's stale or expired.
I've tested 4 major browsers — IE, FF, Opera and Safari, and here is the summary table:
|Expires in the future +
Conditional GET validators
|no request||no request||no request||no request|
|Expires in the future||no request||no request||no request||no request|
|Conditional GET validators||no request||no request||no request||no request|
|no HTTP caching headers||no request||no request||no request||full request|
|Expires in the past||no request||no request||no request||full request|
|Cache-Control: no-store||full request||full request||no request||full request|
|Cache-Control: no-store +
Expires in the past
|full request||full request||no request||full request|
|Page served with||IE8||FF||Opera||Safari|
So we can see that only Opera follows HTTP 1.1 recommendation.
Obviously IE and FF don't produce a request when HTTP caching is not explicitly prohibited which is against the HTTP spec recommendation, but this was done intentionally asauthors usually prohibit caching for a reason and don't want users to view those pages without revalidating.
And Safari just does the full request whenever the page is not cached explicitly.
So IE started filtering values in expressions since IE6, and now IE8b1 in both modes doesn't even allow you to use object property accessors (both dot and square brackets notations — see testcase). So in IE8b1 in expressions you can only use plain string values in your expressions (which is not handy at all) or call externally defined functions.
I can't help thinking of any other reason for disabling this except for protecting from potential XSS threat that I described in the previous post.
Also in IE8b1 expressions are not reevaluated on mouseover event (see testcase), but onscroll still fires
document.recalc (this again seems to be left intentionally in order to support all cludges that were invented to implement for example non-existent position: fixed CSS rule).
Bottom line, if you have expressions used in your CSS code, don't wait — separate all the stuff you do there to JS functions and just call these functions from your expressions.
data URI specification says the following:
some applications that use URLs may impose a length limit; for example, URLs embedded within <A> anchors in HTML have a length limit determined by the SGML declaration for HTML [RFC1866]. The LITLEN (1024) limits the number of characters which can appear in a single attribute value literal, the ATTSPLEN (2100) limits the sum of all lengths of all attribute value specifications which appear in a tag, and the TAGLEN (2100) limits the overall length of a tag.
Though at the time of writing data URI specification HTML3.2 was current HTML recommendation, author intentionally used LITLEN, ATTSPLEN and TAGLEN values from the older HTML2.0 SGML declaration to show that some user-agents may impose a length limit for URI.
HTTP1.1 doesn’t put a limit on the length of URI, but it warns us:
Note: Servers ought to be cautious about depending on URI lengths above 255 bytes, because some older client or proxy implementations might not properly support these lengths.
which basically means that if all clients in the network support URIes more than 255 bytes long, we’re ok.
HTML3.2 SGML declaration states the maximum length of an attribute to be 65535. Even more, HTML4.01 SGML declaration uses value 65535 as a maximum allowed in SGML but says that fixed limits should be avoided. XML1.0 SGML declaration uses 99999999 value just to show that there’s no limit specified.
Different browsers have different maximum length of dataURI’ed values supported.
As per the kb208427 article, IE supports URI length of up to 2048 bytes. According to the Microsoft IE8 data URI support whitepaper, IE8 supports up to 32Kbytes of data URI and silently discards dataURI value if its size exceeds 32Kbytes (which can be checked in the testcase1 and testcase2). As I’ve already mentioned in the previous post, other browsers provide bigger-sized URI support, but I doubt that IE8 will have minor market share so we will still have to stick to 32Kbytes. And I will repeat: data URI spec author that the only reasonable and semantic use of data URI is embedding small resources, so realistically speaking 32Kbytes limit shouldn’t be a problem.
Serving CSS dataURI’ed
In theory, CSS has to be served with its MIME type (
In practice, only Firefox and only in standards compliancy mode cares about MIME type that CSS’s been served with. Please see the testcases with CSS served with wrong MIME type in different render modes: in standards compliancy mode and in quirks mode. Opera, Safari and Internet Explorer 8 all apply CSS served with any MIME type in all modes. The behaviour is the same for both CSS files served using dataURI and by referencing normal external files.
Scripts in data URIs are unsupported because they allow potentially harmful script to bypass server- and
proxy-script filters for applications such as HTML email. (Web-based email clients generally do not allow
emails to execute script; data URIs could be used to easily bypass these filters).
Opera and Safari run dataURI’ed HTML page in a separate isolated context, IE8b1 doesn’t support dataURI’ed html at all, so the only affected browser here is Firefox. There’s an interesting bugzilla entry describing the XSS (marked as duplicate to the security proposal) which says:
Firefox authors reply that this is site maintainers’ problem to filter dataURI and compare this to filtering
To me it seems a bit weird especially looking at the fact that other browsers do care about execution context. The bugzilla entry is still opened, but I doubt that this is going to be fixed. So, “site maintainers”, be aware!
Neither dataURI spec nor any other mentions if dataURI’es can not be nested. So here’s the testcase where dataURI’ed CSS has dataURI’ed image embedded. IE8b1, Firefox3 and Safari applied the stylesheet and showed the image, Opera9.50 (build 9613) applies the stylesheet but doesn’t show the embedded image! So it seems that Opera9 doesn’t expect to get anything embedded inside of an already embedded resource! :D
But funny thing, as IE8b1 supports expressions and also supports nested data URI’es, it has the same potential security flaw as Firefox does (as described in the section above). See the testcase — embedded CSS has the following code:
But base64 RFC doesn’t put a requirement to split base64 strings:
MIME  is often used as a reference for base 64 encoding. However, MIME does not define "base 64" per se, but rather a "base 64 Content-Transfer-Encoding" for use within MIME. As such, MIME enforces a limit on line length of base 64 encoded data to 76 characters. MIME inherits the encoding from PEM  stating it is "virtually identical", however PEM uses a line length of 64 characters. The MIME and PEM limits are both due to limits within SMTP. Implementations MUST NOT not add line feeds to base encoded data unless the specification referring to this document explicitly directs base encoders to add line feeds after a specific number of characters.
DataURIed images with images turned off
When you turn off images in your browser, only Firefox still shows dataURIed images. IE8b1, Safari and Opera don’t show the image as it’s supposed to be when you turn the images off. To test this turn off images in your browser and run the testcase.
UPDATE: Firefox developers told me this is by design as unchecking “Load images automatically” option in the browser settings disables only network request to get the image. So if the image is accessible without doing a network request — either from cache or embedded as dataURI, it will be displayed in any case.
Dynamically created dataURIes
As dataURI can contain binary data (e.g. to show images), there are thoughts on using this. Ajaxian has a crazy article on creating pure JS video player that doesn’t use flash but changes dataURI’ed images instead. This technique may get some practical evolution and usage, but now it’s rather impractical.
Links and references
- HTML 2.0 SGML declaration
- HTML 4.01 SGML declaration
- HTML 3.0 SGML declaration
- HTML 3.2 SGML delcaration
- Microsoft IE8 data URI support
- XML1.0 SGML declaration
- Maximum Length of the URL
- How Mozilla determines MIME types
P.S. And here’s a great tool from Nicholas C. Zakas – CSSEmbed – it reads the CSS file you want, finds all the images references, converts images to dataURIes and saves resulting CSS file. So if you have small presentational images referenced in your CSS file, feed CSSEmbed with your CSS file and you’ll get them all converted in one go! Nice and simple! This tool can be also easily integrated into your publishing process if required. Thanks Nicholas!