The Power of the Plus Talk
June 12, 2012
To begin our journey this morning, I want to tell you a little bit about myself. I have worked on the Web for 13 years as both a designer and front-end developer. I am currently employed as a front-end developer at Bonnier Corporation.
As part of the digital team, I have the privilege of working with several iconic and award-winning brands like Parenting, Popular Science, Saveur, and Popular Photography.
My wife, Anne, and I live in Orlando with our three wonderful kids. One of the things we really enjoy doing as a family is attending Tampa Bay Rays’ games here in St. Pete. We built some really special memories at those games as we have had the privilege of playing catch on the field before the game, running the bases after the game on Family Fun Days, and following the Rays last season through one of the most exciting finishes in Major League history.
My eight-year-old son Ryan loves sports. There is not a day that goes by where he is not playing something, looking through his Sports Illustrated for Kids, or putting together all-star teams with his collection of baseball cards.
Ryan has enjoyed playing baseball for many years. But last summer, he became interested in basketball. We decided to sign him up for a week-long camp so he could get to know the game and see if he enjoyed it.
Through the week, Ryan learned how to dribble, shoot, play defense, and pass the ball to teammates. His favorite part of the day came at the end with they got to scrimmage against each other. He enjoyed getting to put his new skills to use.
That is one of the great things about a sport like basketball. The fundamentals of the game are pretty simple to pick up and Ryan was able to jump in and enjoy himself after just a little bit of training.
But just because these games are simple to learn and pick up, they take years of practice to perfect their skills and master the game. In the years ahead, Ryan will learn defensive strategies, improve his dribbling, and be able to make split second decisions about what to do with the ball when he has it on offense. He will become a better player and have a deeper appreciation of the game.
CSS is something you can learn in a day (or a couple of days) but it takes a lifetime to master. There are some core concepts that once you understand, you can put into practice and create some really amazing work. But there are always new things for us to learn that will make us better at our craft.
In our time together this morning, I want to share with you some practical and creative solutions using CSS selectors. I hope to inspire you by introducing you to some powerful allies who can help you make your work more awesome.
When I first started developing on the Web, I was a one-man team. The sites that I was working on were small and manageable. I was writing my own CSS and HTML so I had a lot of control over my markup. It was not hard for me to select the element I wanted by targeting a specific class in my HTML.
When I started working at Bonnier a year and a half ago, I joined a team of 3 other front-end developers. We work in an agile environment where each of us is part of 2-3 different scrum teams consisting of backend developers, project managers, and product owners. Our digital team primarily works in Drupal, with some sites in WordPress and one that has a custom-built CMS in Java.
It is a fast-paced and challenging environment where there is always work to do and new problems to solve. And though I felt very confident about my CSS skills coming in, I have grown exponentially in the last 20 months as I have met all the new challenges that Bonnier has brought.
NetTuts+ Article
It was a day last June when I was reading through my RSS feed and came across this article from NetTuts+, 30 CSS Selectors You Must Memorize. The article started out with many of the selectors that I already knew and used every day. But in the midst of these very familiar selectors, I was reintroduced to two gems that have become important parts of my toolbox. Let me introduce you to them.
First, there is the adjacent sibling combinator, (E + F). This selector will only select the element that precedes the former element [h2 + p].
The second selector that has become important in my arsenal is child combinator or child selector, (E > F). This selector will only select direct children of the former element. I found this selector very useful in when I have had nested lists or divs, like a site map.
Now these two selectors were not completely new to me. However there were several different reasons why they had not become an essential part of my toolbox.
- One was browser support. When I first learned about these selectors, they were not supported in IE6, which unfortunately still had a big browser share at the time. When I was reintroduced to them a year ago, they were supported in IE7 which was still our baseline at Bonnier.
- The second reason that I had not added them to my everyday toolbox was the control I had over my markup. I saw very little use for these selectors when I already had hooks to target the elements I wanted with CSS. The scale of sites I was working with at the time did not require me to be as creative as I was being pushed to be at Bonnier.
Styling an Ingredients list
Right after I read this article, I was given a problem to solve by the Web producer of Saveur magazine. They wanted to change some of the formatting on their recipe article pages to improve the user experience. The problem was that they had a lot of legacy content and it would be a slow process of updating that content with the changes. What they needed was a solution that allowed them to move forward while still respecting the legacy content.
Specifically, they wanted to add some headings to clearly label the section for the ingredients list and recipe instructions. The current formatting had a bold font weight on the individual ingredients in order to differentiate it from the instructions.
Now that they were going to add the headings, they no longer needed the ingredients list to be bolded. The markup was editorially controlled in a CMS and the editors did not want to have to edit the pages aside from adding the headings. I needed to find a solution that would reduce the font weight on the ingredient list on the pages where the new headings were put into place.
And then it came to me. I could use an adjacent sibling combinator (E + F) to create a conditional style that would only target bold tags where the headings were present. If the heading is not there, the bold tag would not be applied because the selector was dependent on the heading tag. Because the content was entered into the CMS in a couple of different ways, I had to write several different selectors to cover all the scenarios.
.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; }
As you can see, I used a combination of the adjacent sibling combinator and the child combinator to target the elements I needed to style differently. I also used another sibling combinator that the NetTuts+ article mentioned. This adjacent combinator will target any span as long as the follows the h4 tag.
Once You are Aware of Something
Have you ever heard it said that once you are aware of something, you start to see it everywhere? I remember that being true when my wife and I decided to buy our first car. A friend of ours was a Toyota Camry evangelist. And he was pretty convincing. After weighing the many different factors that were important to us, we were interested in purchasing a Camry. And the amazing thing was that I began to notice Camrys everywhere while I was driving. In the same way, I began to see applications of my newfound knowledge in my work at Bonnier.
Comment Box on Saveur
The next solution I want to show you is another case where I needed some conditional CSS. We were asked to implement a new comment box on Saveur.com. There were several different variations of it depending on a number of factors.
If there were no comments on an article, the client wanted to encourage readers to write a comment or review. For this case, there was a link that would take the reader to the bottom of the page to write a comment. That link was going to always be present in the code so I had to figure out a way to hide it when there was a comment count.
Recipe articles not only had comments but also allowed our audience to leave a review.
Different formatting would be required depending on what elements were present in the comment bubble.
I used a combination of adjacent sibling selector and child combinator (E > F) to target the different elements in the DOM I needed.
.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; }
Food Blog Awards Page
The last solution I want to show you was inspired by Chris Coyier. Each year, Saveur does a food blog award. This year’s design was going to be a variation of last year’s design, instead of a new design project.
One of the pages allows users to vote on their favorite food blog in a variety of categories. Last year, a radio button was selected to vote for the reader’s favorite blog in that category. This year, the designer wanted to improve the visual experience of the voting page by indicating a selection with a checkmark graphic instead of using the radio button like that we had the year before.
I had remembered that Chris had done a post on CSS Tricks on creative solutions with checkboxes. As I looked over the article, I realized I could do the same thing with a radio button. So the functionality of our page was not going to change but the visual experience would be much more rich.
This solution was dependent on the adjacent sibling combinator to work. It also used a CSS3 pseudo element of :checked and I used a polyfill to support IE7 and 8.
The DOM is built so that the radio button comes first. Then the image, title, and link to the specific food blog are contained by the label tag.
<div class="vote-on-item"> <input type="radio" name="formAnswers(6349)" value="La Tartine Gourmande: Spiced Pumpkin Pots de Cregrave;me with Sauteacute;ed Apples and Pistachios" /> <label for="1"> <img class="candidate-image" src="images/633-pratos-new.jpg" alt="" width="176" height="160" /> <div class="title"><span>Pratos e Travessas</span></div> <div class="flag"></div> </label> <div class="visit-blog"><a href="http://pratos-e-travessas.blogspot.com" target="_blank">Visit the blog »</a></div> </div>
The trick is to hide the radio button visually from the reader. This was done by absolutely positioning it and then setting the opacity to zero to hide it. I made the height and width of the radio button match the content so that the reader could select the item by clicking anywhere over the item.
.awards-2012 .vote-on-item input { height: 170px; left: 0; opacity: 0; filter: alpha(opacity = 0); position: absolute; top: 0; width: 186px; z-index: 2; }
When the radio button is checked, the styles are applied and we have a much more elegant solution than the year before.
.awards-2012 .vote-on-item input:checked + label, .awards-2012 .each-candidate.selected { border-color:#cc000b; } .awards-2012 .vote-on-item flag { display: none; } .awards-2012 .vote-on-item input:checked + label .flag, .awards-2012 .each-candidate.selected .flag { background: transparent url(images/food-blog-awards/check.png) no-repeat; display: block; height: 66px; left:7px; position: absolute; top:-5px; width: 46px; }
Performance
One final thing that I want to address is performance. One concern I had was how the adjacent sibling combinator and other CSS selectors would affect page performance.
In my research, I came across this listing from Steve Souders, who has authored many books on site performance. This listing shows the order of efficiency for CSS selectors.
- id (#myid)
- class (.myclass)
- tag (div, h1, p)
- adjacent sibling (h1 + p)
- child (ul > li)
- descendent (li a)
- universal (*)
- attribute (a[rel=”external”])
- pseudo-class and pseudo-element (a:hover, li:first)
As you can see, IDs and classes are the most efficient, and pseudo-classes and elements are the least efficient.
But what caught my eye was the fact that the adjacent sibling selector and child selector outperformed the descendent selector, which I use most frequently in my work. Learning this information has freed me up to continue to look for creative ways to use these selectors in my work.
Wrapup
I hope that my presentation today has inspired you to look for ways to use CSS selectors to help you solve the problems you encounter in your work. I have found them to be a very powerful tool to wield.
To get started on your journey, I would encourage you to start by reading the NetTuts+ article and familiarize yourself with the different selectors discussed. One of the things that I found helpful is that the article laid out browser support so I could make decisions on which ones I could incorporate into my work. After you read the article, look for opportunities to use your newfound knowledge.
I have posted the slides from my talk on Speaker Deck. You can also find links to anything I have mentioned today on my Website.
I would love to continue the conversation and hear about the creative solutions that you come up with. You can find me on Twitter @webcraftsman.
Thank you so much for your time. I hope that I have inspired you to go use CSS selectors in creative ways in your work.