4

I've found there's a simple way to count siblings of the <li> tag and return a CSS style fit for the how many <li> siblings there are:

ul{
 list-style-type: none;
    display: block;
}

#container{
 width: 100%;
 float: left;
 height: 100%;
 margin-left: 0;
 margin-top: 0;
}


li:first-child:nth-last-child(1) {
 height: 100%;
 background-color: red;
 width: 100%;
}

li:first-child:nth-last-child(2),
li:first-child:nth-last-child(2) ~ li {
 height: 100%;
 background-color: blue;
 float: left;
 width: 49%;
  margin-left: 1%;
}

li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
 height: 100%;
 float: left;
 background-color: red;
 width: 33.333%;
}


li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li {
 height: 100%;
 background-color: blue;
 float: left;
 width: 24%;
  margin-left: 1%;
}
<div id="container">
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>
</div>

I'm looking to hide <li> tags with the class="hidden"

I've tried:

ul {
list-style: none;
}



li.hidden:first-child:nth-last-child(2),
li.hidden:first-child:nth-last-child(2) ~ li {
 display: none;
}

li.hidden:first-child:nth-last-child(3),
li.hidden:first-child:nth-last-child(3) ~ li {
 background-color: blue;
}
<ul>
<li class="hidden">1</li>
<li>2</li>
<li class="hidden">3</li>
<li>4</li>
</ul>

Is there a way to selectively detect and change the CSS style of a <li> tag with the class of "hidden" based on the number of <li> tags with the class "hidden" without affecting the <li> tags without the class of "hidden"?

Sina
  • 270
  • 1
  • 23
CupOfJava
  • 441
  • 1
  • 5
  • 15
  • 1
    maybe you could provide a little clarity as to what you want to achieve. i cannot understand what do you want to do exactly. – Divneet May 27 '19 at 06:30
  • @Divneet I want to make the display of the < li> tags "none" if there are two < li> tags with the class "hidden" and make the background color blue if the there are three < li> tags with the class "hidden". The method I'm using is applying to all < li> tags as shown in the former of code samples. – CupOfJava May 27 '19 at 06:35
  • So I'm trying to achieve the effect of the former in the latter, but instead of applying it to all < li> tags, I want to apply it the only < li class="hidden"> – CupOfJava May 27 '19 at 06:38
  • I know the question can be answered with jQuery, but I'm really only looking for a CSS/HTML solution. – CupOfJava May 27 '19 at 06:53
  • Have you tried `.hidden{display: none;}` in your css? – MTBthePRO Jun 03 '19 at 20:08

3 Answers3

0

I dabbled with this a little bit. I can't seem to get classes working on this, maybe someone who knows CSS better than I do can get it going, but it seems nth-of-type and last-child have their nuances with what you're trying to do.

That aside, without using classes you can do counting on some level of different DOM elements. Hopefully this is enough for you to build onto or for someone else to add onto this, but it should be a good start anyways.

When you remove a list item so there's only 3, the background color will be blue on all 3. When you reduce to 2 li's, they disappear. 1, 4, or more instances of li's and they will display as normal.

Since nth-last-child expects the argument to be the last child, then by specifying nth-last-child(2) or nth-last-child(3) you are expecting exactly 2 or 3 instances of the element, since this counts children from back to front.

When concatenated with :first-child, we are looking for any element that is both the 2nd (or 3rd) element from the end and the first element.

If that condition is met, then that means there are exactly 2 (or 3) instances of this element.

To grab all elements in between you use the general sibling combinator (~)

To find out more information about this, you can check out this site [ https://alistapart.com/article/quantity-queries-for-css/ ] which explains it in a bit more depth, but I laid out a basic example of this below.

Hope that helps!

<!doctype html>
<html>
    <head>
    <meta charset="utf-8">
    <title>Untitled Document</title>
    <style type="text/css">

        li:nth-last-child(2):first-child, 
        li:nth-last-child(2):first-child ~ li {
            display: none;
        }

        li:nth-last-child(3):first-child, 
        li:nth-last-child(3):first-child ~ li {
            background-color: blue;
        }

    </style>
</head>

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
</body>

Rich
  • 181
  • 1
  • 5
0

A solution to this question of "Can div(s) be resized based on their siblings using CSS" unfortunately is still pending, but due to the number(#) of views on this post I feel as though a solution to the underlying question of "Can div(s) be resized based on their siblings" should be answered.

using jQuery an answer that I've come to:

$(document).ready(function(){

     var classinquestion = (".resizable");
     
     var LeftHeight = $("#left").height();
     
     var NavID = (".resizable");

     var element_count = $(classinquestion).length;
     
             if (element_count === 11) 
             {
                $(NavID).css({"line-height": (LeftHeight / element_count) + "px", "background-color": "red" }); 
             }
             if (element_count === 10) 
             {
                $(NavID).css({"line-height": (LeftHeight / element_count) + "px", "background-color": "blue" }); 
             }
             if (element_count === 9) 
             {
                $(NavID).css({"line-height": (LeftHeight / element_count) + "px", "background-color": "green" }); 
             }
             if (element_count === 8) 
             {
                $(NavID).css({"line-height": (LeftHeight / element_count) + "px", "background-color": "yellow" }); 
             }
             if (element_count === 7) 
             {
                $(NavID).css({"line-height": (LeftHeight / element_count) + "px", "background-color": "pink" }); 
             }
             if (element_count === 6) 
             {
                $(NavID).css({"line-height": (LeftHeight / element_count) + "px", "background-color": "orange" }); 
             }
             if (element_count === 5)
             {
                $(NavID).css({"line-height": (LeftHeight / element_count) + "px", "background-color": "white" }); 
             }
             if (element_count === 4)
             {
                $(NavID).css({"line-height": (LeftHeight / element_count) + "px", "background-color": "black" }); 
             }
             if (element_count === 3)
             {
                $(NavID).css({"line-height": (LeftHeight / element_count) + "px", "background-color": "grey" }); 
             }
             if (element_count === 2)
             {
                $(NavID).css({"line-height": (LeftHeight / element_count) + "px", "background-color": "brown" }); 
             }
             if (element_count === 1)
             {
               alert("1"); 
             };

         });
#left {
  background-color: #363636;
  height: fit-content;
 }

.resizable{
 margin-left: 10%;
  margin-right: 10%;
  margin-top: 1%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="left">
     <div class="resizable">1</div>
     <div class="resizable">2</div>
     <div class="resizable">3</div>
     <div class="resizable">4</div>
     <div class="resizable">5</div>
     <div class="resizable">6</div>
     <div class="resizable">7</div>
     <div class="resizable">8</div>
     <div class="resizable">9</div>
     <div class="resizable">10</div>
     <div class="resizable">11</div>
</div>

To see the real effects of the script the code should be run through different means then Stackoverflow's "Run code snippet", this is because the HTML element within the "Result" section resizes.

CupOfJava
  • 441
  • 1
  • 5
  • 15
-1
  1. I have beautified/refactored your code (I think, is clearer this way) - I did not understand why do you want to use "first-child" in combination with "nth-last-child". How that supposed to work, I don't really understand.

  2. Here's a quick reponse about this very same topic - Why you cannot achieve what you want from CSS only. How to get nth-child selector to skip hidden divs

  3. So, my response is not complete / is not working as you expect it. You'll have to use JQuery to achieve this, in my opinion.

ul{
 list-style-type: none;
    display: block;
}

#container{
 width: 100%;
 float: left;
 height: 100%;
 margin-left: 0;
 margin-top: 0;
}

li {
  color: yellow;
  float: left;
  height: 100%;
  line-height: 50px;
  margin-left: 1%;
  text-align: center;
  width: 20%;
}

li.hidden{
  display: none;
}


li:nth-child(1) {
 background-color: green;
}

li:not(.hidden):nth-child(2){
 background-color: silver;
}

li:not(.hidden):nth-child(3){
 background-color: red;
}

li:not(.hidden):nth-child(4){
 background-color: blue;
}
<div id="container">
  <ul>
      <li>1</li>
      <li class="hidden">2</li>
      <li>3</li>
      <li class="hidden">4</li>
  </ul>
</div>
  1. I have added a version with nth-of-type also - nothing new here. You should consider using jQuery.

ul{
  background: #eee;
  cursor: pointer;
  display: table;
 list-style-type: none;
  padding: 10px;
  width: 80%;
}

#container{
 width: 100%;
 float: left;
 height: 100%;
 margin-left: 0;
 margin-top: 0;
}

li {
  border: 1px solid #333;
  border-radius: 4px;
  color: #333;
  float: left;
  font-weight: bold;
  height: 100%;
  line-height: 50px;
  margin-left: 1%;
  text-align: center;
  width: 20%;
}

li.hidden{
  display: none;
}

ul:hover li.hidden {display: block;}


li:nth-of-type(1):not(.hidden) {
 background-color: green;
}

li:nth-of-type(2):not(.hidden){
 background-color: silver;
}

li:nth-of-type(3):not(.hidden){
 background-color: red;
}

li:nth-of-type(4):not(.hidden){
 background-color: blue;
}
<div id="container">
  <ul>
      <li>1</li>
      <li class="hidden">2</li>
      <li>3</li>
      <li class="hidden">4</li>
  </ul>
</div>
Hunor
  • 449
  • 1
  • 5
  • 19