Using N Inside Calc

Using n inside calc

You can't, as mentioned by @SLaks. But this can be solved by placing each next element inside the previous one.

See with divs:

div {  margin-left: 46px}
<div>test  <div>test    <div>test      <div>test</div>    </div>  </div></div>

Is there a way to use the n value in :nth-child(n)?

CSS doesn't have support for variables. You could use Less/SASS loops and define it for n up to some value, but that would output almost the same CSS multiple times. Here is Codepen example.

SCSS code to support up to 10 cards:

$n: 10;

@for $i from 1 through $n {
.card:nth-child(#{$i}) {
position: absolute;
left: 10px * $i;
top: 10px * $i;
}
}

But are you sure your approach is correct? Maybe you want to take a step back and look for a different approach. Because this still doesn't scale dynamically, you'll have to predict or limit n to some value. If you were to pick large n, it would result in a big CSS file, which equals longer load times.

Use css counter in calc

The Question Can I use the counter(skill) inside a calc()

No. You can't.

The calc function does not permit the use of counter functions as its components. From the specs here - https://www.w3.org/TR/css3-values/#calc-notation:

Components of a
calc() expression
can be literal values or
attr() or
calc()
expressions.

There have been many requests for this but always declined. The underlying reason seems to be that the counter() function represents (outputs) a <string> and hence cannot be used directly in calc. Moreover, the counters are considered very expensive for the browsers.

Reference: https://lists.w3.org/Archives/Public/www-style/2016Aug/0082.html

However, there have been proposals for adding a counter-value() function which would return the value as integer and could be used in calc. See here: https://drafts.csswg.org/css-lists-3/#counter-functions (Scroll down to see Issue 4).

So as of now, you cannot use counter inside of calc and the counter-value does not exist yet.

CSS3 calc with variables

Nowadays all major browsers support calculated CSS values with custom variables, via:

  • calc(...)
    • Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/calc
    • Browser support: https://caniuse.com/css-variables
  • var(--...)
    • Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/var
    • Browser support: https://caniuse.com/calc

Example

.somebar {    /* I define the initial value of "--mydepth" */    --mydepth: 1;    width: calc(var(--mydepth) * 50px);        height: 50px;    background: green;}
.level1 { --mydepth: 2;}.level2 { --mydepth: 3;}
<h3>Example of: calc(var(--mydepth) * 50px)</h3><div class="somebar"></div><div class="somebar level1"></div><div class="somebar level2"></div>
<h3>Expected result (if supported by browser)</h3><div class="somebar" style="width:50px"></div><div class="somebar" style="width:100px"></div><div class="somebar" style="width:150px"></div>

How can I assign the value of a css calc() to a css-variable, and not have it delay the calculation until the css-variable is used

I found a "perfect" work around!.

The solution to this is to use the 'resize' event to read the size of the element you wanted use 100% on using getBoundingClientRect(); and using the width returned to set the "calc" as width px - whatever

So for the example in the question I would use this code

_resize() {
if (this.resizeInProgress) return;
this.resizeInProgress = true;
requestAnimationFrame(() => {
const container = this.shadowRoot.querySelector('.flex');
const bound = container.getBoundingClientRect();
container.style.setProperty('--div-width', `calc(${bound.width}px - 10px)`);
this.resizeInProgress = false;
});
}

I bind that function to this in my custom element constructor

this.resizeInProgress = true;
this._resize = this._resize.bind(this);

and this in the connectedCallback do

window.addEventListener('resize', this._resize);
this.resizeInProgress = false;

and in my disconnectedCallback remove it again with

this.resizeInProgress = true;
window.removeEventListener('resize', this._resize);

I retain the calc() function because in my real life cases as the amount subtracted is in "em" units

Why does this calc() function not work in transform scale?

You have two issues. The first one is about the formula without scale:

calc(0.75 + (0.3 - 0.75) * ((100vw - 320px) / (780 - 320)))

This is invalid because you are adding a number (0.75) with a length ((0.3 - 0.75) * ((100vw - 320px) / (780 - 320)))

At + or -, check that both sides have the same type, or that one side is a <number> and the other is an <integer>. If both sides are the same type, resolve to that type. If one side is a <number> and the other is an <integer>, resolve to .ref

The second issue, is that scale only take a number so you need to correct the formula to transform the second part into a number by removing any kind of unit (vw,px,etc).

Basically, what you want to do cannot be done this way because you have no way to convert your (100vw - 320px) to a number unless you consider using some JS as this is beyond CSS. Even with JS you will need to define what is the logic behind transforming a pixel number to non-pixel number.


Using the same formula within right and with percentage will work fine because:

If percentages are accepted in the context in which the expression is placed, and they are defined to be relative to another type besides <number>, a <percentage-token> is treated as that type. For example, in the width property, percentages have the <length> type. A percentage only has the <percentage> type if in that context <percentage> values are not used-value compatible with any other type. If percentages are not normally allowed in place of the calc(), then a calc() expression containing percentages is invalid in that context.ref

So in this case percentage is allowed to be used with right because we can resolve it thus the forumla will be valid because at the end it will be something like A% + Bpx.

Calc of max, or max of calc in CSS

min(), max(), and clamp() are finally available!

Support starts in Firefox 75, Chrome 79, and Safari 11.1 (clamp is available in Safari 13.1).

min() and max() take any number of arguments.

clamp() has syntax clamp(MIN, VAL, MAX) and is equivalent to max(MIN, min(VAL, MAX)).

min() and max() may be nested. They can be used in calc() as well as outside of it, they also may contain math expressions, that means you can avoid calc() when using them.

Therefore the original example can be written as:

max-width: max(500px, 100% - 80px);


Related Topics



Leave a reply



Submit