1

I have a snippet that I based on the Base Example, targeting previous sibling with the use of flexbox. It is working nicely with li elements, but as soon as I try to do it with label and input it stops working.

Unfortunately I am relying on a code that puts the label first and input second making it so far impossible to target and manipulate on input:focus.

Is there any chance that I can get it to work from CSS(I am using Sass so that is an option)?

The base example is from a similar, but general question querying targeting previous sibling rather then the label+input:focus pair.

Base Example

ul {
    display: flex;
}

li:hover + li {
    background-color: red;
}

li:last-child {
    order: -1;
}

/* non-essential decorative styles */
li {
    height: 200px;
    width: 200px;
    background-color: aqua;
    margin: 5px;
    list-style-type: none;
    cursor: pointer;
}
<ul>
    <li>B</li>
    <li>A</li>
</ul>

Example I'm trying to get to work

div{ 
    display: flex
}
input:focus + label{
    color:red;
}
label{
    order: 1;
}
<div>
  <label for="NAME">Name</label>
  <input type="text">
</div>
<div>
  <label for="EMAIL">Email</label>
  <input type="email">
</div>
Community
  • 1
  • 1
Ben S
  • 558
  • 3
  • 18
  • CSS selector cannot go up in the HTML tree, your second example gives you the answer with flex and order i believe :) at least the EMAIL/input works – G-Cyrillus Dec 05 '16 at 18:52
  • Well I realised that it is not working :(... I need to get this work so I'm open to other suggestions :) Worst case scenario jQuery... – Ben S Dec 05 '16 at 18:54
  • Sorry, maybe you misunderstood me. For it to work it would mean that by flexbox reordering I could still change the colour to red regadless off the DOM order, like with the li example. It does not work with input and label. Not even when using the :has(~input:focus) selector... – Ben S Dec 05 '16 at 18:57
  • only javascript will do if you cannot update html – G-Cyrillus Dec 05 '16 at 19:13
  • That was my worry. I have to use it then... Thanks anyways. – Ben S Dec 05 '16 at 19:23
  • here is an average trick , http://codepen.io/gc-nomade/pen/ENEbEJ can break or not even work in some browsers – G-Cyrillus Dec 05 '16 at 19:25
  • In your _"Example I'm trying to get to work"_ I just changed the `order: 1` to be `order: -1` to match the `li:last-child` of the working example, and when I do that the label appears before the field. Is that what you want? – Stephen P Dec 05 '16 at 20:52

3 Answers3

0

As we do not have a previous sibling selector in CSS this is the pure CSS way use direction: rtl; to reverse the order

div{ 
  direction: rtl;
  text-align:left;
}
div *{ 
  direction: ltr;
}
input:focus + label{
  color:red;
}
<div>
  <input type="text">
  <label for="NAME">Name</label>
</div>
<div>
  <input type="email">
  <label for="EMAIL">Email</label>
</div>
jafarbtech
  • 6,842
  • 1
  • 36
  • 55
  • This is the exact order my HTML is output:
    I cannot reorder the label-input...
    – Ben S Dec 05 '16 at 22:21
  • But this is not feasible in CSS. Please check through [this link](http://stackoverflow.com/a/1817801/6082645) – jafarbtech Dec 05 '16 at 22:25
  • I realised, and unfortunately have to stick with jQuery to sort this problem. Most of the answers were out of date hence I asked again, with a specific thing. TIL that ~ operator relies on physical DOM order. – Ben S Dec 05 '16 at 22:28
  • yes true. you dont have an optiion to manage it in selectors. so Jquery is the best choice while onfocus – jafarbtech Dec 05 '16 at 22:31
0

There can be a rough CSS trick to mimic what you look for, but breakable. See mix-blend-mode and caniuse

div {/* or use the direction properties */
  display:flex;
  flex-flow:row-reverse;
  justify-content:flex-end
}

label {
  display:inline-block;
  position:relative;
  width:5em;
  background:white;/* will remain white */
  mix-blend-mode:screen; /* whatever is black will show what's behind */
}
input:focus {
  box-shadow: 5em 0 red
}
<div>
  <label for="NAME">Name</label>
  <input type="text">
</div>
<div>
  <label for="EMAIL">Email</label>
  <input type="email">
</div>
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
0

As many of you pointed it out, there is still no solution purely with CSS. I will have to work around this with jQuery.

Thanks for taking the effort to try to supply with an answer. Much appreciated.

Ben S
  • 558
  • 3
  • 18