55

In CSS there is no way to select a sibling with plus if the sibling is above in the output, a preceding element in the HTML.

For example

<div class="first">
<div class="second">

.second + .first { 
    //style applied to div.first
}

Is there anyway to do this in SASS/SCSS?

Asef Hossini
  • 655
  • 8
  • 11
petergus
  • 1,192
  • 1
  • 12
  • 18
  • I'd be very surprised to see this, it goes against CSS flow. – Nick Andriopoulos Mar 06 '13 at 11:41
  • well the SASS parent selector `.class &`, but i suppose that is something else. – petergus Mar 06 '13 at 14:05
  • Just wanted to note, SASS doesn't add any feature to CSS! CSS is the only styling language browsers support, unless SASS could somehow be processed by browsers directly it will obviously not add any feature (and it doesn't). – 0fnt Nov 04 '14 at 14:39
  • There is an article about a way to hack this https://medium.freecodecamp.org/how-to-make-the-impossible-possible-in-css-with-a-little-creativity-bd96bb42b29d – petergus Oct 23 '18 at 05:20

5 Answers5

75

SASS supports all CSS3 selectors. Sibling + selector is one of them. But it does not bring some extra features. It means you can do

.first {
    + .second { 
        font-size: smaller;
    }
}

But you can't impact a parent with it...

P.S. It seems to be a feature of CSS4.

Xavier
  • 3,919
  • 3
  • 27
  • 55
  • 6
    im not trying to target a parent, im trying to target a sibling, but not the next sibling down, rather up. – petergus Mar 07 '13 at 12:40
  • 3
    Same answer, Sass don't provide this... You'll have to wait CSS4 – Xavier Mar 09 '13 at 13:29
  • 5
    If the sibling if before of the element doesn't work. Need to be after – Diego Juliao Jun 29 '18 at 22:23
  • 2
    @DiegoJuliao ... I wish more people had liked your comment! :-) Or if Xavier would add it to his answer. – Zeth Oct 31 '19 at 03:12
  • @Zeth That's what `But you can't impact a parent with it ...` meant! – Xavier Oct 31 '19 at 12:39
  • But it's not a parent. It will not work if the sibling is written before the targeted element. `
    `. ... If you on this code write: `#parent + #sibling-one { background: red; }`, then `#sibline-two` will have background: red. But if you write `#parent + #sibling-two { background: red; }`, then `#sibling-one` _will not_ have a red background.
    – Zeth Nov 01 '19 at 22:04
  • I tried making a codepen to prove it, but I can't get anything to work and not work in there. I hope I can be of some use to someone, though: https://codepen.io/zethzeth/pen/LYYexzO – Zeth Nov 01 '19 at 22:24
5

I know the feeling, this is really annoying. I found a quick way of doing it tho.

HTML

<div class="mainmenu">
  <div class="subnav">
    <ul>
      <li>Whatever</li>
    </ul>
  </div>
</div>

SCSS

CSS is pointed towards to first child of div "mainmenu" with the > class "subnav"

 .mainmenu{
      & > .subnav{
         // Child Selector SCSS HERE
      }
  }

@thgaskell, you have proved me wrong :) My code works fine and I lost 6KB of my Minified code! I have updated the code as how the comment below was informed.

Neil
  • 971
  • 2
  • 12
  • 33
  • 1
    In your last example you could replace the second line with `& > .subnav` [Referencing Parent Selectors](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#referencing_parent_selectors_). – thgaskell Mar 19 '13 at 15:03
  • have you tested that out above, if it would it would help me out.. I would test it. But I am currently on a windows machine which does not have sass (as I use CodeKit).... – Neil Mar 20 '13 at 16:36
  • 1
    I think the question is about selecting the first sibling through the second one and not through the parent. – hadaytullah Dec 07 '20 at 19:12
3

May or may not be suitable for your needs but you can use the general sibling selector in Sass/CSS. This will select all elements on the same node level (not explicitly before but still handy):

.second {
   .first ~ & {
       /* styles to be applied to .second if a .first exists at the same node level */   
   }
}
Ben Frain
  • 2,510
  • 1
  • 29
  • 44
  • 4
    This will *only* select siblings *after* `.first`, not all elements on the same node level. – Jason Sep 29 '16 at 14:46
-2

I ended up using Jquery. gets the job done :) (sorry i dont have the example code anymore as i went another route, but its quite simple, something like 'if child has class then add class to this'. :)

petergus
  • 1,192
  • 1
  • 12
  • 18
-6
div { & + & { margin-left: 15px; background: firebrick;}}

try it it's work.

Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162