0

Say I have a list with n items and I want to make the width of the first list item "rowspan=2". The width will change depending on the number of n, but in the example below:

<ul>
  <!-- <li>Row-2-1</li>-->
  <li class="ui-grid-span-2">SPAN 2</li>
  <li>Row 2-3</li>
  <li>Row 2-4</li>
  <li>Row 2-5</li>
  <li>Row 2-6</li>
</ul>

This would change this:

|-----------------------------------|
|  1  |  2  |  3  |  4  |  5  |  6  |
|-----------------------------------|

to this:

|-----------------------------------|
|  1  |   SPAN2   |  4  |  5  |  6  |
|-----------------------------------|

my original six items are now reduced to five (four regular items, one item spanning two). So I'm writing my selector like this:

ul > li:nth-child(-n+5).ui-grid-span-2 {
  width: 33.33%;
}

but it does not work. Instead this rule applies:

ul > li:nth-child(-n+2).ui-grid-span-2 {
    width: 66.66%;
}

and I don't understand why.

Question:
How do I address "all childs of five childs, the one with class: ui-grid-span-2" directly. This means, instead of all cells being 1/6 width = 16.66%, the one with the class assigned should be 2/6 = 33.33%.

EDIT...: This is not a dupe of this questions. The solution of Vera allows to set the width based on total number of cells either by siblings (does not apply here, because if the 3rd cell was a rowspan=2, I could only set the width of the following cells, not the previous ones). The original solution requires a line of code for every cell (if have n=10 max) and then doing this for every *-span class = a giant pile of CSS.

ANSWER:
Found out why. Selectors are "greedy" = "take first seven" will include/override "take first six". Solution below.

Community
  • 1
  • 1
frequent
  • 27,643
  • 59
  • 181
  • 333
  • possible duplicate of [Can CSS detect the number of children an element has?](http://stackoverflow.com/questions/8720931/can-css-detect-the-number-of-children-an-element-has) – Vandervals Jun 01 '15 at 16:13
  • @Vandervals: I know this answer. this does not help at all. – frequent Jun 01 '15 at 16:14
  • 2
    It's not clear to me what you are trying to do. – Paulie_D Jun 01 '15 at 16:15
  • The obvious answer is to use a modifier class on a list that has 5 items. If the list is dynamic, then you would need to use some JS to count the items, and then add a class accordingly. But what you are trying to do will never work as is, and is far too complicated to be practical. – Sean Stopnik Jun 01 '15 at 16:16
  • Can you reiterate what you're trying to do? I also can't seem to understand your goal. – TylerH Jun 01 '15 at 16:18
  • @Paulie_D: I have to stretch the cell with "span-2" to 2/6: 33.33% with the others remaining on 1/6: 16.66% – frequent Jun 01 '15 at 16:19
  • Frankly, this sounds like something an actual `table` would solve with `colspan` – Paulie_D Jun 01 '15 at 16:24
  • How about an illustration of your desired result as opposed to a textual description? – BoltClock Jun 01 '15 at 16:27
  • @Paulie_D: yes. This is probably what I will be doing eventually. For now I did it the harder way (see below). – frequent Jun 02 '15 at 09:33
  • @BoltClock: Good point. – frequent Jun 02 '15 at 09:33

3 Answers3

3

Flexbox seems to be a solution here although the actual question seems unclear.

ul {
  margin: 0;
  list-style: none;
  padding: 0;
  display: flex
}
li {
  border: 1px solid grey;
  flex-grow: 1;
}
.ui-grid-span-2 {
  flex-grow: 2;
}
<ul>
  <li class="ui-grid-span-2">SPAN 2</li>
  <li>Row 2-3</li>
  <li>Row 2-4</li>
  <li>Row 2-5</li>
  <li>Row 2-6</li>
</ul>
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
  • 1
    You should mention that in the question so that other users don't waste their time coming up with solutions you won't accept. – Paulie_D Jun 01 '15 at 16:22
  • so my idea was to write a selector capturing all cells based on their total number including "rowspan-cell" and then applying a width to only the "rowspan-cell" – frequent Jun 01 '15 at 16:23
0

* {
    margin: 0;
    padding: 0;
}
ul {
    list-style: none;
}
li {
    text-align: center;
    display: inline-block;
    width: 16.6%;
    background-color: red;
}
li:last-child, li:first-child, li:nth-child(3) {
    background-color: brown;
}
.ui-grid-span-2 {
    width: 32.2%;
}
<ul>
    <li class="ui-grid-span-2">SPAN 2</li><li>
    Row 2-3</li><li>
    Row 2-4</li><li>
    Row 2-5</li><li>
    Row 2-6</li>
</ul>

I think you CAN'T do what you want for a dinamic number of < li >'s without JS or flex

Aramil Rey
  • 3,387
  • 1
  • 19
  • 30
-1

Ok, after some more meddling my original idea works. This means if you have the following HTML:

<ul class="grid-items">
  <!-- <li>Row 1-1</li> -->
  <li class="ui-grid-span-2">SPAN 2</li>
  <li>Row 1-3</li>
  <li>Row 1-4</li>
  <li>Row 1-5</li>
  <li>Row 1-6</li>
</ul>

the width of the list elements can be set as I intended:

ul > li:nth-child(-n+4).ui-grid-span-2 {
  width: 33.33%;
}
ul > li:nth-child(-n+3).ui-grid-span-3 {
  width: 50%;
}
ul > li:nth-child(-n+2).ui-grid-span-4 {
  width: 66.66%;
}
ul > li:nth-child(-n+1).ui-grid-span-5 {
  width: 83.33%;
}

Note that by spanning multiple cells, the total number of cells change, too, so the pseudo-selector must be adjusted depending on cells spanned. To make it work with multiple ranges of cells (not always 6 cells as above) it is also required to add a class on the list element to note the number of cells in a row. Otherwise larger selector (take first 8 items) will overwrite/encapsulate smaller ones (take first 7 items).

Still not happy with it and only supporting a single rowspan per row, but... it works and it's not using any of the above proposed solutions (~ siblings, x*y cells * n rowspans rules, flexbox or tables). Keep in mind, the regular cell width declarations need to be amended, too, as a row using rowspan will have less number of cells but require the original intended number of cells' width.

Final CSS for up to 8 cell grids (I have not combined declarations for sake of comprehensability).

Note:
- section ROWSPAN is the relevant section
- before I ensure cell width is set based on intended not actual number of cells
- selectors are cutoff for relevance.

/* base width */
ul > li {
  width: auto;
}

/* "cell width" */
ul > li:first-child:nth-last-child(1) {
  width: 100%;
}
ul > li:first-child:nth-last-child(2),
ul > li:first-child:nth-last-child(2) ~ li {
  width: 50%;
}
ul.ui-grid-column-3 > li:first-child:nth-last-child(n),
ul.ui-grid-column-3 > li:first-child:nth-last-child(n) ~ li  {
  width: 33.3333%;
}
ul.ui-grid-column-4 > li:first-child:nth-last-child(n),
ul.ui-grid-column-4 > li:first-child:nth-last-child(n) ~ li {
  width: 25%;
}
ul.ui-grid-column-5 > li:first-child:nth-last-child(n),
ul.ui-grid-column-5 > li:first-child:nth-last-child(n) ~ li {
  width: 20%;
}
ul.ui-grid-column-6 > li:first-child:nth-last-child(n),
ul.ui-grid-column-6 > li:first-child:nth-last-child(n) ~ li {
  width: 16.667%;
}
ul.ui-grid-column-7 > li:first-child:nth-last-child(n),
ul.ui-grid-column-7 > li:first-child:nth-last-child(n) ~ li {
  width: 14.285714286%;
}
ul.ui-grid-column-8 > li:first-child:nth-last-child(n),
ul.ui-grid-column-8 > li:first-child:nth-last-child(n) ~ li {
  width: 12.5%;
}

/* ROWSPAN */
/* 3 cells */
ul.ui-grid-column-3 > li:nth-child(-n+2).ui-grid-span-2 {
  width: 66.666%;
}
/* 4 cells */
ul.ui-grid-column-4 > li:nth-child(-n+3).ui-grid-span-2 {
  width: 50%;
}
ul.ui-grid-column-4 > li:nth-child(-n+2).ui-grid-span-3 {
  width: 75%;
}
/* 5 cells */
ul.ui-grid-column-5 > li:nth-child(-n+4).ui-grid-span-2 {
  width: 40%;
}
ul.ui-grid-column-5 > li:nth-child(-n+3).ui-grid-span-3 {
  width: 60%;
}
ul.ui-grid-column-5 > li:nth-child(-n+2).ui-grid-span-4 {
  width: 80%;
}
/* 6 cells */
ul.ui-grid-column-6 > li:nth-child(-n+5).ui-grid-span-2 {
  width: 33.33%;
}
ul.ui-grid-column-6 > li:nth-child(-n+4).ui-grid-span-3 {
  width: 50%;
}
ul.ui-grid-column-6 > li:nth-child(-n+4).ui-grid-span-4 {
  width: 66.66%;
}
ul.ui-grid-column-6 > li:nth-child(-n+4).ui-grid-span-5 {
  width: 83.33%;
}
/* 7 cells */
ul.ui-grid-column-7 > li:nth-child(-n+6).ui-grid-span-2 {
  width: 28.571428571%;
}
ul.ui-grid-column-7 > li:nth-child(-n+5).ui-grid-span-3 {
  width: 42.857142857%;
}
ul.ui-grid-column-7 > li:nth-child(-n+4).ui-grid-span-4 {
  width: 57.142857142%;
}
ul.ui-grid-column-7 > li:nth-child(-n+3).ui-grid-span-5 {
  width: 71.428571428%;
}
ul.ui-grid-column-7 > li:nth-child(-n+2).ui-grid-span-6 {
  width: 85.714285714%;
}

/* 8 cells */
ul.ui-grid-column-8 > li:nth-child(-n+7).ui-grid-span-2 {
  width: 25%;
}
ul.ui-grid-column-8 > li:nth-child(-n+6).ui-grid-span-3 {
  width: 37.5%;
}
ul.ui-grid-column-8 > li:nth-child(-n+5).ui-grid-span-4 {
  width: 50%;
}
ul.ui-grid-column-8 > li:nth-child(-n+4).ui-grid-span-5 {
  width: 62.5%;
}
ul.ui-grid-column-8 > li:nth-child(-n+3).ui-grid-span-6 {
  width: 75%;
}
ul.ui-grid-column-8 > li:nth-child(-n+2).ui-grid-span-7 {
  width: 87.5%;
}

/* responsive */
@media (max-width: 32em) {
ul > li,
ul[class*="ui-grid-column"] > li {
    width: 100%;
  }
}
frequent
  • 27,643
  • 59
  • 181
  • 333