[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More


The Less-Common CSS Selectors

Published on
8,190 Points
4 Endorsements
Last Modified:
When applying CSS to your HTML, there are many different ways to select which element(s) the CSS applies to.  Some of these selectors are more commonly known and used than others - Here are the more common ones:
#X - Matches an ID of X
.X - Matches a class of X
X Y - Matches an element Y that is a descendant of X.  (children, grand-children, etc)
X > Y - Matches an element Y that is a direct child of X
Those cover most of the cases where you need to apply styles to your elements, but there are often rules you need to create which need more finely-tuned selection.  

Some of the less frequently used (but still handy) selectors are:
X + Y - Matches any element Y directly AFTER (not inside) an X
X ~ Y - Matches any element Y which is after an X, where both share a common parent.  (think of it as a younger brother rule)
[attribute=value] - Any element with an attribute = "value"
[attribute*=value] - Any element with an attribute containing "value"
[attribute^=value] - Any element with an attribute beginning with "value"
[attribute$=value] - Any element with an attribute ending with "value"

Selector X+Y (adjacent siblings)

Let's say you set the top and bottom margins of every <P> to be 20px each.  That's probably fine in most cases within your site, but what if you have the following?
     h2 {margin-top: 20px; margin-bottom: 20px;}

<h2>This header has 20px above and below</h2>
<h2>This header has 20px above and below</h2>

Open in new window

Because the bottom of header 1 has 20px and the top of header 2 has 20px, you'll see 40px between the 2 headers.  Probably not what you wanted... To solve this, you need a rule that says "Put 20px on top and bottom of each H2, unless that H2 is below another H2.  In that case, remove the top 20px and leave 20px below it."  It sounds impossible, right?  Style sheets can't be aware of what other content is on the page!  I recently had that discussion with a visual designer on a project I was doing, and insisted the CSS couldn't support that request.  A week later, I found adjacent siblings in CSS and agreed that it could indeed be done as he asked.

The format for that is "X + Y" which says that any Y immediately after (not inside) an X gets this style.  So that would work for the example above by saying:
     h2 {margin-top: 20px; margin-bottom: 20px;}
     h2 + h2 {margin-top: 0 margin-bottom: 20px;

<h2>This header has 20px above and below</h2>
<h2>This header has 20px below</h2>

Open in new window

It's true that in a case as simple as this you might be able to get away with simply having space ABOVE all of your H2 tags if everything else is styled appropriately... but the real world is very rarely as neat and tidy as this.  The adjacent sibling selector is most often used  when you encounter an exception to the normal rules.  Its much easier to add a "what if" rule than have to redesign all of your other elements to handle that one odd case in your content.

Selector X ~ Y (general siblings)

I like to think of this as the younger brother rule... it will select any Y that shares a parent with X, and comes after X.  This one is only available in browsers that support CSS3, so it will not work in older browsers.  Because of its very specific rule, there may be limited uses for this selector - but it's a good one to keep up your sleeve and pull out when you need it!

In the example below, consider the possibility that you need to target any SPAN inside a .parentDiv that comes after an IMG.  By using .img ~ span you'll select the span "Style this one" but not the first one.
<div class="parentDiv">
     <span> Don't want to style this one</span>
     <img class="olderBrother">
     <img class="middleBrother">
     <div>Element with no class or ID</div>
     <span>Style this one</span>

Open in new window


Most of the other selectors will target an element or set of elements (A, DIV, IMG and so on) but with the attribute selectors you can target a subset of those elements based on their attributes.  A perfect example of this is styling links based on their target window, protocol or file extension.

Many sites have a small symbol next to any link that will open in a new window.  Of course when you're coding these links you could add a class to the <A> tag and have that class display a background, padding and such.  That would work, but requires extra coding and needs to be done manually on every link.  (It also rules out any dynamically created links, unless the code that generates it also adds the class.)  To simplify your code and make it work no matter how the link is generated, add a CSS attribute selector.
a[target='_blank'] {
	padding-right: .9em;
	background-image: url(images/extlink.png);
	background-repeat: no-repeat;
	background-position: right center;
	background-size: 0.75em;

a[target='_blank']:hover {
	background-image: url(images/extlink_light.png);

Open in new window

The above CSS will apply to any A tag where the target is equal to "_blank" (meaning a new window will open.)  Notice that you can also create a selector for when you hover over an A with a target of "_blank" by adding the :hover just like you would a normal A:hover selector.

If your links won't necessarily have a target attribute set, and you want to set a style for any link beginning with "http://" (which in most cases would mean that the link is going to a different web site) you can change the = to be ^=.  This checks for a value BEGINNING with what you specify, rather than looking for an exact and complete match.  The example below will turn all links to secure (HTTPS) sites red.
a[href^='https://'] {
	color: #f00;

Open in new window

Another common feature you can apply to your links is appending an icon to let the user know if they'll be downloading a .PDF file, a .DOC file, etc.  Also easy!  By replacing the = with $= you tell CSS to apply styles to any link ENDING in the value specified.  In this case, if the filename ends in ".pdf", add some space and a PDF icon.
a[href$='.pdf'] {
	padding-right: .9em;
	background-image: url(images/pdf-icon.png);
	background-repeat: no-repeat;
	background-position: right center;
	background-size: 0.75em;

Open in new window

The examples given above might lead you to think the attribute selector only works on A tags... this is not the case.  Any tag with attributes can be selected in this manner... for instance an IMG with the ALT text of "Login" would be


Open in new window

Or if you wanted to style any IMG with the word "important" anywhere within the ALT text, you can use another variation of the attribute selector.  Replace the = with *= and it will match if the value is contained at least once in the attribute.  (Meaning that if your ALT text is "important and super important" it will still be matched by img[alt*='important'].


LVL 38

Expert Comment

No problem leaving it around, so long as you plan to keep working on it :)

And I fixed the other comment for you.

Author Comment

Coincidentally, the morning after this article was published I was looking for a way to clean up the content of some RSS feeds coming into my personal website.  The content contains a lot of blank spaces, caused by back-to-back <br> tags.  

Since I'm using jQuery on my site, the removal part was easy with the .remove() function, so all I needed to do is figure out the best way to select multiple BR tags.  I tried the adjacent sibling selector from my recent article, and it worked perfectly!

$('br + br').remove();

Open in new window


Featured Post

Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

Join & Write a Comment

In this tutorial viewers will learn how add a full-size background image to a webpage using CSS3. Create a new HTML document with an internal stylesheet.: In CSS, define the html element to have a background image. Use a high resolution image.: In t…
The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…
Next Article:

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month