Styling websites can get a little mundane if the site you are working on is not so aesthetically pleasing or challenging. If I find myself just going through the motions, I tend to step back and try to improve my skills. Doing this not only increases motivation for the project, it also puts are few more tricks up my sleeve for future projects.
Below are 10 CSS selectors. Some of them you probably use on every project and some possibly never. Next time you’re finding yourself going through the motions, maybe it’s a good time to sneak in some new selectors that you wouldn’t normally use.
E + F
h2 + p {
margin-top: 10px;
}
The adjacent sibling combinator. It will select the element that is immediately preceded by the former element. In the example above, only the first paragraph will have a top margin of 10px.
A little more specific:
h2.article + p { margin-top: 0;}
Similar to the previous example, except that it adds a class selector. This rule will only triggers when H2
has class="article"
.
E > F
nav > ul {
border: 1px solid black;
}
Child selectors. A child selector matches when an element is the child of some element. A child selector is made up of two or more selectors separated by >
.
The above example will only target the uls
which are direct children of the nav
element. It will not target the ul
that is a child of the first li
.
<nav>
<ul>
<li>List Item</li>
<li>List Item</li>
<li>List Item
<ul> <!-- this ul will not be targeted -->
<li>Child</li>
</ul>
</li>
<li>List Item</li>
</ul>
</nav>
A little more specific:
nav ul > li a { color: red;}
Descendant selectors and child selectors. The above example matches an a
element that is a descendant of a li
. The li
element must be the child of a ul
. The ul
element must be a descendant of a nav
element.
E ~ F
h1 ~ p {
color: red;
}
General sibling combinator. The general sibling combinator is made of the “tilde” ~
. The sibling combinator is quite similar to the adjacent sibling combinator (not as strict). The difference is that the element doesn’t need to immediately follow the first element, but can be anywhere after it.
With the above example, it will select any p
elements as long as it follows a h1
.
E:before
& E:after
The before and after pseudo elements are super handy. If you have a keen eye, you might have noticed that the comment bubbles on this site are constructed with just CSS thanks to these handy selectors.
The :before
and :after
pseudo-elements can be used to describe generated content before or after an element’s content.
<div class="boom_box">
<p>css arrow boom!</p>
</div>
.boom_box {
position: relative;
background: #88b7d5;
border: 4px solid #c2e1f5;
}
.boom_box:after, .boom_box:before {
bottom: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.boom_box:after {
border-bottom-color: #88b7d5;
border-width: 30px;
left: 50%;
margin-left: -30px;
}
.boom_box:before {
border-bottom-color: #c2e1f5;
border-width: 36px;
left: 50%;
margin-left: -36px;
}
css arrow boom!
E:link
& E:active
& E:hover
& E:focus
div:hover {
background: #e3e3e3;
}
The dynamic pseudo-classes. These are also super handy and if you are not using them to give your users feedback on their actions, I would highly recommend using these in your next project (or add them to your existing sites) to give it a little more perzaz.
The :link
pseudo-class is used to select unvisited links.
The :hover
pseudo-class applies while the user hovers over an element, but does not activate it. For example, when the cursor hovers over a link, the colour changes.
The :active
pseudo-class applies while an element is being activated by the user. For example, between the times the user presses the mouse button and releases it.
The :focus
pseudo-class applies while an element has the focus (accepts keyboard events or other forms of text input).
You might have seen these basic rules declared in a reset stylesheet like so:
a:link { color: blue } /* unvisited links */
a:visited { color: black } /* visited links */
a:hover { color: red } /* user hovers */
a:active { color: orange } /* active links */
Note that the a:hover
must be placed after the a:link
and a:visited
rules, otherwise the cascading rules will override the a:hover
rule. Same goes with the a:active
being placed after a:hover
. The active state will apply when the user both activates and hovers over the element.
The above example is pretty boring. If you think outside the box you can do some pretty rad stuff like transform: rotate(70deg);
, transform: scale(0.5);
or transition: all 0.3s ease-out;
.
E:nth-child(n)
li:nth-child(6) {
color: bold;
}
The :nth-child()
pseudo-class accepts an integer as a parameter and is not zero-based (not like arrays). If you wish to target the sixth list item, use li:nth-child(6)
.
This selector can even be used to select a variable set of children. For example, you could do tr:nth-child(2n+1)
to select every odd row of a HTML table.
You can get pretty crafty with these guys and it is worth reading up on the spec if you are into that kind of jazz.
E:nth-last-child(n)
li:nth-last-child(4) {
color: green;
}
The :nth-last-child()
pseudo-class is a great selector to be aware of. Can’t say I have used it many times to be honest, but when I have, it saved the day. Say you have a huge content heavy site with the biggest list in the world and you have to target the 4th last item. Hello :nth-last-child(4)
. You could do this with :nth-child(4598792)
but it is a little less likely to be bulletproof, especially if the client adds a few menu items to the top of the list.
E:nth-of-type(n)
.article p:nth-of-type(4) {
color: red;
}
The :nth-of-type()
pseudo-class gives you the ability to target the type of element rather than the child.
For example, if you have lots of paragraphs within an article on your site and want to target the 4th one and you don’t have a hook (ID or Class) to target, you can use :nth-of-type(4)
.
E:first-child
& E:last-child
ul li:first-child {
border-left: none;
}
ul li:last-child {
border-right: none;
}
This :first-child
and last-child
structural pseudo classes allow you to target only the first child or last child of the element’s parent. These two selectors are quite handy when dealing with list styling, menus in particular.
The :first-child
pseudo-class represents an element that is the first child of some other element. The :last-child
pseudo-class represents an element that is the last child of some other element.
X[title]
h2[title] {
color: red;
}
Attribute selectors. You can go pretty crazy with these guys if you desire (or need too). They allow you to specify rules that match elements which have certain attributes defined in the source. For example, the above selector matches all H2
elements that specify the "title"
attribute, whatever its value.
This is only the tip of the iceberg into what attribute selectors can do.
The End
I hope I have given you a little incentive to make that next boring project a little more fun.
One word of warning is that some of the above selectors won’t work in older browsers, and by no means is the above list the best of the best, or the ones you should learn. It was just a few off the top of my head.
Do you have any favourite selectors that you would recommend?
Nice post Jake! Glad to see the WDW blog up and running.
I use a lot of pseudo classes and attribute selectors (especially nth-child), they’re a great time saver, but it’s worth mentioning you’ll need to rock Selectivizr (http://selectivizr.com/), or another polyfill, in your builds to make sure they work in IE π
By the way, love the real time comment previews!
>, +, [attr], :first-child all work in IE7 and up.
Indeed they do π I believe :last-child :nth-child, :nth-of-type, etc (anything in the css3 spec?) will need a polyfill to work below IE9.
Selectivizr doesn’t add support for :before and :after though right?
Apparently not, I actually thought it did!
Very nice.
Just one note, ::before and ::after are pseudo-elements, not classes.
Fixed. Thanks!
Thanks for a nice post. What exactly is the difference between E ~ F and E F though? Seems to me that both would apply to F elements that follow E.
Hey Rima,
The difference between the descendant selector and the general sibling selector is:
E F
is a Descendant SelectorE ~ F
is a General Sibling SelectorThe descendant selector matches all elements that are descendants of a specified element.
The general sibling selector matches elements that are siblings. The elements donβt have to be adjacent siblings, but they have to have the same parent.
So if you think about the HTML below:
The
h1
,span
andh3
, are all siblings.The
spans
within theh1
, andh3
, and descendants of their parent tagsYou can also see a coded example – http://dabblet.com/gist/2850099
Hope that helps.
You bet – very clear now! Thanks π
Great page, well done, except you need one very important element in this page.
What is needed is a….. “Print.css”!
The black display boxes do not show well on any print preview. On the Chrome browser, many of the elements are scrambled together and all of your left column link list overlaps the content.
A print.css would greatly assist anyone, as myself, who wants to print the page to read and review (and use) offline.
Thanks for pointing that out Mark!
As soon as I have time I will make sure this is fixed.
I have logged the issue on the WDW GitHub repository. If you have anything else you would like to see fixed please don’t hesitate to comment.
Cheers,
Jake