Home >Web Front-end >CSS Tutorial >CSS Selectors: Combinators
CSS rules are matched to elements with selectors. There are a number of ways to do this, and you’re probably familiar with most of them. Element type, class name, ID, and attribute selectors are all well-supported CSS selectors and widely used.
The Selectors Level 3 and Level 4 specifications introduced several new selectors. In some cases, these are new variations of existing types. In other cases, they are new features of the language.
In this chapter, we’ll look at the current browser landscape for CSS selectors, with a focus on newer selectors. This includes new attribute selectors and combinators, and a range of new pseudo-classes. In the section Choosing Selectors Wisely, we look at the concept of specificity.
This chapter stops short of being a comprehensive look at all selectors―that could be a book unto itself. Instead, we’ll focus on selectors with good browser support that are likely to be useful in your current work. Some material may be old hat, but it’s included for context.
A comprehensive look at the current state of browser support for selectors can be found at CSS4-Selectors.
The following is an extract from our book, CSS Master, written by Tiffany B. Brown. Copies are sold in stores worldwide, or you can buy it in ebook form here.
Combinators are character sequences that express a relationship between the selectors on either side of it. Using a combinator creates what’s known as a complex selector. Complex selectors can, in some cases, be the most concise way to define styles.
You should be familiar with most of these combinators:
descendant combinator, or whitespace character
child combinator, or >
adjacent sibling combinator, or
general sibling combinator, or ~
Let’s illustrate each of these combinators. We’ll use them to add styles to the HTML form shown below.
This form was created using the following chunk of HTML:
<span><span><span><form</span> method<span>="GET"</span> action<span>="/processor"</span>></span> </span><span><span><span><h1</span>></span>Buy Tickets to the Web Developer Gala<span><span></h1</span>></span> </span><span><span><span><p</span>></span>Tickets are each. Dinner packages are an extra . All fields are required.<span><span></p</span>></span> </span><span><span><span><fieldset</span>></span> </span> <span><span><span><legend</span>></span>Tickets and Add-ons<span><span></legend</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="quantity"</span>></span>Number of Tickets<span><span></label</span>></span> </span> <span><span><span><span</span> class<span>="help"</span>></span>Limit 8<span><span></span</span>></span> </span> <span><span><span><input</span> type<span>="number"</span> value<span>="1"</span> name<span>="quantity"</span> id<span>="quantity"</span> step<span>="1"</span> min<span>="1"</span> max<span>="8"</span>></span> </span><span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="quantity"</span>></span>Dinner Packages<span><span></label</span>></span> </span> <span><span><span><span</span> class<span>="help"</span>></span>Serves 2<span><span></span</span>></span> </span> <span><span><span><input</span> type<span>="number"</span> value<span>="1"</span> name<span>="quantity"</span> id<span>="quantity"</span> step<span>="1"</span> min<span>="1"</span> max<span>="8"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span></fieldset</span>></span> </span><span><span><span><fieldset</span>></span> </span> <span><span><span><legend</span>></span>Payment<span><span></legend</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="ccn"</span>></span>Credit card number<span><span></label</span>></span> </span> <span><span><span><span</span> class<span>="help"</span>></span>No spaces or dashes, please.<span><span></span</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="ccn"</span> name<span>="ccn"</span> placeholder<span>="372000000000008"</span> maxlength<span>="16"</span> size<span>="16"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="expiration"</span>></span>Expiration date<span><span></label</span>></span> </span> <span><span><span><span</span> class<span>="help"</span>></span><span><span><abbr</span> title<span>="Two-digit month"</span>></span>MM<span><span></abbr</span>></span>/<span><span><abbr</span> title<span>="Four-digit Year"</span>></span>MM<span><span></abbr</span>></span>YYYY<span><span></span</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="expiration"</span> name<span>="expiration"</span> placeholder<span>="01/2018"</span> maxlength<span>="7"</span> size<span>="7"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span></fieldset</span>></span> </span><span><span><span><fieldset</span>></span> </span> <span><span><span><legend</span>></span>Billing Address<span><span></legend</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="name"</span>></span>Name<span><span></label</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="name"</span> name<span>="name"</span> placeholder<span>="ex: John Q. Public"</span> size<span>="40"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="street_address"</span>></span>Street Address<span><span></label</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="name"</span> name<span>="name"</span> placeholder<span>="ex: 12345 Main Street, Apt 23"</span> size<span>="40"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="city"</span>></span>City<span><span></label</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="city"</span> name<span>="city"</span> placeholder<span>="ex: Anytown"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="state"</span>></span>State<span><span></label</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="state"</span> name<span>="state"</span> placeholder<span>="CA"</span> maxlength<span>="2"</span> pattern<span>="[A-W]{2}"</span> size<span>="2"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="zip"</span>></span>ZIP<span><span></label</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="zip"</span> name<span>="zip"</span> placeholder<span>="12345"</span> maxlength<span>="5"</span> pattern<span>="0-9{5}"</span> size<span>="5"</span>></span> </span> <span><span><span></p</span>></span> </span><span><span><span></fieldset</span>></span> </span> <span><span><span><button</span> type<span>="submit"</span>></span>Buy Tickets!<span><span></button</span>></span> </span><span><span><span></form</span>></span></span>
You’re probably quite familiar with the descendant combinator. It’s been around since the early days of CSS (though it was without a type name until CSS2.1). It’s widely used and widely supported.
The descendant combinator is just a whitespace character. It separates the parent selector from its descendant, following the pattern A B, where B is an element contained by A. Let’s add some CSS to our markup from above and see how this works:
<span>form h1 { </span><span>color: #009; </span><span>}</span>
We’ve just changed the color of our form title, the result of which can be seen below.
Let’s add some more CSS, this time to increase the size of our pricing message (“Tickets are $10 each”):
<span>form p { </span><span>font-size: 22px; </span><span>}</span>
There’s a problem with this selector, however, as you can see below. We’ve actually increased the size of the text in all of our form’s paragraphs, which isn’t what we want. How can we fix this? Let’s try the child combinator.
In contrast to the descendant combinator, the child combinator (>) selects only the immediate children of an element. It follows the pattern A > B, matching any element B where A is the immediate ancestor.
If elements were people, to use an analogy, the child combinator would match the child of the mother element. But the descendant combinator would also match her grandchildren, and great-grandchildren. Let’s modify our previous selector to use the child combinator:
<span>form <span>> p</span> { </span><span>font-size: 22px; </span><span>}</span>
Now only the direct children of article are affected, as shown below.
With the adjacent sibling combinator ( ), we can select elements that follow each other and have the same parent. It follows the pattern A B. Styles will be applied to B elements that are immediately preceded by A elements.
Let’s go back to our example. Notice that our labels and inputs sit next to each other. That means we can use the adjacent sibling combinator to make them sit on separate lines:
<span><span><span><form</span> method<span>="GET"</span> action<span>="/processor"</span>></span> </span><span><span><span><h1</span>></span>Buy Tickets to the Web Developer Gala<span><span></h1</span>></span> </span><span><span><span><p</span>></span>Tickets are each. Dinner packages are an extra . All fields are required.<span><span></p</span>></span> </span><span><span><span><fieldset</span>></span> </span> <span><span><span><legend</span>></span>Tickets and Add-ons<span><span></legend</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="quantity"</span>></span>Number of Tickets<span><span></label</span>></span> </span> <span><span><span><span</span> class<span>="help"</span>></span>Limit 8<span><span></span</span>></span> </span> <span><span><span><input</span> type<span>="number"</span> value<span>="1"</span> name<span>="quantity"</span> id<span>="quantity"</span> step<span>="1"</span> min<span>="1"</span> max<span>="8"</span>></span> </span><span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="quantity"</span>></span>Dinner Packages<span><span></label</span>></span> </span> <span><span><span><span</span> class<span>="help"</span>></span>Serves 2<span><span></span</span>></span> </span> <span><span><span><input</span> type<span>="number"</span> value<span>="1"</span> name<span>="quantity"</span> id<span>="quantity"</span> step<span>="1"</span> min<span>="1"</span> max<span>="8"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span></fieldset</span>></span> </span><span><span><span><fieldset</span>></span> </span> <span><span><span><legend</span>></span>Payment<span><span></legend</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="ccn"</span>></span>Credit card number<span><span></label</span>></span> </span> <span><span><span><span</span> class<span>="help"</span>></span>No spaces or dashes, please.<span><span></span</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="ccn"</span> name<span>="ccn"</span> placeholder<span>="372000000000008"</span> maxlength<span>="16"</span> size<span>="16"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="expiration"</span>></span>Expiration date<span><span></label</span>></span> </span> <span><span><span><span</span> class<span>="help"</span>></span><span><span><abbr</span> title<span>="Two-digit month"</span>></span>MM<span><span></abbr</span>></span>/<span><span><abbr</span> title<span>="Four-digit Year"</span>></span>MM<span><span></abbr</span>></span>YYYY<span><span></span</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="expiration"</span> name<span>="expiration"</span> placeholder<span>="01/2018"</span> maxlength<span>="7"</span> size<span>="7"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span></fieldset</span>></span> </span><span><span><span><fieldset</span>></span> </span> <span><span><span><legend</span>></span>Billing Address<span><span></legend</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="name"</span>></span>Name<span><span></label</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="name"</span> name<span>="name"</span> placeholder<span>="ex: John Q. Public"</span> size<span>="40"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="street_address"</span>></span>Street Address<span><span></label</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="name"</span> name<span>="name"</span> placeholder<span>="ex: 12345 Main Street, Apt 23"</span> size<span>="40"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="city"</span>></span>City<span><span></label</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="city"</span> name<span>="city"</span> placeholder<span>="ex: Anytown"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="state"</span>></span>State<span><span></label</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="state"</span> name<span>="state"</span> placeholder<span>="CA"</span> maxlength<span>="2"</span> pattern<span>="[A-W]{2}"</span> size<span>="2"</span>></span> </span> <span><span><span></p</span>></span> </span> <span><span><span><p</span>></span> </span> <span><span><span><label</span> for<span>="zip"</span>></span>ZIP<span><span></label</span>></span> </span> <span><span><span><input</span> type<span>="text"</span> id<span>="zip"</span> name<span>="zip"</span> placeholder<span>="12345"</span> maxlength<span>="5"</span> pattern<span>="0-9{5}"</span> size<span>="5"</span>></span> </span> <span><span><span></p</span>></span> </span><span><span><span></fieldset</span>></span> </span> <span><span><span><button</span> type<span>="submit"</span>></span>Buy Tickets!<span><span></button</span>></span> </span><span><span><span></form</span>></span></span>
You can see the results below.
Let’s look at another example that combines the universal selector (*) with a type selector:
<span>form h1 { </span><span>color: #009; </span><span>}</span>
This example adds a 5em margin to the top and bottom of every fieldset element, shown below. Since we’re using the universal selector, there’s no need to worry about whether the previous element is another fieldset or p element.
Heydon Pickering explores more clever uses of the adjacent sibling selector in his article “Axiomatic CSS and Lobotomized Owls.”
What if we want to style a sibling element that isn’t adjacent to another, as with our Number of Tickets field? In this case, we can use the general sibling combinator.
With the general sibling combinator―a tilde―we can select elements that share the same parent without considering whether they’re adjacent. Given the pattern A ~ B, this selector matches all B elements that are preceded by an A element, whether or not they’re adjacent.
Let’s look at the Number of Tickets field again. Its markup looks like this:
<span>form p { </span><span>font-size: 22px; </span><span>}</span>
Our input element follows the label element, but there is a span element in between. Since a span element sits between input and label, the adjacent sibling combinator will fail to work here. Let’s change our adjacent sibling combinator to a general sibling combinator:
<span>form <span>> p</span> { </span><span>font-size: 22px; </span><span>}</span>
Now all of our input elements sit on a separate line from their label elements, as seen below.
Using the general sibling combinator is the most handy when you lack full control over the markup. Otherwise, you’d be better off adjusting your markup to add a class name. Keep in mind that the general sibling combinator may create some unintended side effects in a large code base, so use with care.
CSS combinators are used to explain the relationship between two or more CSS selectors. There are four types of combinators in CSS: descendant combinator (space), child combinator (greater than symbol >), adjacent sibling combinator (plus symbol ), and general sibling combinator (tilde symbol ~). The descendant combinator selects all elements that are descendants of a specified element. The child combinator selects all elements that are direct children of a specified element. The adjacent sibling combinator selects all elements that are the next siblings of a specified element. The general sibling combinator selects all elements that are siblings of a specified element.
The child combinator in CSS is represented by the “>” symbol. It is used to select elements that are direct children of a specific element. For example, if you want to select all
elements that are direct children of a
element, you would write it as “div > p”. This will apply the CSS styles only to theelements that are direct children of the
element, not to those that are nested deeper.The main difference between a child combinator and a descendant combinator lies in their specificity. A child combinator (>) selects only the direct children of a specific element, while a descendant combinator (space) selects all descendants (children, grandchildren, etc.) of a specific element. For example, “div > p” selects only the
elements that are direct children of a
element, while “div p” selects allelements within the
element, regardless of how deeply they are nested.The adjacent sibling combinator in CSS is represented by the “ ” symbol. It is used to select an element that is directly after another specific element, and both elements share the same parent. For example, if you want to select a
element that directly follows a
element, you would write it as “div p”. This will apply the CSS styles only to theelement that directly follows the
element.Yes, you can combine multiple CSS combinators in a single rule to create more specific and complex selectors. For example, you can combine the child combinator and the adjacent sibling combinator to select an element that is both a direct child and an adjacent sibling of specific elements. The rule “div > p p” will select a
element that is a direct child of a
element and is also directly following anotherelement.
The general sibling combinator in CSS is represented by the “~” symbol. It is used to select elements that are siblings of a specific element. Unlike the adjacent sibling combinator, the general sibling combinator selects all elements that are siblings of a specific element, not just the one that directly follows it. For example, “div ~ p” will select all
elements that are siblings of a
element.CSS combinators can be very useful for styling nested elements. For example, you can use the descendant combinator to style all
elements within a
element by writing “div p”. You can also use the child combinator to style only the direct children of a element by writing “div > p”. By combining different combinators, you can create very specific selectors that target exactly the elements you want to style.Yes, you can use CSS combinators with pseudo-classes. For example, you can use the child combinator with the :first-child pseudo-class to select the first child of a specific element. The rule “div > p:first-child” will select the first
element that is a direct child of a
element.CSS combinators themselves do not have any specificity. However, they help to determine the specificity of a selector by defining the relationship between elements. The specificity of a selector is calculated based on the number of ID selectors, class selectors, and type selectors it contains. A selector with more specific selectors will override a selector with less specific selectors.
Yes, you can use CSS combinators with attribute selectors. For example, you can use the child combinator with an attribute selector to select elements that have a specific attribute and are direct children of a specific element. The rule “div > p[title]” will select all
elements that have a title attribute and are direct children of a
element.The above is the detailed content of CSS Selectors: Combinators. For more information, please follow other related articles on the PHP Chinese website!