ABSTRACT
If you ever do art, you know that for any given medium, you can buy a great many hues in tubes. However, the true power and flexibility comes from having just a few, basic colors, and mixing them together into many others. This is what is meant by an artist’s “palette.” The term refers to the hues chosen by the artist as the “base colors” of their mixes, as well as the way they mix them.
CHOOSING OUR PALETTE
When using pre-mixed colors, the choices are limited, even for manufacturers with a great variety. When mixing your own colors, the possibilities are endless.
Most experienced artists don’t stick to just one manufacturer for their base colors. They may choose Windsor and Newton Alazarin Crimson, Da Vinci Cerulean Blue and Schmincke Horadam Cobalt Green. Using a similar logic, we won’t stick to just one technique or philosophy for our CSS rules. We need to learn to look at what everybody does, and start from a position where we are already “mixing our own.”
We need to choose our palette.
We already have a pretty good idea of our “base colors,” and the rules we use to “mix” them:
- We have the four levels of specificity:
- cascaded (inherited) Specificity from an Element’s Parent (Container) Elements;
- Generic Element Specificity that Applies to all Elements of that Name;
- Class Specificity, keying on the “class” attribute, and
- ID specificity, keying on an element’s “id” attribute.
- We have our basic specificity modifiers:
- Including an Element’s Parents in Our Rule Selector, and
- The Order in Which the Rules are Specified.
Reviewing Our Structure
Let’s review our markup once again, sans style:
<html> <head> <title>Example 33</title> </head> <body id="mr_boddy" class="overall_body_class"> <div class="container_class" id="main_container"> This text is in the main, outer container. <div class="secondary_container_class" id="secondary_container"> This text is in one level. <p class="tertiary_container_class" id="tertiary_container"> This text is in two levels. </p> </div> <div class="secondary_container_class secondary_container_class_2" id="secondary_container_2"> This text is in one level, but via a second container. <p class="another_container_class" id="another_container"> This text is in two levels. </p> </div> <p class="inside_container_class" id="yet_another_container"> This text is in one level, but via a third container. </p> </div> <p class="outside_container_class" id="yet_another_silly_container"> This text is in a second, outer container. </p> </body> </html>
Say we want to apply a style to just the first element that says: “This text is in two levels.” This is a <p> element inside of a <div> element, inside another <div> element, inside a <body> element, inside of an <html> element (also referred to as the “root” element). The element has a class attribute with a value of “tertiary_container_class”, and an ID attribute set to “tertiary_container”.
<body id="mr_boddy" class="overall_body_class"> <div class="container_class" id="main_container"> This text is in the main, outer container. <div class="secondary_container_class" id="secondary_container"> This text is in one level. <p class="tertiary_container_class" id="tertiary_container"> This text is in two levels. </p> </div> <div class="secondary_container_class secondary_container_class_2" id="secondary_container_2"> This text is in one level, but via a second container. <p class="another_container_class" id="another_container"> This text is in two levels. </p> </div> <p class="inside_container_class" id="yet_another_container"> This text is in one level, but via a third container. </p> </div> <p class="outside_container_class" id="yet_another_silly_container"> This text is in a second, outer container. </p> </body>
Now, there are a few ways that we can affect this node value. For purposes of our demonstration, we’ll turn the text red, and make it bold.
The first, and most obvious way, is to use the color straight from the tube, and select the ID of the element:
#tertiary_container { font-weight:bold; color: red }
However, we can also select it by saying “apply this to a <p> element contained in another element with an ID of ‘secondary_container’.” You do this by separating them with a space. The specifier to the right of the space is the container (parent element), and the one to the left of the space is the child element. Don’t use commas! Commas separate selectors. Spaces separate containers from contents.
#secondary_container p { font-weight:bold; color: red }
Since there is only one <p> element inside the <div> element, maybe we can even apply the rule to the enclosing <div>”
#secondary_container { font-weight:bold; color: red }
Oops. No, that didn’t work, because the style was applied to the node value for the <div> as well. How about specifying the class of the container?
.secondary_container_class p { font-weight:bold; color: red }
No, that didn’t work either, as there are two <div> elements with that class. However, you can see how we can use this type of thing to focus our styles to certain elements. There may be many places where this effect is exactly what we want.
Okay, we’ve figured out that if we want to target just that one element, we need to use ID selectors; either for the element itself, or for its container, with a general element specifier for the element itself. However, while we were doing this, we found out that we can affect the two <p> elements inside of <div> elements with a class of “secondary_container_class”. That’s useful information. This is also exactly how we can explore the world of CSS-based design. Sometimes, the wrong turns can lead us to even more interesting places than our original destination. Like Recovery, the Journey can be more important than the destination.
Now, let’s combine what we just found out with a specific target, and turn both of the elements’ node values bold, but only the first one red:
.secondary_container_class p { font-weight:bold } #tertiary_container { color: red }
What we did here was use a lower specificity rule to cover multiple elements, and a higher specificity rule to target one particular element, and add an additional property.
Now, that wasn’t actually a really good example of using increased specificity to override a property applied by a lower specificity. We can easily address that:
.secondary_container_class p { font-weight:bold; color:green } #tertiary_container { color: red }
In this case, the higher specificity rule applied a “color:red” property that overrode the “color:green” property applied by the more general rule.
Let’s Get A Little Crazy
Okay, now we’re gonna get a bit crazy. Don’t click on the link until you’ve read through the following section:
div { color:purple } p { color:green; font-weight:medium } .secondary_container_class p { font-weight:bold } div p { color: yellow } #tertiary_container { color: red }
What do you think will happen here?
Let’s examine the rules and our markup, and see if we can figure it out:
To start, let’s look at the first rule. We’ll figure out which elements it affects:
<html> <head> <title>Example 48</title> <style type="text/css"> div { color:purple } p { color:green; font-weight:medium } .secondary_container_class p { font-weight:bold } div p { color: yellow } #tertiary_container { color: red } </style> </head> <body id="mr_boddy" class="overall_body_class"> <div class="container_class" id="main_container"> This text is in the main, outer container. <div class="secondary_container_class" id="secondary_container"> This text is in one level. <p class="tertiary_container_class" id="tertiary_container"> This text is in two levels. </p> </div> <div class="secondary_container_class secondary_container_class_2" id="secondary_container_2"> This text is in one level, but via a second container. <p class="another_container_class" id="another_container"> This text is in two levels. </p> </div> <p class="inside_container_class" id="yet_another_container"> This text is in one level, but via a third container. </p> </div> <p class="outside_container_class" id="yet_another_silly_container"> This text is in a second, outer container. </p> </body> </html>
Wow. That is gonna affect the whole page. Every <div> element is going to have its node value (and that of child elements) displayed purple.
There will be only one single node not affected by this:
<p class="outside_container_class" id="yet_another_silly_container"> This text is in a second, outer container. </p>
That’s because it’s the only one not surrounded by a <div> element.
Let’s break down the rule:
Every <div> element will have its node value displayed as purple. This will be at specificity level 2 for <div> elements, and specificity level 1 for child elements contained within <div> elements.
Let’s look at the next one:
<html> <head> <title>Example 48</title> <style type="text/css"> div { color:purple } p { color:green; font-weight:medium } .secondary_container_class p { font-weight:bold } div p { color: yellow } #tertiary_container { color: red } </style> </head> <body id="mr_boddy" class="overall_body_class"> <div class="container_class" id="main_container"> This text is in the main, outer container. <div class="secondary_container_class" id="secondary_container"> This text is in one level. <p class="tertiary_container_class" id="tertiary_container"> This text is in two levels. </p> </div> <div class="secondary_container_class secondary_container_class_2" id="secondary_container_2"> This text is in one level, but via a second container. <p class="another_container_class" id="another_container"> This text is in two levels. </p> </div> <p class="inside_container_class" id="yet_another_container"> This text is in one level, but via a third container. </p> </div> <p class="outside_container_class" id="yet_another_silly_container"> This text is in a second, outer container. </p> </body> </html>
It will affect all <p> elements, but at a specificity level of 2. Remember what I said about specificity applying to the properties of a rule; not the rule itself? Let’s look at how this rule works for us in a simple breakdown:
Every <p> element in the page is colored green, at a specificity level of 2. This overrides the level 1 purple color of <p> elements contained within <div> elements.
Every <p> element in the page has a font weight of “medium,” at a specificity level of 2.
Fair enough, let’s look at the next rule:
<html> <head> <title>Example 48</title> <style type="text/css"> div { color:purple } p { color:green; font-weight:medium } .secondary_container_class p { font-weight:bold } div p { color: yellow } #tertiary_container { color: red } </style> </head> <body id="mr_boddy" class="overall_body_class"> <div class="container_class" id="main_container"> This text is in the main, outer container. <div class="secondary_container_class" id="secondary_container"> This text is in one level. <p class="tertiary_container_class" id="tertiary_container"> This text is in two levels. </p> </div> <div class="secondary_container_class secondary_container_class_2" id="secondary_container_2"> This text is in one level, but via a second container. <p class="another_container_class" id="another_container"> This text is in two levels. </p> </div> <p class="inside_container_class" id="yet_another_container"> This text is in one level, but via a third container. </p> </div> <p class="outside_container_class" id="yet_another_silly_container"> This text is in a second, outer container. </p> </body> </html>
This rule only applies to two of the elements on the page. It will make them bold. The specificity levels of this rule’s properties are not as easy to determine as the previous rule’s; but we can be assured that they are higher than 2, as the rule adds a parent specifier to the mix, overruling the “font-weight:medium” rule specified for <p> elements at specificity level 2. These two elements will be bold.
Moving right along, let’s look at the next one:
<html> <head> <title>Example 48</title> <style type="text/css"> div { color:purple } p { color:green; font-weight:medium } .secondary_container_class p { font-weight:bold } div p { color: yellow } #tertiary_container { color: red } </style> </head> <body id="mr_boddy" class="overall_body_class"> <div class="container_class" id="main_container"> This text is in the main, outer container. <div class="secondary_container_class" id="secondary_container"> This text is in one level. <p class="tertiary_container_class" id="tertiary_container"> This text is in two levels. </p> </div> <div class="secondary_container_class secondary_container_class_2" id="secondary_container_2"> This text is in one level, but via a second container. <p class="another_container_class" id="another_container"> This text is in two levels. </p> </div> <p class="inside_container_class" id="yet_another_container"> This text is in one level, but via a third container. </p> </div> <p class="outside_container_class" id="yet_another_silly_container"> This text is in a second, outer container. </p> </body> </html>
All three <p> elements contained within a <div> element are affected. The specificity for them would be:
All <p> elements contained within a <div> element will have their text displayed as yellow, at a specificity level greater than 2. This overrides the green color specified at specificity level 2 for <p> elements in a prior rule.
Okay, last, but not least, we have the fourth rule:
<html> <head> <title>Example 48</title> <style type="text/css"> div { color:purple } p { color:green; font-weight:medium } .secondary_container_class p { font-weight:bold } div p { color: yellow } #tertiary_container { color: red } </style> </head> <body id="mr_boddy" class="overall_body_class"> <div class="container_class" id="main_container"> This text is in the main, outer container. <div class="secondary_container_class" id="secondary_container"> This text is in one level. <p class="tertiary_container_class" id="tertiary_container"> This text is in two levels. </p> </div> <div class="secondary_container_class secondary_container_class_2" id="secondary_container_2"> This text is in one level, but via a second container. <p class="another_container_class" id="another_container"> This text is in two levels. </p> </div> <p class="inside_container_class" id="yet_another_container"> This text is in one level, but via a third container. </p> </div> <p class="outside_container_class" id="yet_another_silly_container"> This text is in a second, outer container. </p> </body> </html>
This affects only one particular element, and overrides the greater than specificity level 2 color (yellow) applied by the third rule.
Okay, time to predict what the output will look like. I’ll fake it with some inline styles:
Bingo. We nailed it.
In the next posting, I’ll go over a pseudo-mathematical way to determine specificity.