How to Use a Unitless CSS Variables and Later Add the Needed Unit

How to use a unitless CSS variables and later add the needed unit?

Use calc() and do a simple multiplication with any unit:

div{width:calc(var(--mywidth) * 1%);}

example:

:root {  --a:50;}
.box { width:calc(var(--a) * 1%); border:calc(var(--a) * 0.5px) solid red; background:linear-gradient(calc(var(--a) * 0.8deg),blue 50% ,green 0); padding:20px; box-sizing:border-box;}
<div class="box"></div>

CSS - how to specify unit of a calc()?

In the comments you mentioned variables. So the answer from here may be useful.

Use variable in calc and multiply it by 1 with the needed unit:

font-size: calc(var(--size) * 1rem);

Assign unit of css variable

You can do that by using the calc() function by multiplying your var which don't have px value by 1px as in example:

As this will transform the value to px at the end.

I searched a lot but I think there is no way to just add px to the var without calc().

:root {
--width: 200;
}

div.a {
width: calc(var(--width) * 1px);
border: 1px solid black;
}
<body>
<h1>Test</h1>

<div class="a">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit. Vestibulum volutpat tellus diam, consequat gravida libero rhoncus ut. Maecenas imperdiet felis nisi, fringilla luctus felis hendrerit sit amet. Pellentesque interdum, nisl nec interdum maximus, augue diam porttitor lorem, et sollicitudin felis neque sit amet erat.</div>

</body>

Calculate and Concatenate in CSS variables

You can use calc() in your CSS properties to calculate pixel and percentage units of measurement with variables.

box model

:root {
--size: 100;
}

.myElement {
background-color: lightgreen;
margin: calc(var(--size) * .2%);
padding: calc(var(--size) / 2 * 1px);
}

.myElement>span {
background: limegreen;
}
<div class="myElement">
<span>text</span>
</div>

Is it possible to add a (dynamic) unit to a unitless number in sass?

There's no sass native way to achieve your goals. The problem is that $unit is a string and in sass, like other languages, when you make operations with a string and a number, it automatically concatenates both and returns a string. And there is no native function that performs this operation, here's the reason of the creator of sass:

these functions would encourage more sloppy code than they do add expressive power.

More info about this topic here

Alternatives

So you can only use multiplication, as you've mentioned before or if you don't want to use multiplication you can use this function to convert unit strings into numbers:

@function length($number, $unit) {
$strings: 'px' 'cm' 'mm' '%' 'ch' 'pica' 'in' 'em' 'rem' 'pt' 'pc' 'ex' 'vw' 'vh' 'vmin' 'vmax';
$units: 1px 1cm 1mm 1% 1ch 1pica 1in 1em 1rem 1pt 1pc 1ex 1vw 1vh 1vmin 1vmax;
$index: index($strings, $unit);

@if not $index {
@warn "Unknown unit `#{$unit}`.";
@return false;
}

@return $number * nth($units, $index);
}

As you can see, it takes a number and a unit as arguments and it returns them as a length number. So in your case, you only need to change this declaration:

$united-value: #{$value}#{$unit};

By this other:

$united-value: lenght($value, $unit);

This is an idea grabbed from Hugo Giraudel's blog

When specifying a 0 value in CSS, should I explicitly mark the units or omit?

I argue you should also omit the units.

From a programmer's perspective, 0 == null == none == false, where 0px == 0px only.

Which means that if you specify a border width of 0 then no border will be there, but if you specify a 0px border, then a border of 0 px will be created (that's the idea behind it, in reality 0px gives the exact same result like 0).

Further Points

  • unit-less 0 makes it easier to read as it is easily distinguishable from normal unit'ed values.
  • It makes sense to remove the units as they have no point in being there (0 could mean size, color, etc.).

Conclusion: Omit the units in 0. They're not needed and confusing.

Why doesn't min() (or max()) work with unitless 0?

You need to add a unit to 0 otherwise it's confusing for the browser to handle the comparison between a uniteless value (a <number>) and a value with unit (a <length>) and the top property accept a <length> not a <number>

top: max(0px, 120vh - 271px)

To understand this, you need to follow the specification:

The min() or max() functions contain one or more comma-separated calculations, and represent the smallest (most negative) or largest (most positive) of them, respectively.

Then for calculations:

A calc() function contains a single calculation which is a sequence of values interspersed with operators, and possibly grouped by parentheses (matching the <calc-sum> grammar),

So the content of min()/max() is treated like the one of calc() then from the type checking

A math function can be many possible types, such as <length>, <number>, etc., depending on the calculations it contains, as defined below. It can be used anywhere a value of that type is allowed.

and

Note: Altho there are a few properties in which a bare <number> becomes a <length> at used-value time (specifically, line-height and tab-size), <number>s never become "length-like" in calc(). They always stay as <number>s.

You may get surprised but using top:0 is valid while top:min(0) or top:max(0) is not. To make them valid you need to add the unit.

But you can use opacity: min(0) for example since opacity accept a number as argument.

Worth to note that the same also apply to clamp() since it's equivalent to max(MIN, min(VAL, MAX))

Related: Why doesn't css-calc() work when using 0 inside the equation?

Using percents as multipliers with CSS calc()

If I'm forced to define two separate variables (Part B of the question), it appears I can do this:

:root {
--half-factor: 0.50;
--half: calc(100% * var(half-factor));
}

So that will make my application work and have the values ultimately depend on one value definition (here --half-factor). But if there is a way to pull off both use cases with a single definition, I'd be interested in knowing it. (I know that I can inline calc(100% * var(half-factor)) instead of using var(--half) but that's not what I mean by "single definition".)



Related Topics



Leave a reply



Submit