Although in official specifications, HTML has versions and CSS levels, in practice, there is no version level. The key is to check whether the browser supports them.
For example, IE6 does not support CSS sub-element selection, which is very frustrating.
Although there are other alternatives, such as adding class names to HTML elements, the amount of code will increase a lot, and the semantics of HTML elements cannot be well utilized.
There is currently a third-party JS library selectivizr(Http://selectivizr.com/), the current version v1.0.2, can enhance the support effect of IE on many css3 pseudo class selection and attribute selection, it should be used with some "4th party" JS libraries (such as jquery.
The principle is roughly as follows: analyze the URLs of the external style sheets loaded on the current page, re-read these style sheets through Ajax, and replace the delimiters not supported by IE6 with specific class names, at the same time, add such names to the corresponding HTML elements, and then add the modified style sheet to the document.
Disadvantages:
1. Only external style sheets can be processed. The <style> </style> elements embedded in the page are not processed.
2. You need to re-load the Style Sheet Using ajax to consume unnecessary resources.
3. for complex Selection Characters, they are replaced by a simple class name. The original CSS priority weight relationship is severely damaged.
4. The modified style sheet breaks the original order and may affect the priority.
5. The key is that it currently does not support using the sub-element selector "E> F" in IE6"
Next we will discuss how to further enhance the support for IE separators.:
IE provides some Dom APIs to access CSS rules (CSS rules). The code format is roughly as follows:
Document. stylesheets // obtain all the style sheets of the current document, including the document on the external and page. stylesheets [0]. rules // obtain all the rules document for a style sheet. stylesheets [0]. rules [0]. selectortext // plain text // obtain the content document of the style rule. stylesheets [0]. removerule ([Index]); // remove a style rule document. stylesheets [0]. addrule (selector, csstext, [Index]); // adds a style rule.
Using these APIs, The selectivizr mentioned earlier may be avoided due to 1 or 2, but why does it not?
The possible cause is that rule. selectortext returns "unknow" or a string containing "unknow" for separators not supported by IE.
Therefore, you cannot use this API to learn the original selector text.
However, ie has another feature: the original text is basically maintained for the style rules that it does not support. For example
<style type="text/css">:my-pseudo-class {foo: bar;}[attr] {selector: [attr];}</style><script type="text/javascript">alert(document.styleSheets[0].rules.length);alert(document.styleSheets[0].rules[0].selectorText); // :unknowalert(document.styleSheets[0].rules[0].style.cssText); // foo: baralert(document.styleSheets[0].rules[1].selectorText); // UNKNOWalert(document.styleSheets[0].rules[1].style.cssText); // selector: [attr]</script>
Therefore, in the new solution, we can take a compromise to solve the shortcomings of the first two points:
First, obtain the selector:
Specify a format (style attribute name) and use CSS hack to record the selector, for example, "selector: Body> nav ";
The rule content is extracted through rule.style.css text and parsed by selector (skip if the selector attribute is not included ).
Analyze the selector and create a new class name to replace the selector:
Complex delimiters with "include selector" (e f) relationships are divided into multiple segments based on the contained hierarchy;
Analyze each segment in sequence. If IE6 is fully supported, no processing is performed;
If a segment contains pseudo classes (: pseudo-class), attributes ([ATTR]), links (E> F, E + F, E ~) that are not supported by IE6 ~ F), multi-class names (. cls1.cls2) and other delimiters, create a new class name corresponding to this segment, and add a new class name to the corresponding HTML element (this can be done using the "fourth party" library );
After each segment is processed, it is combined into a new "include selector" in the original order, and the original rule is replaced by removerule () and addrule.
If there is no "include" Link, you can directly create a new class name to replace it.
At this point, the above 3, 4, and 5 points are also basically solved.
Advantages of the new solution:
1. Supports in-page styles and external styles.
2. minimize the impact of priority weight on replacement of complex separators.
3. good scalability. It can support new types of delimiters that may appear in the future.
Disadvantages of the new solution:
1. CSS hack is used, and the style code increases the size;
2. You need to determine which selector is not supported by IE in advance, and maintenance may cause a little trouble (the selector that requires hack must be written twice), but it may be processed through some automated scripts.
Further Optimization:
After the content of the document changes dynamically, You need to review the association between the document elements and the new class names.
For IE6 ~ 8. Different versions are optimized.
Extended thinking:
During the investigation, I considered whether other non-ie browsers can use similar hack methods to implement some "selector" that the browser itself does not support ", however, at present, no method is found to facilitate reading of hack writing through APIS. the only method that can be used is the font-family attribute, which can contain various characters and is easy to read and can also be selectively ignored by the browser.
PS: the IE selector supports simple test.
<SCRIPT type = "text/JavaScript"> function issupportselector (selector) {var head = document. getelementsbytagname ('head') [0]; var style = primary text = selector + '{}'; // alert(style.stylesheet.css text); var support =! /Unknow/I .test(style.stylesheet.css text); head. removechild (style); return support;} alert (issuppselecselector ('nav A'); alert (issupportselector ('nav: First-child ')); alert (issuppselecselector ('nav: First-Child A'); alert (issuppselecselector ('. cls1.cls2 '); // multi-class names cannot be detected, to be improved </SCRIPT>
PS: For details about selector parsing, refer to the chunker Regular Expression in jquery/sizzle source code.
PS: currently, only the idea is recorded, and there is no complete code implementation.