Showing posts with label Selectors. Show all posts
Showing posts with label Selectors. Show all posts

Monday, October 4, 2010

Divs and Contextual Selectors

There are two ways to target those particular paragraphs, the first of which will be familiar
from Chapter 2. Now that divs have been introduced, however, it is no longer the best way.


The Bad Way

 
Knowing what you already know, it’s tempting to create a new class for turning the paragraphs
red, as follows:
/* Make text red */
.highlight {
color: #F00;
}
Then in the (X)HTML, the identifiers for our highlight class would need to be added like
so:
<div id="container">
<p>This is our content area.</p>
<div class="box">
<p class="highlight">I'm in a box!</p>
</div>
<div class="box">
<p class="highlight">I'm also in a box!</p>
</div>
</div>
The paragraphs will certainly be red now, but it’s taken extra markup for each opening
paragraph tag to accomplish the effect. This extra markup would be required for every paragraph
within the div, which is only serving to bloat the markup.


The Good Way

 
This time, the identifiers are not required. In fact, no changes need be made to the (X)HTML at
all. Everything can be controlled within the style sheet. Time to put the paragraphs into context
with the following combination:
/* Make text red only for paragraphs within the box class */
.box p {
color: #F00;
}
Using this approach, no extra markup is required. Everything needed to take complete
control of the paragraphs is already in place. The contextual selector is constructed to show
that the rule will only have an effect when the last selector (p) is a direct descendent (the child)
of the first selector (.box). This is a strong example of how major changes to whole sections can
be achieved simply by working with what you already have.
Another contextual selector could then be used to control paragraphs in the parent
element (the container div).

/* Make text gray only for paragraphs within the container */
#container p {
color: #333;
}
Now paragraphs inside the container will be rendered dark gray, unless contained by .box, in
which case they will be red.


Taking the Context Even Further

 
Let’s now assume that you are using the box class all over the site. Sometimes the box classes
are children of the container div, and sometimes they have a different parent. What if you only
want the paragraph text to appear bold when the box class is inside the container? This can be
achieved without extra markup also. Note that, outside of the container div, a new box div has
been added, which is not parented by anything:
<div id="container">
Content
<div class="box">
<p>I'm in a box!</p>
</div>
<div class="box">
<p>I'm also in a box!</p>
</div>
</div>
<div class="box">
<p>I'm also in a box!</p>
</div>
As for the amazing CSS, the contextual selector consists of three selectors, putting the
paragraphs into a more specific context.
/* Make text bold only for paragraphs within the box class AND within the ➥
container */
#container .box p {
font-weight:bold;
}
This contextual selector is very powerful. The first thing to note is that the markup is very
clean. Yes, division elements exist to separate the content, but no identifiers are required for
any base elements. The effect of the contextual selector is threefold:

Css Tutorial : Contextual Selectors

Now there’s a horribly scary term. In the previous section, a heading containing emphasized
text was used to illustrate basic inheritance. Remember that the em selector was added to ensure the
<em> element in the (X)HTML would be rendered with red text. Here’s the CSS again:
/* Top-level heading */
h1 {
color:#333;
}
/* Make emphasized text shine brightly */
em {
color:#F00;
}
The downside of this is that all emphasized text across the whole web site would also
become red, regardless of its parent element. Assuming the rule is only meant to target the <em>
element when a child of <h1> headings, a simple adjustment can be made to put the emphasized
text into context:
/* Make emphasized text shine brightly ONLY when it’s the child of an h1 heading */
h1 em {
color:#F00;
}
Contextual selectors consist of two or more simple selectors separated by whitespace.
Here the contextual selector is constructed to show that the rule will only have an effect when
the last selector (em) is a direct descendent (be it a child, grandchild, great grandchild, or so on)
of the first selector (h1). If the browser does not find an exact match (i.e., it only finds <em> elements
outside of <h1> elements), it will not apply the styles dictated by the contextual selector to them.
Here’s similar markup to the original example, but with a paragraph acting as the parent
to a second <em> element:

<h1>This is the greatest heading <em>in the world</em></h1>
<p>I'm sorry but it simply is <em>not</em>, you fool.</p>
The <em> element owned by the <h1> element will be red, whereas the one owned by the
paragraph will not—it will inherit the default font color. To control the style of any emphasized
text that is out of context, simply define a new selector for em with the values you desire, or
maybe create a new contextual selector with p as the parent to your em.
In Chapter 6, contextual selectors will be used to gain tight control of nested elements
such as hierarchical lists and other problematic situations.

Combining IDs with Selectors

Existing or new IDs can be combined with selectors in the style sheet to add further control. In
the following example, the base CSS defines all h2 headings as dark gray and 16 pixels in size:
/* Basic heading style */
h2 {
color:#333;
font-size:16px;
}


That is fine for most uses of <h2>, but let’s say the main <h2> on your page (the title of
an article) needs to be emphasized with a different color. This calls for a new rule where the
selector is defined in the form element#name:
/* Adjust the color of h2 when used as a title */
h2#title {
color:#F00;
}
Here the new rule will override the default <h2> color (color: #333;) with red (color: #F00;)
whenever an <h2> is identified with id="title" in the (X)HTML. The new rule does not redefine
font-size, so that will be carried over and unchanged. Simply add the unique identifier to
the page:
<h2 id="title">Title Of My Article</h2>
Remember that title is a unique identifier, so it cannot be used again within that template.
Any other instances of <h2> on the page will be rendered with the default styling.