{"id":20,"date":"2005-03-27T04:58:31","date_gmt":"2005-03-27T09:58:31","guid":{"rendered":"http:\/\/wahlers.com.br\/claus\/blog\/?p=20"},"modified":"2005-10-28T14:36:03","modified_gmt":"2005-10-28T19:36:03","slug":"css3-selectors","status":"publish","type":"post","link":"http:\/\/wahlers.com.br\/claus\/blog\/css3-selectors\/","title":{"rendered":"CSS3 Selectors"},"content":{"rendered":"<p>Recently, i continued porting the DENG1 CSS parser to ECMAScript 4 (AS2, to be specific), and making it fully compliant to the CSS3 specification. The current AS1 version of the parser already has many CSS3 features implemented, but not all of them (like the <code>nth-child()<\/code>, <code>nth-last-child()<\/code>, <code>nth-of-type()<\/code> and <code>nth-last-of-type()<\/code> pseudo classes for example, that required a special type of argument that wasn&#8217;t supported by the parser yet).<\/p>\n<p>Part of the work was commenting changes in the grammar, to know what was added or changed from the CSS2.1 grammar, and to verify if the existing code fully conforms to the CSS3 grammar.<\/p>\n<p>I figured this might be an interesting read for some of you, so here it is. Disclaimer: Please note that the comments might not be accurate or complete. In doubt, please refer directly to the <a title=\"Link to the CSS3 Selectors module\" href=\"http:\/\/www.w3.org\/TR\/2001\/CR-css3-selectors-20011113\/\">Selectors module<\/a> of the <a title=\"Link to the Introduction to CSS3\" href=\"http:\/\/www.w3.org\/TR\/2001\/WD-css3-roadmap-20010406\/\">CSS3 specification<\/a> at W3C.<\/p>\n<p><strong>Commented grammar for CSS3 Selectors Module<\/strong><\/p>\n<p>It is now specified that only one pseudo element is allowed in a selector, and that this pseudo element has to occur as the very last element. Pseudo classes can occur anywhere in a simple selector sequence.<\/p>\n<blockquote>\n<pre>selector\r\n  \/* there is at least one sequence of simple selectors *\/\r\n  \/* in a selector and the pseudo-elements occur only *\/\r\n  \/* in the last sequence; only one pseudo-element may *\/\r\n  \/* occur *\/\r\n  : [ simple_selector_sequence combinator ]*\r\n       simple_selector_sequence [ pseudo_element ]?\r\n  ;<\/pre>\n<\/blockquote>\n<p>New combinators <code>~<\/code> (indirect adjacent combinator) and <code>*<\/code> (descendant combinator) have been introduced (the <code>*<\/code> combinator is not contained in the current CSS3 grammar though).<\/p>\n<blockquote>\n<pre>combinator\r\n  \/* combinators can be surrounded by white space *\/\r\n  : S* [ '+' | '&gt;' | '~' | \/* empty *\/ ] S*\r\n  ;<\/pre>\n<\/blockquote>\n<p>Typeselectors and the universal selector (<code>*<\/code>) have an optional namespace prefix now. Both the typeselector and the universal selector are optional.<\/p>\n<p>The grammar for <code>negation<\/code> is missing in the current CSS3 grammar, it should look similar to the rule for <code>pseudo_class<\/code>, with a function identifier <code>not()<\/code> and one or more <code>negation_args<\/code> as function argument. The grammar is incomplete here. Example: <code>a:not([href])<\/code>.<\/p>\n<blockquote>\n<pre>simple_selector_sequence\r\n  \/* the universal selector is optional *\/\r\n  : [ type_selector | universal ]?\r\n        [ HASH | \r\n          class | \r\n          attrib | \r\n          pseudo_class | \r\n          negation ]+ |\r\n    type_selector | universal\r\n  ;\r\n\r\ntype_selector\r\n  : [ namespace_prefix ]? element_name\r\n  ;\r\n\r\nelement_name\r\n  : IDENT\r\n  ;<\/pre>\n<\/blockquote>\n<p>A namespace prefix, if used, needs a preceding <code>@namespace<\/code> rule, where the namespace prefix is associated with a namespace URL. Let&#8217;s assume we want to mix SVG and XHTML markup in the same document. Both SVG and XHTML feature the <code>&lt;a&gt;<\/code> element. We most likely want the <code>&lt;a&gt;<\/code> element to appear different in the SVG context (i.e. shape appears with a stroke) than in the XHTML context (text appears underlined). <\/p>\n<p>Using the <code>@namespace<\/code> rule and namespaced prefixes we can write rules that apply either to SVG&#8217;s or to XHTML&#8217;s &lt;a&gt; element:<\/p>\n<pre>@namespace xhtml url(http:\/\/www.w3.org\/1999\/xhtml);\r\n@namespace svg url(http:\/\/www.w3.org\/2000\/svg);\r\nxhtml|a[href] { text-decoration: underlined; }\r\nsvg|a[href] { stroke-width: 2px; }<\/pre>\n<blockquote>\n<pre>namespace_prefix\r\n  : [ IDENT | '*' ]? '|'\r\n  ;\r\n\r\nuniversal\r\n  : [ namespace_prefix ]? '*'\r\n  ;\r\n\r\nclass\r\n  : '.' IDENT\r\n  ;<\/pre>\n<\/blockquote>\n<p>Attribute simple selectors allow an optional namespace prefix for the attribute <code>ident<\/code> now.<\/p>\n<p>Prefixmatch (<code>^=<\/code>), suffixmatch (<code>$=<\/code>) and substringmatch (<code>*=<\/code>) operators have been introduced.<\/p>\n<p>Example: we want to style <code>&lt;a&gt;<\/code> elements with the <code>href<\/code> attribute set to an URL starting with &quot;http:\/\/wahlers.com.br&quot; differently than other <code>&lt;a&gt;<\/code> elements. we are using the prefixmatch operator:<\/p>\n<pre>a[href] {\r\n   font-weight: bold;\r\n}\r\na[href ^= &quot;http:\/\/wahlers.com.br&quot;] {\r\n   font-style: italic;\r\n}<\/pre>\n<p>All <code>&lt;a&gt;<\/code> elements with the <code>href<\/code> attribute set appear bold, <code>&lt;a&gt;<\/code> elements with a <code>href<\/code> attribute starting with &quot;http:\/\/wahlers.com.br&quot; appear bold and italic.<\/p>\n<blockquote>\n<pre>attrib\r\n  : '[' S* [ namespace_prefix ]? IDENT S*\r\n        [ [ PREFIXMATCH |\r\n            SUFFIXMATCH |\r\n            SUBSTRINGMATCH |\r\n            '=' |\r\n            INCLUDES |\r\n            DASHMATCH ] S* [ IDENT | STRING ] S*\r\n        ]? ']'\r\n  ;\r\n\r\npseudo_class\r\n  \/* a pseudo-class is an ident, or a function taking *\/\r\n  \/* an ident or a string or a number or a simple  *\/\r\n  \/* selector (excluding negation and pseudo- *\/\r\n  \/* elements) or a an+b expression for argument *\/\r\n  : ':' [ IDENT | functional_pseudo ]\r\n  ;<\/pre>\n<\/blockquote>\n<p>&quot;an+b&quot; expressions have been introduced as argument for functional pseudo classes (select nodes depending on their position). Allowed argument types include <code>string<\/code>, <code>number<\/code>, &quot;an+b&quot; <code>expression<\/code> and <code>negation<\/code> now, in addition to <code>ident<\/code> (the only allowed argument type in CSS2.1).<\/p>\n<p>Example: style even and odd rows of a table differently:<\/p>\n<pre>tr { background-color: #eee; }\r\ntr:nth-child(2n) { background-color: #ccc; }<\/pre>\n<blockquote>\n<pre>functional_pseudo\r\n  : FUNCTION S* [ IDENT | STRING | NUMBER |\r\n      expression | negation_arg ] S* ')'\r\n  ;\r\n\r\nexpression\r\n  :  [ [ '-' | INTEGER ]? 'n' [ SIGNED_INTEGER ]? ] |\r\n      INTEGER\r\n  ;\r\n\r\nnegation_arg\r\n  : type_selector |\r\n    universal |\r\n    HASH |\r\n    class |\r\n    attrib |\r\n    pseudo_class\r\n  ;<\/pre>\n<\/blockquote>\n<p>Pseudo elements are now prefixed by <code>::<\/code> (instead of <code>:<\/code> in CSS2.1) to distinguish between pseudo elements and pseudo classes. For backwards compatibility with CSS2.1 and previous, user agents have to accept the <code>:<\/code> notation for pseudo elements defined in earlier specs (like <code>:before<\/code> and <code>:after<\/code>).<\/p>\n<blockquote>\n<pre>pseudo_element\r\n  : [ ':' ]? ':' IDENT\r\n  ;<\/pre>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Recently, i continued porting the DENG1 CSS parser to ECMAScript 4, and making it fully compliant to the CSS 3 specification. The current AS1 version of the parser already has many CSS 3 features implemented, but not all of them (like the nth-child(), nth-last-child(), nth-of-type() and nth-last-of-type() pseudo classes for example, that required a special type of argument that wasn&#8217;t supported by the parser yet). Part of the work was commenting changes in the grammar, to know what was added or changed from the CSS 2.1 grammar, and to verify if the existing code fully conforms to the CSS 3 grammar. I figured this might be an interesting read for some of you, so here it is&#8230; <a href=\"http:\/\/wahlers.com.br\/claus\/blog\/css3-selectors\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-20","post","type-post","status-publish","format-standard","hentry","category-css"],"_links":{"self":[{"href":"http:\/\/wahlers.com.br\/claus\/blog\/wp-json\/wp\/v2\/posts\/20","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/wahlers.com.br\/claus\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/wahlers.com.br\/claus\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/wahlers.com.br\/claus\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/wahlers.com.br\/claus\/blog\/wp-json\/wp\/v2\/comments?post=20"}],"version-history":[{"count":0,"href":"http:\/\/wahlers.com.br\/claus\/blog\/wp-json\/wp\/v2\/posts\/20\/revisions"}],"wp:attachment":[{"href":"http:\/\/wahlers.com.br\/claus\/blog\/wp-json\/wp\/v2\/media?parent=20"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/wahlers.com.br\/claus\/blog\/wp-json\/wp\/v2\/categories?post=20"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/wahlers.com.br\/claus\/blog\/wp-json\/wp\/v2\/tags?post=20"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}