Search code examples
htmlcsscss-selectorsconditional-formatting

Select element only if a later sibling exists


In my HTML structure, I have it set up like this:

<body>
   <main>
      <section>
      ...
      </section>

      <aside>
      ...
      </aside>
   </main>
</body>

The problem is, not all pages have <aside>

I need to select <section> and give it a max-width: 500px; ONLY when <aside> is present. The default is section { max-width: 1000px; } (when <aside> is absent)

Unlike in Selector for one tag directly followed by another tag the user [asking the question] wants to style "B" ALL the time. Also, in this question, the user wants to select "B" (not "A")


  • I need to style <section> ONLY if <aside> is present.
  • I can't change the order of the HTML >_<
  • Can it be done with CSS only?
  • What selector do I need or how to set it up?
  • If it can't be done with CSS (I rather it be CSS-only), how can I accomplish this?

Solution

  • A neat little trick

    You can achieve what you want by using a trick to check if the <section> element is the only element in <main>. This will not work, if there are any other elements there. In your case it should work like this (http://jsfiddle.net/Ljm323qb/2/):

    section {
         max-width: 500px;
    }
    /* The STAR of the show */
    section:only-child {
         max-width: 1000px;
    }
    

    As illustrated in this codepen: http://codepen.io/omarjuvera/pen/ByXGyK?editors=110


    General stuff on Sibling Selectors

    There's the + selector which would select a sibling that comes right after the element (https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_selectors)

    And there's the ~ selector which selects all following siblings (https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_selectors)

    You could achieve it by putting the <aside> element before the <section> element and using a sibling selector.

    Here's an example: http://jsfiddle.net/Ljm323qb/1/

    A quick look in the future
    Soon this will be possible, with a new :has pseudo class (http://dev.w3.org/csswg/selectors-4/#relational)
    You'll be able to call something like main:has(> aside) > section { ... } but we'll have to wait for that, unfortunately :(