We have now started using calc() in css, for setting widths on a result of calculation.
For example:
<div id='parent'>
<div id='calcWidth'></div>
</div>
#parent{
width:100px;
}
#calcWidth{
width:calc(100% - 3px);
height:100px;
background:red;
}
I know how calc() works, but I just want to know what is returned in css, in the place of calc(100% - 3px); in the example given above.
Whats my confusion?
In the above example width:calc(100% - 3px);
say the 100% width is actually 100px, which will be determined at runtime by css.
So the calculated width will be 100px-3px=97px 97px and if you convert it to % 97% right?
But now, there are two possibilities
97px is returned, which is set as a width.
97% is returned, which is set as a width.
My Question is:
In both cases now the width shall be set to 97px, but what is
returned as a result of width:calc(100% - 3px);, 97px OR 97% ?
you can also see this fiddle:
http://jsfiddle.net/8yspnuuw/1/
EDIT: please read
See friends: Take a simple example:
<div class='parent'>
<div class='child'>
</div>
</div>
.parent{
width:200px;
}
.child{
width:20%
}
I know the width of child will become 160 px when it is rendered.
okay! but thats not what is set in css right? css sets it in %, it is
just rendered in pixels.
So similarly, using calc, does it return % or pixel
Or to explain my question, read BoltClocks answer, what is the computed value, (and not the used value, i know that is in pixels)
The spec does not define very strictly what the computed value of a calc() expression is, however it does say that percentages are never calculated as part of the computed value. How exactly this value is represented is left as an implementation detail.
If you see a pixel length instead of a percentage, then that length is the used value, not the computed value, because the pixel value can only be determined after calculating any percentages and laying out elements.
Note that getComputedStyle() may return results that are inconsistent with the CSS definition of "computed value". This is one of many unfortunate consequences of browsers doing their own thing back in the 90s.
The rendered widths are in pixels.
Whatever the pixels size of the calcWidth div is, the value 3 is reduced from it..for example if the width of parent is 200 the calcWidth div's width will be 197px. so it is px and not %
Demo
document.getElementById('calcWidth').offsetWidth;
CSS does not support dynamic values (bedides simple percentage values like width: 100%;). That means the 100% within calc() are converted one time initially to px and not continiously.
That already answers your question. The %-value gets converted into px end you end up with 97px. You can confirm that with window.getComputedStyle() or by taking a screenshot and measure it.
calc() does not have a computed value; it occurs at time of render -- that is why you can mix units.
Related
I would like to know if there is a CSS command allowing to increase the font size when the viewport width becomes smaller (like a reverse clamp method).
In fact, I want to do the opposite of what clamp does (as the first entry is the MIN value).
I searched on internet without success.
Thank you in advance for your feedback.
You can use calc to subtract from a font-size based on the width of the viewport which will give you the inverted scaling you desire.
You can then still use clamp as desired with a min/max value.
Run the snippet below as full page.
h1 {
font-size: clamp(10px, calc(100px - 5vw), 100px);
}
<h1>Heading 1</h1>
Is there a way to resize a container to a percentage of its own content?
I'm having a tricky issue relating to scaled content. Doing a transform: scale(...) on something works as far as having it display as I'd like, but unfortunately, the content still has the same effective size of the original content. This is problematic when content needs to flow below the scaled content without vertical spacing.
For example, given this HTML:
<div class="scaled-preview">
<div class="content">...</div>
</div>
<div class="stuff-below">Stuff below</div>
...and this CSS:
.content {
transform: scale(0.4);
width: 250%; /* Inverse of the scale */
}
....stuff-below is spaced below it as though it was not scaled.
You can see this in this JSFiddle.
The size of the content being scaled is unknown, but the scale factor is known. Is there a way I can have .scaled-preview set to a height that is a percentage of its own content?
This might not be quite the solution you're looking for, but it may solve your problem in an unusual way.
By the time the browser is calculating transform information, the layout is sadly solidified, so I wasn't able to think of a way to have the content height reflect the transformed height. So, I tried working off of font-size instead. It transitions just as well, and you can even size elements off of it using em values. The only downside is, I had to specify a particular width: xxem value so that the varying font-size would not cause line breaks in the middle of the transition.
https://jsfiddle.net/07c7s83y/
I come across width: calc(25% - 20px + 5px);
I couldn't find any answer via google. I wanted to know how to get the width to be 410px for three boxes in each row, because right now it returns me 4 boxes in smaller width than 410px.
Any help or insight will be appreciated.
This method resolves the entire expression into a single value and then applies that to the element.
The thing you're trying to do would first calculate the 25% of the parent element as an integer value and then it would move on to the next operand. Then would calculate the result and will apply.
I think, you need to lessen down the parent element's width property. Then you'll see three checkboxes with a width of 410px.
Secondly, you can also try to make sure the expression is accurate while calculating the result for the width.
Try this fiddle: http://jsfiddle.net/afzaal_ahmad_zeeshan/D6sQ5/ To see, how calc() method works.
Example:
<style>
div {
position:absolute; left:auto; right:auto; width:auto;
margin:0; padding:0; border:0;
}
</style>
<div id="containingBlock">
foo
<div id="inner">this is my text</div>
</div>
To determine the widths of both divs, we need the shrink-to-fit algorithm in http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width *
Let's start with #inner:
get the preferred minimum width
this
is
my
text
|----| preferred minimum width
get the preferred width
this is my text
|---------------| preferred width
compare both to available width:
computed width = min(max(preferred minimum width, available width),
preferred width)
Easy. But what is available width? Since we got no margins/paddings/borders, it's simply the width of containingBlock. But now we get an infinite loop, since the same algorithm applies again:
get the preferred minimum width of containingBlock
foo
+-------+
| inner |
+-------+
|--?????--| preferred minimum width
In other words: to get the width of inner, we must know the width of containingBlock and vice versa.
In reality, it looks like browsers just assume available width = 0 in this case: http://jsfiddle.net/pxvJJ/6/.
But this is not covered by the specs, or am I missing something obvious?
* (note that this spec has not yet been superseded by CSS3)
If we read carefully through the specs, we'll find that
CSS 2.1 does not define the exact [shrink-to-fit] algorithm.
It's supposed to be
similar to calculating the width of a table cell using the automatic table layout algorithm
which, in turn, is implementation-dependent.
So, the above example shows that excluding #inner from the calculation of containingBlock's preferred minimum width may be a good idea when implementing a straight-forward algorithm, and we'd end up with this:
|---| preferred minimum width
foo
+-------+
| inner |
+-------+
|--?????--|
which is probably what browsers do.
That being said, the question is: Which elements do actually contribute to containingBlock's preferred minimum width?
Let's see what happens if #inner has position:static; width: auto. This case is even harder. Again, the specs give the constraint
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
with no shrink-to-fit allowed this time. And, again, it cannot be solved. Or can it? Funny enough, it can! Let's see what actually happens: http://jsfiddle.net/pxvJJ/12/
Apparently, the statically positioned divs are treated differently. So I suppose the algorithm to determine width of containing block goes like this:
determine the preferred width of all contained block boxes in normal flow.
set width of containing block = maximum of those preferred widths
calculate the width of all contained boxes, now that width of containing block is known
I am still confused as to why (all) browsers do this. There seems to be no reason for treating absolutely positioned elements differently in this regard.
I need to make ui controls panel, that has 100% width and gradient background. UI elements on this control panel should have width 1000px and should be centered.
For a moment i have two elements:
panel (width 100%, gradient background), global wrapper
panel-wrapper (width 1000px, transparent background), is placed inside "panel" element, contains UI elements.
It works brilliant in all browsers i need, but i really don't like to use two HTML elements, when logically it should be just one. Perhaps it is possible to have one element "panel" with fixed width (1000px) and auto-padding, that will cover all free space to the left and to the right? (i've made an image to show it if my explanation is crazy :))
It is possible?
You could potentially use the calc() function, though it isn't highly browser compliant.
Here is a quick example and more information on compatibility and usage can be found here.
*I made the example in Firefox, didn't test it elsewhere.
Just for a quick code example, the following shows one solution:
div {
width: 100px;
background-color: blue;
height: 100px;
padding-left: calc(50% - 50px);
padding-right: calc(50% - 50px);
}
The challenge is you can't really combine percentages and fixed widths with padding in the traditional sense, since the padding is added to the total width.
If the total width is 100%, and you want the content in the center to be 500px, you can't calculate the padding.
With CC3, though, you can use the box-sizing to change 'where' the padding is placed in the box model.
http://www.css3.info/preview/box-sizing/
Alas, I still don't think that will give you want you want simply due to there still being an unknown variable in play (the width of the container that the 100% width object is in).
In the end, we can sometimes over think these solutions in the name of over-optimization. IN this case, an extra div seems perfectly acceptable and, likely, the proper solution.
Why padding ?
You could set left and right margins to auto and that would make the div centered..
So just set
.panel{
width:1000px;
margin:0 auto;
}