[Dataisland-developer] CSS3 selectors
Status: Alpha
Brought to you by:
varsenault
|
From: Vincent-Olivier A. <vi...@up...> - 2003-06-19 15:45:00
|
Hello, this is for my favourite designers in the world. There is a nice arti= cle=20 on the new CSS3 selectors on Oreilly Network. Here it is : http://www.xml.com/lpt/a/2003/06/18/css3-selectors.html *CSS 3 Selectors* *By* Russell Dyer Although the promise of Cascading Style Sheets (CSS) has been wondrou= s,=20 the progress has been wanting. As with all W3C <http://www.w3.org/>= =20 standards, there is the lengthy discussion process conducted by the= =20 related working group, then the problem of implementation by web brow= ser=20 vendors, and finally the unpredictable period of time for people to= =20 update to new versions of their browser. These steps can take a year = or=20 two each. To expedite the process, the CSS working group has started= =20 grouping related features into modules and releasing them separately,= =20 without waiting for completion of all modules. This allows browser= =20 vendors to proceed with implementation of CSS updates with the=20 confidence that standards won't be changed by the time the full relea= se=20 of CSS is approved. Ideally the result will be to reduce the process = by=20 a year or more. One CSS module that has recently been moved to /Recommended/ (or=20 finished) status by the CSS working group is the /Selectors/ module.= =20 Although it was completed just a few weeks ago, much of it has alread= y=20 been implemented by some of the browser vendors. The vendors seem ver= y=20 keen to expedite the /Selectors/ module since it can improve HTML and= =20 XML document design decidedly and for fairly little effort. As CSS= =20 grows, more selectors are adopted, although some can be pruned. This= =20 article will review all currently approved selectors. It will address= =20 the surviving CSS1 and CSS2 selectors in brief and the new CSS3=20 selectors in more detail. Basic Definitions A /cascading style sheet/ is used to set or change the styles of a= =20 markup document like a web page. Style sheets contain /rules/ that we= b=20 browsers follow when loading a web page, an XML document, or any=20 document written in a compatible markup language. A style sheet rule = is=20 composed of two basic components: a /selector/ and a /declaration/. T= he=20 selector is an identifier of a markup tag. For example, in HTML, p is= =20 the selector for <p> (or paragraph) tags. Declarations are the style= =20 settings that are to be applied by the browser when it encounters a= =20 match in a document for a selector. There are many different=20 declarations that may be made, but it is only selectors that concern = us=20 here. So when providing examples, I will focus on selectors and not= =20 comment on declarations. CSS1 Selector Basics The basic value of a selector is to point to objects or text for whic= h a=20 designer would like to set the style. For instance, suppose one decid= ed=20 to set to navy blue the main heading of each web page on a site=20 containing over a thousand pages. If all of the pages are linked to t= he=20 same style sheet and each page's main heading is wrapped in <h1> tags= ,=20 then the task would be simple and quick. It would be a matter of mere= ly=20 inserting into to the style sheet the simple rule below: h1{color: navy;} Occasionally designers need to select elements by /class/ or by uniqu= e=20 /identifiers/. Suppose a web page contains several tables and the= =20 designer wants the background color of some tables to be silver. Clas= s=20 selectors can be utilized by assigning a class to tables that are to = be=20 colored. One would place the first line below in the style sheet and= =20 start off silver tables in the document like the second line: table.special{background-color: silver;} <table class=3D'special'> To change the style for only one element on a site, an identification= =20 (ID) can be used: table#unique{background-color: pink;} <table ID=3D'unique'> In CSS1 a few /pseudo-class/ selectors were provided for anchor (<a>)= =20 elements: :link, :visited, :active,:hover, and :focus. These can be u= sed=20 to change the style of links depending on their state or on user=20 interaction. Two /pseudo-element/ selectors were also provided: the= =20 ::first-letter and the ::first-line selectors are for styling the fir= st=20 letter and the first line contained between selected tags.=20 Pseudo-elements are distinguished by two colons and they can affect= =20 partial content, but the declarations of pseudo-class selectors are= =20 applied to all of the content. A powerful function found in CSS1 is the /descendant combinator/. It= =20 allows the designer to select markup elements contained within anothe= r=20 specified element. One simply gives the parent element, then a space= =20 followed by the descendant. Don't confuse this syntax with that of= =20 grouping selectors (e.g., h1, h2, h3{...}). This rule will make the t= ext=20 within <quote> tags italic and green, but only when inside a paragrap= h: p quote{font-style: italic; color: green;} To style elements contained within elements that are contained within= =20 ancestor elements, that is, to style grandchildren elements, one woul= d=20 use an asterisk with spaces around it as a combinator: p * quote{font-style: italic; color: green;} From these basic selectors, designers have been able to standardize = the=20 styles of markup documents and reduce design and production time=20 significantly for the last few years. This has been especially critic= al=20 for XML developers since XML doesn't have default styling conventions= . CSS2 Selectors CSS2 offered a universal selector (*) to allow selection of specified= =20 elements of /all/ parents. For instance, this rule will select TD cel= ls=20 of all tables: *.td{font-size: 85%;} CSS2 expanded selectors to include discerning the values of element= =20 attributes. In HTML an image element (<img/>) may contain attributes= =20 like src, alt, align, and border. One can check if an image tag has a= =20 specified attribute. To set the padding only for images where the bor= der=20 is given, this rule will suffice: img[border]{margin: 5px;} You can also check if a value is contained in a space separated list= =20 contained in an attribute (e.g., img[alt~=3D"fish"]{...}). Or one can= =20 check the full value for an exact match: img[src=3D"logo.gif"]{border: 0;} CSS2 also expanded /descendant/ selector possibilities. The=20 pseudo-element selectors ::before and ::after allow one to add conten= t=20 before and after elements found. If one marked up the text of a play= =20 with XML tags around the dialog to identify a character's lines (e.g.= ,=20 <romeo>...</romeo>), one could use CSS to add text before and after e= ach=20 set of lines: romeo::before{content: "Romeo: \"";} romeo::after{content: "\"";} Starting in CSS2, designers can now change the style for the /first= =20 child/ of an element. To double the size of the first letter of the= =20 first paragraph of each section of a document (provided each section = is=20 enclosed in <div class=3D'section'></div> tags), try this: div.section:first-child::first-letter{font-size: 200%;} Notice that the parent is div; /section/ is the class, not the child.= =20 The child is whatever the browser finds first. It will double the siz= e=20 of the first letter of each child's content. A /child combinator/ selector was added to be able to style the conte= nt=20 of elements contained within other specified elements. For example,= =20 suppose one wants to set white as the color of hyperlinks inside of d= iv=20 tags for a certain class because they have a dark background. This ca= n=20 be accomplished by using a period to combine div with the class=20 /resources/ and a greater-than sign as a combinator to combine the pa= ir=20 with a, as shown below: div.resources > a{color: white;} Also added in CSS2 was the /direct adjacent combinator/. For example,= =20 imagine you want to indent all paragraphs in a document except for on= es=20 immediately following a sub-heading (<h2>). The second rule below sho= ws=20 an h2 selector combined with a p selector using a plus sign as the= =20 combinator to indicate that the declaration applies only if p=20 immediately follows h2: p{text-indent: 0.5in;} h2 + p{text-indent: 0;} Finally, consider the language selector. The :lang selector is for= =20 selecting a document of a specific language: html:lang(en){color: black;} xml:lang(en){color: gray;} Similarly, the hreflang attribute of the link element can be used wit= h=20 the attribute value selector that checks for a value and the same val= ue=20 followed by a hyphen. The following rule will match French (fr) and= =20 Belgian French (fr-be): link[hreflang|=3D"fr"]{font-style: italic; =09 by Russell Dyer Implemented CSS3 Selectors The Mozilla Project has already implemented several CSS3 selectors an= d=20 is working on implementing the rest soon. The other vendors aren't fa= r=20 behind, either. Let's look at what Mozilla has implemented first. Three more attribute selectors were added in CSS3; they allow for= =20 substring selection. One matches elements based on the beginning valu= es=20 of named attributes. This could be useful, for instance, if one wants= to=20 have different styles for hyperlinks to a sub-domain (e.g.,=20 sales.somesite.com), as opposed to the main domain (e.g., www.somesit= e.com): a[href^=3D'http://sales.']{color: teal;} To select elements based on the ending value of attributes, the carat= =20 above would be replaced with a dollar sign. The rule below would let= =20 users know that they are about to click on a link to a Java Server Pa= ge. a[href$=3D'.jsp']{color: purple;} CSS3 also provides substring matching irrespective of word boundaries= .=20 So if one wants to set the border for images from a particular direct= ory=20 (say, /images/artwork/), this rule will accomplish the task: img[src*=3D'artwork']{ border-color: #C3B087 #FFF #FFF #C3B087;} A few more pseudo-class selectors were added in CSS3. One is the :roo= t=20 selector, which allows designers to point to the root element of a= =20 document. In HTML, it would be <html>. Since :root is generic, it all= ows=20 a designer to select the root element of an XML document without=20 necessarily knowing it's name. To permit scrollbars when needed in a= =20 document, this rule would work: :root{overflow:auto;} As a complement to the :first-child selector, the :last-child was add= ed.=20 With it one can select the last element named of a parent element. Fo= r a=20 magazine site with articles contained in <div class=3D'article'></div= >=20 tags, where each has a last paragraph with author information, this r= ule=20 would change the font for each writer's blurb: div.article > p:last-child{font-style: italic;} The parent here is a div with /article/ as the class. Once the browse= r=20 finds such a div tag, it then looks for matching children (<p> tags= =20 here). It then selects the last paragraph and adjusts its style based= on=20 the rule's declaration. A new user interaction pseudo-class selector was added: the :target= =20 selector. To draw the user's attention to a span of text when the use= r=20 clicks on a same-page link, a rule like the first line below would wo= rk=20 nicely; the link would look like the second line, the highlighted spa= n=20 like the third: span.notice:target{font-size: 2em; font-style: bold;} <a href=3D'#section2'>Section 2</a> <p id=3D'section2'>...</p> To complement the direct adjacent combinator introduced in CSS2, the= =20 /indirect adjacent combinator/ was included in CSS3. It's used in= =20 situations where two specified elements are of the same parent and th= e=20 second element follows the first, but not immediately afterward. To= =20 render text as bold when it's contained within <tt> tags, but not whe= n=20 contained within a table, since there will be many elements for the= =20 browser to consider (e.g., <tr> and <td> tags) before it would reach = a=20 <tt> tag, a direct adjacent combinator selector wouldn't work. But an= =20 indirect adjacent combinator selector could handle this: tt{font-weight:bold;} table ~ tt{font-weight: normal;} Finally, a functional notation for selecting specified elements that= =20 fail a test has been created. The negation pseudo-class selector (:no= t)=20 can be coupled with almost any other selector that has been implement= ed.=20 To put a border around images that don't have a border specified, use= a=20 rule like this: img:not([border]){border: 1;} Unimplemented CSS3 Selectors The selectors that are yet to be implemented are a little more=20 complicated but very powerful; they should be implemented soon by the= =20 Mozilla Project. Almost all of them are pseudo-class selectors and ar= e=20 very similar. They will likely all be implemented by Mozilla simultan= eously. Quite often designers create online forms for users to complete. As t= he=20 user fills out portions of a form, based on the user's answers, some= =20 portions won't apply. To dynamically style text or input elements bas= ed=20 on whether an element is enabled or disabled, the :enabled and :disab= led=20 pseudo-class selectors have been devised: radio.creditcard_type:disabled{color: gray;} The :checked and :indeterminant pseudo-class selectors were created f= or=20 styling based on the status of check boxes and radio buttons. To=20 highlight the text associated with a check box once it has been check= ed,=20 use this rule: input:checked{background-color: blue; color: white;} For check boxes and radio buttons that start off with nothing checked= ,=20 one could highlight them to draw the user's attention to them as=20 required fields. In the example below, the input element has a class= =20 label of /required/: input.required:indeterminant{color: red;} Several descendant selectors await implementation. The :only-child= =20 selector is used to select elements that don't have any siblings. For= =20 instance, if one wants to indent paragraphs for sections (using XML= =20 <section> tags) only when there is more than one paragraph, this rule= =20 can solve the problem: section{text-indent: 0.5in;} section:only-child{text-indent: 0;} To style based on the uniqueness of type (i.e., no siblings), the= =20 :only-of-type selector is available. A related selector is :empty, us= ed=20 for selecting elements that have no children. Use the first rule belo= w=20 to style unique elements in a section and the second for sections wit= h=20 no children: section:only-of-type{text-style: italic;} section:empty{text-style: bold;} Along the same lines, one can style the first and last descendants ba= sed=20 on type. Suppose one has several documents (using <doc> tags) that= =20 involve the pattern of an introductory paragraph, several main=20 paragraphs, and a concluding paragraph. One could use this rule to st= yle=20 the first and last paragraphs differently: doc:first-of-type{text-style: bold;} doc:last-of-type{text-style: italic;} Keep in mind when using these pseudo-class selectors in which the= =20 element type is not specified, that stray elements might be styled= =20 unintentionally. A very handy and potentially confusing set of selectors that have bee= n=20 added in CSS3 are the /nth child/ pseudo-class selectors. These=20 structural selectors were made for designers to be able create precis= e=20 rules for climbing a document tree. Here's the basic format of an= =20 :nth-child selector: element:nth-child(an+b){...} The notation a represents the number of children by which the browser= is=20 to group. The notation b is the count of each grouping that is select= ed.=20 The n is always n and is not replaced with a number. To alternate the= =20 background of rows in a table, this rule could be deployed in the fut= ure: tr:nth-child(2n+1){background-color: magenta;} Notice here that the browser is to organize the rows into pairs and t= o=20 style the first of each pair. To highlight the first of three rows, t= hen=20 this is how the rule would read: tr:nth-child(3n+1){background-color: tan;} One could write a rule for each row of the three: tr:nth-child(3n+1){background-color: tan;} tr:nth-child(3n+2){background-color: fuschia;} tr:nth-child(3n+3){background-color: aqua;} There is some shorthand that can be used. Rather than 2n+1 for odd an= d=20 2n+2 for even, they can be replaced with odd and even: tr:nth-child(odd){background-color: maroon;} tr:nth-child(even){background-color: tan;} Incidentally, if a and b are equal, then b can be left out and the va= lue=20 of a will be the implied value of b. The rules below are equivalent a= nd=20 would be applied to the second row of each pair of rows (i.e., the ev= en=20 rows): tr:nth-child(2n+2){background-color: indigo;} tr:nth-child(2n){background-color: indigo;} For a non-repeating pattern, that is, to style one particular element= ,=20 then the a notation would be set to zero or just left out. The rules= =20 below are equivalent and will style just the eighth row: tr:nth-child(0n+8){background-color: silver;} tr:nth-child(n+8){background-color: silver;} tr:nth-child(8){background-color: silver;} To have the browser count elements starting from the bottom, use the= =20 :nth-last-child selector. The a notation uses a negative to indicate = a=20 reverse count. This rule styles the last two rows of a table: tr:nth-last-child(-n+2){background-color: violet;} To group on types for elements that are mixed with others, use=20 :nth-of-type selector. For instance, suppose one wants to alternate t= he=20 alignment of images in a document. These rules would do the trick: img:nth-of-type(2n+1){float: right;} img:nth-of-type(2n+2){float: left;} One can count based on type from the bottom, as well, by using the= =20 :nth-last-of-type selector. This rule aligns right only the last two = images: img:nth-last-of-type(-n+2){float: right;} CSS3 also has a content pseudo-class selector. The :contains selector= =20 searches the content of a specified element for a matching substring.= =20 This selector is for static media only (i.e., print and not screen= =20 display). A rule to style text when printed from a bullet list that= =20 contains the word "special," would look like this: li:contains("special"){text-style: italic;} Finally, to style text differently from the browser's default style t= hat=20 the user selects, the ::selection pseudo-element selector can be used= .=20 Typically, when text is selected by a user for copying, the backgroun= d=20 color changes to blue or black. This rule will alter the user selecte= d=20 text and limit alterations to text within paragraph tags: p::selection{ background-color: maroon; font-size: 200%;} Since this is a pseudo-element selector, only the selected text will = be=20 changed while selected and not the entire paragraph. Concluding Admissions Although I have attempted to cover all CSS selectors and give example= s=20 of each, there are some twists and aspects that I omitted. For instan= ce,=20 there are many ways to combine selectors to accomplish tasks. A few o= f=20 the example rules presented utilize two or more selectors, hinting at= =20 such potential complexities. I also didn't discuss the possibility of= =20 using different namespaces with selectors. There's also the issue of= =20 what to do about browsers that aren't CSS3 compatible, but are CSS2= =20 compatible. What will they ignore and with what will they meddle? If you would like more details, you can review the Web Consortium's= =20 documentation on Selectors=20 <http://www.w3.org/TR/2001/CR-css3-selectors-20011113/>. If you would= =20 like to test your browser for compatibility, try the Web Consortium's= =20 test pages <http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/>= .=20 For more on CSS in general, check out /CSS: The Definitive Guide=20 <http://www.oreilly.com/catalog/css/>/ by Eric Meyer. *XML.com* Copyright =A9 1998-2003 O'Reilly & Associates, Inc. |