June 26, 2012

Editor’s note: This How To assumes a basic understanding of HTML.

Along with HTML and JavaScript, CSS forms the foundation of the open Web. These three technologies power just about every website, and a basic understanding of each can go a long way toward preparing you to build and edit Web pages.

If HTML is about bringing meaning to content, CSS is about defining how our content looks — the layout and positioning of elements, the colors, the typography and other visual effects. HTML provides a skeletal structure, while CSS offers the outer shell.

CSS defines the appearance of just about every part of news or information website, including comment areas, forum pages and, of course, articles.

CSS and HTML work hand in hand. In fact, CSS is useless without an HTML document to graft on to. And, the better structured the HTML, the more seamlessly the CSS can be added. (Well-structured HTML means using the right tag for the right purpose, using the right number of tags, and organizing tags in the best way possible.)

Connect HTML & CSS with selectors

Generally, HTML lives in one file and CSS lives in another. While it’s technically possible to blend HTML and CSS into a single document, this practice has significant drawbacks and is usually discouraged. Among other reasons, separating CSS and HTML makes it easier for teams to collaborate on the same work.

So, if HTML and CSS are kept separate, how can we get them working together?

This question leads to one of the most important ideas behind CSS: The selector, so named because it’s the way we “select” the HTML we want to style.

To put it another way, CSS attaches to HTML by way of selectors.

There are several different selectors, but most fall into one of three groups.

  • Element selectors target specific kinds of HTML tags, for example, the <p> tag. If a page had dozens of <p> tags, all would be affected by the styles defined in a <p> element selector.
  • ID selectors target specific HTML tags that have the specified ID defined as an attribute. For example, given the tag <p id = "homepage">, an ID selector with the word “homepage” would target this particular tag. (In HTML, IDs must be unique within a document; no two tags can have the same ID.)
  • Class selectors target all the tags that have the given class. For example, a document might have one h1 tag with the class “main” (<h1 class = “main”></h1>) and one <p> tag with the class “main” (<p class = “main”></p>). In this case, a class selector referencing “main” would affect both these tags.

Bring structure to selectors

The different types of selectors use slightly different syntax. All use opening and closing braces to denote the beginning and ending of the selector’s rules — the specific style changes the selector applies. We won’t cover too much about CSS rules in this tutorial, but remember that rules always go inside selectors’ curly braces.

Here’s how the three kinds of selectors are formatted:

  • Element selectors use the tag name (without the angled brackets), followed by a space and opening and closing braces (in which specific rules would go). For example: p { }
  • ID selectors begin with a hashtag followed by the name of the selector and the braces: #homepage { }
  • Class selectors begin with a period, followed by the class name and the braces: .container { }

So, an element selector affects every instance of that element, an ID selector affects a single tag and a class selector affects every tag bearing that class.

Combine selectors for more control

Sometimes, it’s helpful to have more control over where CSS gets applied. This is especially true with highly complex HTML documents with many layers of content.

CSS provides several ways to combine selectors for more control.

p .container { }

An element followed by a class means “target every instance of the class when it appears inside the element.” This example means “target every tag with the ‘container’ class that’s inside a p tag.” If there’s a tag with the “container” class that’s not within a <p> tag, the selector won’t target it.

p.container { }

An element followed by a class with no space in between means “target every instance of the element that has the specified class.” In this case, it means to target every <p> tag with the “container” class.

p > .container { }

An element followed by a greater than sign and then a class means “target every instance of this class that’s a child of the element.” In this example, we’re targeting every instance of the container class that’s a child of the p tag. What’s the difference between being a child and appearing inside something? A child is a direct descendant — it appears  immediately under its parent. Something that “appears within an element” (the p .container { } syntax) can be several deep within the hierarchy. So, the > selector is more exclusive.

Resolve conflicting selector rules

Often, two or more selectors overlap. That is, they define rules that apply to the same objects in an HTML document. This leads to a pressing question: When two conflicting rules target the same object, which “wins”?

CSS resolves conflicts in two main ways. First, it gives precedence to proximity. Second, it gives precedence to specificity. Let’s take a look at what each of these mean and how they work.

Proximity

Selectors closer to the object we’re targeting within the structure of an HTML document take precedence when two rules conflict. Let’s look at a real-world example to see how this unfolds. Here’s a snippet of HTML from a recent story from the Wichita Eagle:

<div id="story_header">
<h1> <span>Crops arrive early for picking in Kansas</span> <span>Mild winter, warm spring bring fruits, veggies weeks ahead of time</span> </h1>  <ul id="story_meta">
<li>By <span>Sarah Tucker</span></li>
<li><span>The Wichita Eagle</span></li>
</ul>  <ul id="story_datetime"> <li>Published <abbr title="2012-06-22T12:17:55Z">Friday, June 22, 2012, at  7:17 a.m.</abbr></li>
<li>Updated <abbr title="2012-06-22T12:20:38Z">Friday, June 22, 2012, at  7:20 a.m.</abbr></li></ul>
</div>

As you can gather from the markup, this block of HTML defines the headline, subhead and byline information for a story. Let’s focus on a particular piece of content: the author. And let’s assume we want to apply some CSS that changes the color of the author’s name to red. (We can do this with the color: red; rule inside our selector.)

<span>Sarah Tucker</span>

Here’s where the author’s name appears. The closest tag in the structure — the one that’s most proximate — is the span tag which, in this case, happens to have a class called “fn.”

Scanning through the markup, though, we see this tag is nested within several others.

It’s in an <li> tag, within a <ul> tag, within a <div> tag.

Many of these tags have classes and lots of tags and classes mean lots of ways of targeting the content we want to change, in this case, “Sarah Tucker.” All of the following are valid ways to change the color:

div { }
ul { }
#story_meta { }
li { }
.byline { }
.byline span { }

There are two things to remember, though. First, if we’re more general in how we apply the rule, for example, by targeting the <div> tag, lots of additional elements will be affected by our change, in this case, the headline, subhead and so on. Of the selectors listed, only the last will target the author’s name alone.

Second, if we have two selectors and one is closer to the content we’re focused on, it will “beat” the more general selector. Given the following:

.byline { color: red }
.byline span { color: blue }

The author’s name will turn out blue, since the span element under the tag with “byline” (which happens to be an <li> tag in this case) is closer to the text.

Even if we swapped he order of the rules…

.byline span { color: blue }
.byline { color: red }

…The author’s name would still be blue. Proximity wins.

Specificity

Along with proximity, CSS uses specificity to resolve rule conflicts. These two ideas are closely related, so let’s take a closer look at what CSS specificity is all about.

Each type of selector has a different level of specificity:

  • IDs are the most specific
  • Classes are the next most specific
  • Elements are the least specific

Let’s take this example markup:

<p id = "story-510" class = "stories">The body of the story goes here.</p>

There are at least three ways we could target this content. From most to least specific, we could use the following:

#story-510 {
color: red;
}

.stories {
color: blue;
}

p {
color: green;
}

These three selectors have the same proximity to the content we’re looking to change, but they possess different levels of specificity. Since more specific elements get precedence, the text would turn out red.

What happens if we combine selectors?

p.stories { } is more specific than .stories (which is more specific than p), but #story-510 is still the most specific.

Combine proximity & specificity for greater control

Now things get interesting. Suppose we’re working with this markup:

<div class = "article">
<h2 class = "headline">Good web heads are short and specific</h2>
</div>

What if these two selectors go head to head:

.article { color: red; }
h2 { color: blue; }

In other words, what takes precedence — using a more specific selector (.article class over h2 element), or using a selector closer to the content we want to affect (one that’s more proximate)?

Proximity is more important than specificity. In this case, the h2 style beats the .article style, even though the .article style is more specific than the h2 style.

Rules “pass through”

It’s important to remember that CSS rules written at more specific levels only replace the same rules at more general levels. Let’s take a look at an example. Here’s how a typical ProPublica article is structured:

<div id="content">
<div>
<div>
<div>
<h1>Injection Wells: The Poison Beneath Us</h1>
The article body goes here...
</div>
</div>
</div>
</div>

Let’s suppose the class “wrapper” has a style that defines the font color, and the article-title class has a style that sets the font size. They might look like this:

.wrapper { color: #222; }
.article-title { font-size: 2em; }

(The value #222 is a dark gray.) Even though the article-title class is closer to the headline and at the same level of specificity as the .wrapper class, the color defined by wrapper will still take effect since there’s no color rule in the .article-title selector to overwrite it.

This is a handy way to inherit some values while overriding others, and it strikes to the heart of the “cascading” in cascading stylesheets.

How to pick the right selector

Let’s take a look at another real-world example. Here’s a typical headline structure for Voice of San Diego:

<h1 id="blox-asset-title">
<span>DeMaio Courts 'Downtown Insiders' He Once Ripped</span>
</h1>

Let’s say we wanted to change something about the headline style. Maybe we want to give it a light, dotted underline. Our rule might look something like this:

border-bottom: 2px dotted #ccc;

And we could apply it using no fewer than 12 different selectors:

span { }
.blox-headline {}
.entry-title {}
h1 {}
#blox-asset-title {}
#blox-asset-title span {}
#blox-asset-title .blox-headline {}
h1#blox-asset-title {}
span.blox-headline
span.entry-title {}
h1 .blox-headline {}
h1 .entry-title {}

The best choice all depends on how generally we want this style applied and how our HTML is structured from page to page. Remember, if we use the span selector, for example, our border style might apply to every span tag on our site. On the other hand, a  very narrow selector might be:

h1#blox-asset-title span.blox-headline {}

This means “apply the rules to span tags with the class ‘blox-headline’ inside h1 tags with the ID #blox-asset-title. That’s a pretty specific structural combination, and it almost certainly applies only to article headlines. However, depending on the site structure, the selector .article-title { } is a lot easier to read and may have the same effect.

Here are some final tips for working with selectors:

  • Get to know the site structure. Become familiar with how the HTML is structured and where those structures are repeated.
  • When in doubt, be as specific as possible. Use ID and class selectors and concatenate the selectors to further qualify them.
  • To apply the same style across different selectors, separate them with a comma but still use a single pair of braces. For example: h1, span { ... }
  • Sometimes, the best way to write CSS is to change how the HTML is structured. When that’s not possible, the great range of available selectors is essential to changing the parts of a page we want updated without affecting the rest.
  • If all else fails, you can use the !important modifier. Placing this at the end of the rule will make the selector that contains it beat any rival selectors, regardless of proximity and specificity. The !important modifier is a way to strong arm your rules. It’s best to not become overly dependent since it “breaks” how selectors naturally work, but, every once in a while, it can really get you out of a bind.

This piece is part of a Poynter Hacks/Hackers series featuring How To’s that focus on what journalists can learn from emerging trends in technology and new tech tools.

Support high-integrity, independent journalism that serves democracy. Make a gift to Poynter today. The Poynter Institute is a nonpartisan, nonprofit organization, and your gift helps us make good journalism better.
Donate
Casey Frechette is a visiting assistant professor in the journalism and media studies department at the University of South Florida St. Petersburg, a Web strategist…
Casey Frechette

More News

Back to News

Comments

Comments are closed.