1

I am having trouble seeing why the following CSS code involving custom css variables fails to work as expected:

html

<ul class="grid">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>

css

.grid > *:nth-child(2n) {
    border-right-width: calc((1 - abs(clamp(-1, var(--columns, 1) - 2, 1))) * 5px);
}
.grid {
    --column-gap: 10px;
    --row-gap: 20px;
    --columns: 5;
}

Output:

enter image description here

jsfiddle

The problem is that every 2n item has a right border width, when by calculation the border-right-width should be zero (since --columns has a value other than 2 and 1 - abs(clamp(-1, var(--columns, 1) - 2, 1)) should evaluate to 0).

What am I missing? And how can the border-right-width calculation activate only when --columns takes the value of 2 and not otherwise (otherwise 0)?

2 Answers 2

2

As of now abs() is only supported by Firefox and Safari. Change abs(x) to max(x, 0 - x)

.grid>*:nth-child(2n) {
  border-right-width: calc((1 - max(clamp(-1, var(--columns, 1) - 2, 1),
     0 - clamp(-1, var(--columns, 1) - 2, 1))) * 5px);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Firefox also produces unexpected output even though it is supposed to support abs (chrome also fails but differently). Nevertheless I will try the max alternative and see.
1

To ensure that the border-right-width is only applied when --columns is exactly 2, you need to adjust your calculation. You can use a simpler check:

.grid > *:nth-child(2n) {
border-right-width: calc((var(--columns, 1) == 2) * 5px);

}

However, the equality check (==) is not supported in CSS calc(). As a workaround, you could use JavaScript to dynamically add a class or inline style based on the value of --columns.

If you want a pure CSS solution, check below:

HTML:

<ul class="grid" data-columns="5">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
</ul>

CSS:

.grid > li {
    text-align: center;
    padding: 30px 0;
    font-size: 20px;
    font-weight: 900;
    border: 1px solid #aaa;
}

/* Apply specific styles when --columns is 2 */
.grid[data-columns="2"] > li:nth-child(2n) {
    border-right-width: 5px;
}

.grid {
    --column-gap: 10px;
    --row-gap: 20px;
    --columns: 5;
}

Here, you manually set the data-columns attribute in your HTML to match the --columns value. Then, you use this attribute in your CSS to selectively apply styles. This method requires updating the HTML whenever you change the --columns value.

1 Comment

yes using js or data properties would work but I do not want that. Why do you think the clamp calculation fails when it should produce correct result in theory?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.