0

Im trying to change the first child, when i hover on the second child. How do you do this with html and css only?

(With the tilde/~ i seem to be able to select childeren downwards in the html code, but not upwards. Do i have to use a different selector to go upwards?)

grtz

<div id="container">
        <div id="box1"></div>
        <div id="box2"></div>
</div>

<style>
   #box1 {
      height: 100px;
      width: 100px;
      background-color: red;
   }

   #box2 {
      height: 100px;
      width: 100px;
      background-color: lime;
   }

   #box2:hover ~ #box1 {
      height: 300px;
      width: 300px;
      background-color: yellow;
   }

</style>
Kenneth
  • 13
  • 1
  • 6
  • 2
    The gist of CSS is that it's cascading. You can affect something that comes after an element, or is a child of an element. TLDR; you can't do that without JS – Chad Dec 23 '14 at 18:18
  • I can't even choose from which duplicate this question is – LcSalazar Dec 23 '14 at 18:28
  • possible duplicate of [Is there a previous sibling selector?](http://stackoverflow.com/questions/1817792/is-there-a-previous-sibling-selector) – Nelu Dec 23 '14 at 18:29
  • indeed. So many ways to ask a question for the same answer – Kenneth Dec 23 '14 at 18:36
  • @Chad: Cascading has nothing to do with that. Perhaps you could say that a child can inherit from a parent's styles (inheritance being one of the components of cascading), but sibling elements are completely separate from each other and cascading never takes place across elements. Being only able to select forward and not backward is little more than an unfortunate fact. – BoltClock Dec 24 '14 at 01:14

2 Answers2

2

General sibling selectors, this is what the tilde expresses, will only select the siblings following (not preceeding) the matched element.

The elements represented by the two sequences share the same parent in the document tree and the element represented by the first sequence precedes (not necessarily immediately) the element represented by the second one.

Reference: http://www.w3.org/TR/css3-selectors/#general-sibling-combinators


In your case there might be a CSS-only chance to archive this. Actually two ...

Chance 1

On parents :hover, change the children.

#container:hover div:first-child {
  background-color: #cff;
}

In your case, this required #container to be display: inline-block;, otherwise the red box would change too, when hovering the empty area right to both boxes.

Bin: http://jsbin.com/dilitucije/1

Works in all modern browsers and most older browsers too.

Chance 2

I'd use flexbox with defined order to reverse the rendering of both items. Since the rendering order of elements is reversed but the DOM order is not, this works.

CSS:

.reversed {
  display: flex;
  flex-direction: column-reverse; /* reverse rendering */
}

#container div:hover:first-child ~ div {
  background-color: #cff;
}

Explanation of the Flexbox rules:

  • use Flexbox (great explanation, W3C spec)
  • order the items in rows (the container is a "column"), reverse the order of the items within the .reversed container (first DOM node is rendered last, last DOM node is rendered first)

Add the class to your #container

<div id="container" class="reversed">...</div>

Bin: http://jsbin.com/piyokulehe/1

Works in FF 34, Chrome 39, should work in at least IE 11 too (probably not IE10).

Update:

  • Fixed wrong row-reverse (the example uses column-reverse, matches your requirement)
  • Removed unnecessary justify-content (since the items are rendered into rows, this is not necessary)
  • Added explanaition to the Flexbox solution
try-catch-finally
  • 7,436
  • 6
  • 46
  • 67
  • Could you explain, -- display: flex; flex-direction: row-reverse; /* reverse rendering */ justify-content: flex-end; -- of the 2nd solution a bit more plz. – Kenneth Dec 27 '14 at 02:52
  • Extended answer. Note: I've changed `row-reverse` (items in columns) to `column-reverse` (items in rows) to match the Jsbin. Removed `justify-content: flex-end;`, it's not necessary when not using together with `row-reverse` (items in a row). I hope the explanation s enough. – try-catch-finally Dec 27 '14 at 11:06
0

To achieved this on hover your element need to be the child of the element or comes after the element that is hovered.

The element whose styles are needed to be changed must be the descendent of the hovered element or comes next to it to work

A.B
  • 20,110
  • 3
  • 37
  • 71