Value calculation for CSS
I'd say it is because CSS just defines how something is displayed by the browser. There is no flow of information back to the style sheets, or to say it in other words: CSS is not dynamic.
If you know the height of an element and want to change it everytime the page is displayed you can generate a style sheet with PHP or other languages. Then you also know what's the half of the height and can set it also.
If you don't know the height it would be a dynamic change. The browser would have to render the page at first, then determine the height of the element and send it back to CSS. There the line-height is computed and altered in the rendered page. But maybe therefore the overall height of the element changes , too. Now the browser had to go back to CSS again and so on...
Just would not work. CSS is there to define the look of the page statically.
Get computed value of CSS variable that uses an expression like calc
Technically you cannot because the computed value is not static and will depend on other properties. In this case it's trivial since we are dealing with pixel value but imagine the case where you will have percentage value. Percentage is relative to other properties so we cannot compute it until it's used with var()
. Same logic if we use unit like em
, ch
, etc
Here is a simple example to illustrate:
let div = document.getElementById('example');
console.log(window.getComputedStyle(div).getPropertyValue('--example-var'))
console.log(window.getComputedStyle(div).getPropertyValue('font-size'))
console.log(window.getComputedStyle(div).getPropertyValue('width'))
console.log(window.getComputedStyle(div).getPropertyValue('background-size'));
:root {
--example-var: calc(100% + 5px - 10px);
}
#example {
font-size:var(--example-var);
width:var(--example-var);
background-size:var(--example-var);
}
<div id='example'>some text</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
What is calculated value for font-size
Your question is a little confusing, but I'll try to cover the details off as I think you're asking.
First, I think you mean the "Computed" value rather than the "Calculated" value. You also ask in a comment about the "Used" value, and to get a full picture we also need to cover some other values, the "Specified" value, the "Resolved" value and the "Actual" value.
Now taking the font-size
first, we have for the .myspan element
- Specified value = 220%
- Computed value = 18px * 220% = 39.6px
- Resolved value = 39.6px
(The resolved value forfont-size
is the computed value) - Used value = 39.6px
(Always the same as the computed value forfont-size
) - Actual value = about 39-40px
(The CSS pixels will be converted to device pixels. some other approximations may be made based on the available fonts and the closest renderable number on the device is used)
For the width
, things work slightly differently
- Specified value = 50%
- Computed value = 50%
(The pixel length is not known at computed value time because the layout hasn't happened at this step) - Used value = 200px * 50% = 100px
(The layout is done and the pixel value is determined) - Resolved value = 100px
(The resolved value forwidth
is the used value) - Actual value = about 100px
(As with font-size, the CSS pixels will be converted to device pixels and the closest renderable number on the device is used)
Now, what causes confusion is that when you use getComputedStyle()
in JavaScript, or inspect the "Computed Values" tab in the browsers' developer tools, you don't get the "Computed" values for the element - You get the "Resolved" values for the element.
For getComputedStyle()
, this is just an historical anomaly that exists for backward compatibility reasons. Why the developer tools also report the Resolved value, I don't know.
Performing calculations (calc) on data attributes in CSS (e.g. modulus)
Here's a simple JavaScript solution:
var pids = document.querySelectorAll('[data-pid]');
Array.prototype.forEach.call(pids, function(elem, index) {
elem.classList.add('pid-mod-' + (index % 4));
});
.pid-mod-0 {
color: red;
}
.pid-mod-1 {
color: orange;
}
.pid-mod-2 {
color: yellow;
}
.pid-mod-3 {
color: green;
}
<div data-pid="0">0</div>
<div data-pid="1">1</div>
<div data-pid="2">2</div>
<div data-pid="3">3</div>
<div data-pid="4">4</div>
<div data-pid="5">5</div>
<div data-pid="6">6</div>
<div data-pid="7">7</div>
can I calculate the value of CSS property of a dynamically changing div and use to calc() the value for positioning a sibling div in CSS?
Note: Javascript solutions are welcome but I need to know if this is achievable by CSS only? Also the con of Javascript is if user resizes the window in this case I need another eventlistener for this.
Simply, no. CSS alone will not be able to determine the position of an element in order to style an element. You will indeed need a dynamic solution using JS for this.
It sounds like you are writing your own tooltip library for your application. If this is the case, I recommend considering third-party solutions for this as they already have done much of the heavy lifting an often already address accessibility needs. Some I found, though have not used myself:
- Tippy.js
- Popper.js
- or if you're already using a UI toolkit, check if it is already built in. For example, Bootstrap already uses popper.js for this.
If you are determined to write your own JS for this you are correct in that you will need a resize event listener. Be sure to use a debounce function for this so you don't encounter performance problems.
Calculating fluid CSS element sizes using CSS using calc(px + vw)
You need to solve the equation Y = A*X + B
where in your case Y
is the width and X
is 100vw
So width: calc(A*100vw + B)
When 100vw = 1920px
you need width: 150px
so we have
150px = A*1920px + B
When 100vw = 375px
you need width: 110px
so we have
110px = A*375px + B
We do some math and we get A = 0.026
and B = 100.3
Your code is width: calc(0.026*100vw + 100.3px)
Also width: calc(2.6vw + 100.3px)
You can also write it as
--a: ((150 - 110)/(1920 - 375));
--b: 150px - 1920px*var(--a); /* OR 110px - 375px*var(--a) */
width: calc(var(--a)*100vw + var(--b));
body {
font-size: 18px;
}
.box {
width: calc(2.6vw + 100.3px);
height: 100px;
}
.box-alt {
--a: ((150 - 110)/(1920 - 375));
--b: 150px - 1920px*var(--a);
width: calc(var(--a)*100vw + var(--b));
height: 100px;
}
<div class="box" style="background:red;color:white;margin:10px;">
</div>
<div class="box-alt" style="background:red;color:white;margin:10px;">
</div>
Related Topics
How to Recreate Perspective-Origin Effect by Transforming Child Elements
Will CSS 3 Still Allow Omitting Final Semicolons
Disable Zoom on a Div, But Allow Zoom on the Page (An Alternate Div)
Textarea's Rows, and Cols Attribute in CSS
CSS Opacity VS Rgba: Which One Is Better
Align Right in a Table Cell with CSS
Can't Get Z-Index to Work for Div Inside of Another Div
Align Material Icon with Text on Materialize
Alternative for Nth-Child for Older Ie Browsers
Prevent a Pseudo Element from Triggering Hover
How Does CSS Computation for Background Percentages Work
How to Make Div Background Color Transparent in CSS
How to Convert .Svg Files to a Font