Power of the Plus :: Adjacent Sibling Combinators and other CSS selectors

November 11, 2011

For most of my Web practice, I wrote my own HTML and could add classes and IDs to elements as hooks to target elements in my CSS. So when I first heard about CSS combinators, I did not see much use for them. I wondered why I would need them. Why would I need something general when I could specify an element by class or ID?

Fast forward to this year. After several career changes, I am now working with CMS frameworks that do not give me the control over the code that I had in the past. At times, it can be a challenge to find hooks to target specific elements with CSS.

Last Spring, I was reintroduced to CSS combinators. These powerful little statements are now part of my daily workflow.

Sidenote: I read this article around the time that I started using combinators. I found it to be a great resource because it had a handy reference to browser support.

Conditional CSS?

One of the powerful ways that I have started using combinators is to create “conditional CSS.” I had a project where the business unit wanted to add headings to their body content for recipes. They wanted to add “Ingredients” and “Instruction” headings to make the content more clear. At that time, all the ingredients in the ingredient listing were bold. Now that they were adding the headings, they wanted those list items to be of normal weight.

The challenge. The headings were going to be added to new articles and then slowly added to existing articles on the site. Could I come up with a solution that would only be implemented on articles with the new headings?

Thus the a need for “conditional CSS.” I found my solutions by using the adjacent sibling combinator (E +F) and the child combinator (E > F) to target the elements in the ingredients listings and change the font weight to normal.

.recipe-page .body h4 + p > b {
font-weight: normal;
}
.recipe-page .body h4 + div b {
font-weight: normal;
}
.recipe-page .body h4 ~ span {
font-weight: normal !important;
}

I had to come up with several declarations because different editors had entered in the content differently.

Another Example

Another project where I needed some conditional CSS was showing the comment count for an article.

The challenge was to write CSS to cover several different conditions. Some comments would just show a comment count. Another listing would include a rating or there might be ratings without a comment count.

The business unit also wanted to have a link to the comment area for articles that did not have a comment or review. The developer needed to have that link always be present in the code so I had to come up with a solution to hide the link when there was a comment count and/or rating present. When there was not a comment, there would not be any code for the comment count. So showing the link when there was not a comment was easy.

Here is my solution to hiding the comment link:

The Comment Block on the page

The HTML

The CSS

So I want to hide the div with a class of “rating-buttons” because users have already commented on this article.

.recipe-rating-comments-count .rating + .rating-buttons >
.write-comment, .recipe-rating-comments-count .comment-counts-text + .rating + .rating-buttons >.rate-review,
.recipe-rating-comments-count .comment-counts-text + .rating-buttons > .rate-review,
.recipe-rating-comments-count .comment-counts-text + .rating-buttons > .write-comment {
display: none;
}

Using a combination of adjacent selectors and child combinator, I can target the different conditions in which I want to hide the “Write a Comment” link.

I also used a couple of combinations of adjacent sibling combinator and child combinator to add different margins depending on what elements were present. For example, I wanted the ratings to have more margin at the top when a comment count was not present.

In Closing

I spend the majority of my time working in Drupal. Both of my examples are not from a Drupal environment but I could share more. One of the ones I use most often is Panel Separators. I can use the adjacent sibling combinator to target the class of the pane that precedes the panel-separator to target it for styling.

Just like a lot of things in life, once you are aware of something, you begin to see it everywhere. Or is this case, I keep seeing problems that these combinators provide a great solution for.

Special thanks to Chris Coyier, who encouraged me to blog about this when I shared the idea with him at Front End Design Conference.

Comments are closed.