Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: 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?
like image 257
Omar Avatar asked Apr 15 '15 22:04

Omar


People also ask

How do I target a previous sibling in CSS?

No, there is no "previous sibling" selector. On a related note, ~ is for general successor sibling (meaning the element comes after this one, but not necessarily immediately after) and is a CSS3 selector. + is for next sibling and is CSS2.

How do I select a specific sibling in CSS?

Adjacent Sibling Selector (+) The adjacent sibling selector is used to select an element that is directly after another specific element. Sibling elements must have the same parent element, and "adjacent" means "immediately following".

What is next sibling selector?

Description: Selects all sibling elements that follow after the "prev" element, have the same parent, and match the filtering "siblings" selector.


2 Answers

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 :(

like image 162
wawa Avatar answered Sep 18 '22 14:09

wawa


You can toggle a class .haveSidebar to the body tag using jQuery and make your CSS for the section tag depends whether this class exists on the body tag or not:

HTML

<main>     <section>     </section>      <aside>     </aside> </main> 

CSS

main {     width:100%; } main aside {     width:300px;     background:red;     min-height:300px;     float:left; } main section {     width:100%;     background:green;     min-height:300px;     float:left; } body.haveSidebar main section {     width: calc(100% - 300px); } 

JS

var sideBar = $('body > main > aside'); if (sideBar.length > 0) {     $('body').addClass('haveSidebar'); } else {     $('body').removeClass('haveSidebar'); } 

Fiddle with aside tag

Fiddle without aside tag

Update

Solution without calc(), by using margin-left property

main aside {     width:300px;     background:red;     min-height:300px;     position:relative; } main section {     width:100%;     background:green;     min-height:300px;     float:left; } .haveSidebar main section {     margin-left:301px; } 

Fiddle without calc()

like image 37
Fares M. Avatar answered Sep 18 '22 14:09

Fares M.