Combined Selectors

Selectors can be more complex than just by class, tag, or identifier. We list all available combined selectors.

Time to read: less than 5 min

Briefly

Sometimes when writing styles we want to refer to a selector more precisely than just by class name or tag. For this, we can use various combinations.

Grouping: .element1, .element2

Example

If several selectors need to have the same rule, you can write it out long:

        
          
          h1 {  font-weight: bold;}h2 {  font-weight: bold;}h3 {  font-weight: bold;}
          h1 {
  font-weight: bold;
}

h2 {
  font-weight: bold;
}

h3 {
  font-weight: bold;
}

        
        
          
        
      

Or you can list all selectors separated by commas and write just one CSS rule:

        
          
          h1, h2, h3 {  font-weight: bold;}
          h1, h2, h3 {
  font-weight: bold;
}

        
        
          
        
      

How to Write

Selectors are simply written in any order separated by commas:

        
          
          .selector1,code,#id,[attr="value"] {  color: red;}
          .selector1,
code,
#id,
[attr="value"] {
  color: red;
}

        
        
          
        
      

If you list selectors separated by commas, the rules will apply to each group:

        
          
          .heading span,.block,.wrapper {  color: red;}
          .heading span,
.block,
.wrapper {
  color: red;
}

        
        
          
        
      

How to Understand

In the example, the property will apply to three types of selectors:

  1. For all <span> inside the class .heading (at any depth);
  2. for all elements with the class .block;
  3. for all elements with the class .wrapper.

Combination: .class1.class2

Example

        
          
          .selector.selector_modificator {  color: red;}
          .selector.selector_modificator {
  color: red;
}

        
        
          
        
      

How to Write

This technique is applicable only for classes and attributes, because only they can have more than one. Selectors are written together. Styles will be applied only to the element that contains all listed selectors.

How to Understand

This "gluing" combines selectors into one rule.

Descendants: .element1 .element2

Example

        
          
          article h3 {  color: red;}
          article h3 {
  color: red;
}

        
        
          
        
      

How to Write

Selectors are written sequentially separated by a space.

How to Understand

The sequence of selectors reflects the nesting — each subsequent selector must necessarily be at some level of nesting in the previous selector.

Directly Nested: .element1 > .element2

Example

        
          
          article > h3 {  color: red}
          article > h3 {
  color: red
}

        
        
          
        
      

How to Write

Selectors are separated by the > sign.

How to Understand

The sequence of selectors reflects direct nesting — the selector to the right of the operator must be a direct descendant of the selector from the left side:

        
          
          article > h3 {  color: red;}
          article > h3 {
  color: red;
}

        
        
          
        
      

Styles for h3.article__heading will not apply to article > h3, since the direct descendant of <article> is div.article__header, not <h3>:

        
          
          <article class="article">  <div class="article__header">    <h3 class="article__heading">Title</h3>  </div></article>
          <article class="article">
  <div class="article__header">
    <h3 class="article__heading">Title</h3>
  </div>
</article>

        
        
          
        
      

In this example, styles will apply to the heading because <h3> is a direct descendant of <article>:

        
          
          <article class="article">  <h3 class="article__heading">Title</h3></article>
          <article class="article">
  <h3 class="article__heading">Title</h3>
</article>

        
        
          
        
      

And here, everything is fine — <h3> is still a direct descendant of <article> because it is located at the nearest nesting level, even though it follows div.article__header:

        
          
          <article class="article">  <div class="article__header">…</div>  <h3 class="article__heading">Title</h3></article>
          <article class="article">
  <div class="article__header"></div>
  <h3 class="article__heading">Title</h3>
</article>

        
        
          
        
      

Tips

💡 This combination is handy to select an element based on its exact location in the document structure.

Adjacent: .element1 + .element2

Example

        
          
          label + input {  color: red;}
          label + input {
  color: red;
}

        
        
          
        
      

How to Write

Selectors are combined with the + sign.

How to Understand

The element to the right of + must follow immediately in HTML after the element to the left of +. In simpler terms, the right element must be a sibling of the left element for the adjacent selector to work.

The code from the example will apply only to such an <input> that comes immediately after <label>:

        
          
          label + input {  color: red;}
          label + input {
  color: red;
}

        
        
          
        
      

This will not apply because there is a <p> before <input>:

        
          
          <label></label><p>…</p><input>
          <label></label>
<p></p>
<input>

        
        
          
        
      

With this markup, the style will apply only to the first <input>, but not to the second:

        
          
          <label>Label</label><input><input>
          <label>Label</label>
<input>
<input>

        
        
          
        
      

And the rule will not work here. <label> and <input> are at different levels of nesting:

        
          
          <label>Label</label><div>  <input></div>
          <label>Label</label>
<div>
  <input>
</div>

        
        
          
        
      

Subsequent: .element1 ~ .element2

Example

        
          
          .star:hover ~ .star {  color: red;}
          .star:hover ~ .star {
  color: red;
}

        
        
          
        
      

How to Write

Selectors are combined using the ~ (tilde) symbol.

How to Understand

The rule will apply to all blocks that match the right selector, provided they are siblings of the blocks from the left selector. Both selectors must have the same parent and be at the same level of nesting. In HTML, the right selector must come after the left selector.

In practice

Advice 1

🛠 It’s better to write selectors one per line — this makes them easier to read and edit:

        
          
          .selector1,code,#id,[attr="value"] {  color: red;}
          .selector1,
code,
#id,
[attr="value"] {
  color: red;
}

        
        
          
        
      

🛠 Combining increases the specificity of the rule, so this can be convenient for overriding properties without !important:

The code below cannot be edited for some reasons:

        
          
          .class1 {  color: red;}
          .class1 {
  color: red;
}

        
        
          
        
      

Let’s increase the specificity to override the rule described in the non-editable part and therefore having greater weight:

        
          
          .class1.class2 {  color: green;}.class1 {  color: red;}
          .class1.class2 {
  color: green;
}

.class1 {
  color: red;
}

        
        
          
        
      

As a result, the text in the block that has both the class .class1 and the class .class2 will be green.

🛠 It turns out that even an innocent space already has significance when selecting a selector at any level of nesting.

Regardless of the nesting level, the selector article h3 will "find" <h3> with the text "Very nested header" and any other <h3> that are located inside <article>:

        
          
          <article>  <div>    <div>      <div>        <div>          <div>            <div>              <div>                <div>                  <div>                    <h3>Very nested header</h3>                  </div>                </div>              </div>              <h3>Header</h3>            </div>          </div>        </div>      </div>    </div>  </div></article>
          <article>
  <div>
    <div>
      <div>
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <h3>Very nested header</h3>
                  </div>
                </div>
              </div>
              <h3>Header</h3>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</article>

        
        
          
        
      

Advice 2

🛠 Using the adjacent combinator, it is convenient to select a group of identical elements based on the principle of "all except the first" — for example, to set a margin.

Styles will not apply to the first <li> since there is no other <li> before it:

        
          
          <ul>  <li>First item</li>  <li>Second item</li>  <li>Third item</li>  <li>Fourth item</li></ul>
          <ul>
  <li>First item</li>
  <li>Second item</li>
  <li>Third item</li>
  <li>Fourth item</li>
</ul>

        
        
          
        
      
        
          
          li + li {  margin-top: 1em;}
          li + li {
  margin-top: 1em;
}

        
        
          
        
      

A classic example is the layout of a "star" rating. First, let's describe the structure:

        
          
          <div class="rating">  <button>★</button>  <button>★</button>  <button>★</button>  <button>★</button>  <button>★</button></div>
          <div class="rating">
  <button></button>
  <button></button>
  <button></button>
  <button></button>
  <button></button>
</div>

        
        
          
        
      

And the styles:

        
          
          button {  border: none;  background-color: transparent;  font-size: 5em;}button:hover,button:focus,button:hover ~ button,button:focus ~ button {  color: #F498AD;}
          button {
  border: none;
  background-color: transparent;
  font-size: 5em;
}

button:hover,
button:focus,
button:hover ~ button,
button:focus ~ button {
  color: #F498AD;
}

        
        
          
        
      

But now, when hovering the cursor, all elements after (i.e., on the right) will be highlighted.

Open demo in the new window

To fix this, we will change the order of the elements using the CSS property direction: rtl.

We will add this property to the parent of the stars .rating:

        
          
          .rating {  direction: rtl;}button {  border: none;  background-color: transparent;  font-size: 5em;}button:hover,button:focus,button:hover ~ button,button:focus ~ button {  color: #F498AD;}
          .rating {
  direction: rtl;
}

button {
  border: none;
  background-color: transparent;
  font-size: 5em;
}

button:hover,
button:focus,
button:hover ~ button,
button:focus ~ button {
  color: #F498AD;
}

        
        
          
        
      
Open demo in the new window