1

Is there a way in CSS to apply CSS rules to a last visible child without knowing the class which makes an element invisible?

Example:

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li style="display: none">Item 5</li>
<ul>

<style>
  ul > li {
    border: 1px solid black;
  }

  // Remove right border from last visible child
  // This does not work of course, but this is what I am looking for
  ul > li:last-child:not([style="display: none"]) {
    border-right: none;
  }
</style>

To be clear: I'm looking for a rule-based selector not class-based in CSS not Javascript. But this answer A CSS selector to get last visible div for example does not work. The problem here is that :last-child and :not can not be combined. :last-child([style="display: block"]) also does not work (when li has dispay: block), because it looks at the style attribute and not at the CSS rule.

Example in bootstrap (NOTE: hidden-md is an example, it could also be an other class which uses display:none):

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li class="hidden-md">Item 5</li>
<ul>
Community
  • 1
  • 1
Klaasvaak
  • 5,634
  • 15
  • 45
  • 68
  • here you could do `li[style] {border:none;}` but , what's the point if it is set at `display:none;` ? – G-Cyrillus Mar 20 '14 at 08:58
  • @GCyrillus it might be placeholder...? – benomatis Mar 20 '14 at 08:59
  • how do you set display:none ? through style attribute or a class or whatever. Whereever there is something peticular to it that CSS can see, use it :) my example only search for a li that has the style attribute since it is the one you want to select – G-Cyrillus Mar 20 '14 at 09:00
  • @GCyrillus display: none is set by a class which would be unknown in this case. – Klaasvaak Mar 20 '14 at 09:01
  • are others getting a class too ? if not use li[class] if classes all start wicth the same caracters use li[class^="baba"] it will match .babac, .babawhatever – G-Cyrillus Mar 20 '14 at 09:02
  • @GCyrillus No, in my case the invisible li gets class hidden-md (bootstrap) but I want to make it so that it would also work on a hidden-xs, etc. So it should only remove the border when it has the right screensize. So the question is really is there a way to select on rule rather than class? – Klaasvaak Mar 20 '14 at 09:07
  • @James Donnelly that does not answer my question – Klaasvaak Mar 20 '14 at 09:09
  • Is it always the last child that is invisible? – Nico O Mar 20 '14 at 09:25
  • 1
    @Klaasvaak , for what you want you need javascript , to test a rule and then select previous sibbling element. CSS can not – G-Cyrillus Mar 20 '14 at 09:38
  • 1
    @GCyrillus I guess the answer would be: it is not possible. I know it can be done with workaround but that is not the question. – Klaasvaak Mar 20 '14 at 09:40

2 Answers2

5

It is not possible with CSS, however you could do this with jQuery. Try this clumsy code.

jQuery:

 $('li').not(':hidden').last().addClass("red");

HTML:

<ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li class="hideme">Item 4</li>    
</ul>

CSS:

.hideme {
    display:none;
}

.red {
    color: red;
}

jQuery (previous solution):

var $items = $($("li").get().reverse());

$items.each(function() {

    if ($(this).css("display") != "none") {
        $(this).addClass("red");
        return false;
    }

});
martynas
  • 12,120
  • 3
  • 55
  • 60
3

From CSS it is not possible :)

maybe if you draw the right border from the left border of next element or next pseudo element , you get half of the job done :http://codepen.io/gc-nomade/pen/ohKwv/

/* basic and naive workaround for borders */
  ul {
  text-align:center;
}li {
   display:inline-block;
   padding:0 1em
 }
li + li {
  border-left:solid;
}
ul:hover li:nth-child(even) {/* test : hide every even lis at once */
  display:none;
}
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129