Reputation: 2807
* {
outline: 1px solid rgba(255, 0, 0, .2);
}
ol {
*:not(li) {
grid-area: none;
/* hmmm... this is not right*/
}
padding: 0;
list-style: none;
display: grid;
grid-template-columns: min-content 1fr;
grid-column: subgrid;
li {
grid-column: 1 / -1;
display: grid;
grid-template-columns: subgrid;
width: 100%;
}
}
ol {
counter-reset: Nr;
*::before {
font-variant-numeric: tabular-nums;
overflow-wrap: normal;
word-break: keep-all;
}
>li {
counter-increment: Nr;
&::before {
content: counter(Nr) ".";
text-align: end;
margin-right: 0.85rem;
}
>ol {
counter-reset: lit;
>li {
counter-increment: lit;
&::before {
content: counter(lit, lower-latin)')';
}
>ol {
counter-reset: sublit;
>li {
counter-increment: sublit;
&::before {
content: counter(sublit, lower-roman) '.';
}
}
}
}
}
}
}
<ol>
<li>
This is <strong>txt</strong> hi.
<ol>
<li>This li is not affected.</li>
</ol>
</li>
</ol>
I would like to have all inline-elements such as the strong
from the example behave normally and not get influenced by any grid/subgrid layouts… Also, everything in the same li
after the strong
element in the example is broken, too.
What I have tried so far is manipulating the display property and the grid property of any non-li item. My latest approach is in the code with a comment next to it.
It should look like this:
[
But the snippet output is:
Why I am using grid? I want to have maximum control over the width of the numbers/bullets, their "padding" (e. g. exactly centering a variable/unknown-width number in the "column of numbers") and the extent of indentation of any sub-lists...
For example: indent from the left should be exactly 1 cm while perfectly centering what ever bullet is being used + aligning numbers with different digit lengths to another correctly and letting any sub-lists numbering begin with its left edge exactly where the previous li text started... and so on, all at the same time and with granular control and maximum flexibility.
Upvotes: 0
Views: 121
Reputation: 14340
This is the grid solution you are looking for.
The key to the solution (and yes, it is slightly annoying) is to add some extra wrapper elements in your HTML. For any <li>
which contains another explicit element such as <strong>
or <a>
, wrap its entire contents with another element ... I have used a <div>
. (Of course, you can make it easy by just adding the additional wrapper inside every <li>
.)
ol {
margin-left: 1em;
padding: 0;
counter-reset: l1;
display: grid;
grid-template-columns: auto 1fr;
gap: 0 0.5em;
}
ol > li {
list-style: none;
display: contents;
}
ol > li::before {
content: counter(l1) '.';
counter-increment: l1;
}
ol ol {
counter-reset: l2;
}
ol ol > li::before {
content: counter(l2, lower-latin) ')';
counter-increment: l2;
}
ol ol ol {
counter-reset: l3;
}
ol ol ol > li::before {
content: counter(l3, lower-roman) '.';
counter-increment: l3;
}
<ol>
<li>
<div>
This is <strong>txt</strong> hi.
<ol>
<li>
<div>a <a href="">link</a> here.
<ol>
<li>
<div>
a <a href="">link</a> here.
</div>
</li>
<li>This li is not affected.</li>
</ol>
</div>
</li>
<li>
<div>
This <strong>li is not</strong> affected.
</div>
</li>
<li>This li is not affected.</li>
</ol>
</div>
</li>
<li>This li is not affected.</li>
<li>This li is not affected.</li>
</ol>
Upvotes: 0
Reputation: 2807
grid-area: none;
was wrong
instead I used display: contents;
Nested lists did not display correctly then. But this is just because they were not accounted for in the :not()
function. Added ol
and ul
to the function.
Now everything displays correctly.
* {
outline: 1px solid rgba(255, 0, 0, .2);
}
li > *:not(ul, ol) {
/* I have added ol, ul to the :not() function to make list nesting work again and improved the syntax*/
display: contents; /* this fixes it */
}
padding: 0;
list-style: none;
display: grid;
grid-template-columns: min-content 1fr;
grid-column: subgrid;
li {
grid-column: 1 / -1;
display: grid;
grid-template-columns: subgrid;
width: 100%;
}
}
ol {
counter-reset: Nr;
*::before {
font-variant-numeric: tabular-nums;
overflow-wrap: normal;
word-break: keep-all;
}
>li {
counter-increment: Nr;
&::before {
content: counter(Nr) ".";
text-align: end;
margin-right: 0.85rem;
}
>ol {
counter-reset: lit;
>li {
counter-increment: lit;
&::before {
content: counter(lit, lower-latin)')';
}
>ol {
counter-reset: sublit;
>li {
counter-increment: sublit;
&::before {
content: counter(sublit, lower-roman) '.';
}
}
}
}
}
}
}
<ol>
<li>
This is <strong>txt</strong> hi.
<ol>
<li>This li is not affected.</li>
</ol>
</li>
</ol>
Upvotes: 0
Reputation: 273839
I would consider float to achieve the same layout. I don't think CSS grid is the right approach.
ol {
padding: 0;
list-style: none;
overflow: hidden; /* this */
}
ol {
counter-reset: Nr;
*::before {
font-variant-numeric: tabular-nums;
overflow-wrap: normal;
word-break: keep-all;
}
li {
counter-increment: Nr;
clear: both; /* and this */
&::before {
content: counter(Nr) ".";
text-align: end;
margin-right: 0.85rem;
/* and this */
margin-bottom: 2px;
float: left;
/**/
}
ol {
counter-reset: lit;
li {
counter-increment: lit;
&::before {
content: counter(lit, lower-latin)')';
}
ol {
counter-reset: sublit;
li {
counter-increment: sublit;
&::before {
content: counter(sublit, lower-roman) '.';
}
}
}
}
}
}
}
<ol>
<li>
This is <strong>txt</strong> hi.
<ol>
<li>a <a href="">link</a> here.
<ol>
<li>a <a href="">link</a> here.</li>
<li>This li is not affected.</li>
</ol>
</li>
<li>This <strong>li is not</strong> affected.</li>
<li>This li is not affected.</li>
</ol>
</li>
<li>This li is not affected.</li>
<li>This li is not affected.</li>
</ol>
Upvotes: 0