Converting number to px in CSS [duplicate] - html

I am trying to set a CSS variable with a number then I want to use it in my CSS as a percentage, while in other places I will need to use it as a plain number for some calc() operations.
Example
--mywidth:10;
div{width:var(--mywidth) + %;} --- should be ---> width:10%
is it possible?

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>

Related

Is there a good way to encode numbers in css classnames, to allow you to to target abitrary ranges with only CSS?

Is there a clever class naming scheme, that would make it easy to provide hooks for CSS styling on things based on the range of a numerical value.
A common example might be a progress bar which changes color at different percentages.
It will likely have the number available in some way, but no easy way in CSS to say "red up to 50%, then yellow above that, then green from 80% up. Many existing solutions will just generate 100 lines of CSS that each target a single number value with a pre-processor in advance and then work off a single class like .progress99 for 99% progress and if you want to target a range of 51 items, then you'd either use 51 classes, or (49 classes to invert the selection).
This is clunky but workable for a small number like 100, and can even be optimised a little for single use cases with sass mixins that would only use the minimum css required to match everything you need in a specific project and generate the boring bits.
But is there anything cleverer that you can do that would work for potentially any number in a classname with only CSS side changes to control which numerical range is targetted?
I'm assuming that if there is someone would have done it already, but also think that in most cases you can either:
a) add the logic to the server side and add a .success class or whatever when the number is above the required value
b) use JS to do the above logic on the client side.
c) use nth-child selectors to affect the children if it's the number of children that are relevant (though you can't target the parent with this trick)
so possibly it's just never been thought worth the effort, but is it actually possible?
Disclaimer:
you should probably be using javascript to achieve the desired results you're looking for. If you're using a percentage system as per your example this implies that you are almost certainly using javascript on the page already.
The CSS
you can use :nth-of-type(n) so for example of you want to target the 51st percentile you can do
.percentageBlock:nth-of-type(51) {
background-color: red; /* The 51% mark will be red */
}
Where you have 100 divs each classed as class='percentageBlock'. You can also do values above a certain criteria (ie 50% or more) by using the 50 + n syntax in the above.
.percentageBlock:nth-of-type(50 + n) {
background-color: blue; /* The 50% mark and all after it will be blue */
}
A note about nth-child is that it only works on elements not on classes. Please see This Answer Here for further details.
Example:
A few terse examples of what I describe above using the percentage chart analogy...
#wrapper {
width:100vw;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#wrapper > div {
width: 10%;
display:inline-block;
text-align: center;
padding: 0.5rem 0;
margin: 0;
box-sizing: border-box;
}
div#wrapper > div:nth-child(1),
div#wrapper > div:nth-child(2)
{
background-color: red;
}
div#wrapper > div:nth-child(n + 3){
background-color: green;
}
<div id='wrapper'><div>10%</div><div>20%</div><div>30%</div><div>40%</div><div>50%</div><div>60%</div><div>70%</div><div>80%</div><div>90%</div><div>100%</div>
</div>
Rather than "parsing" numbers values from attributes like <div class="progress99"> you'd better directly set numeric custom property like <div style="--progress: 99">. This gives you value you can use directly in any calc(var(--progress) ... ) expression in your CSS.
Then you can use this value for "offset" (animation-delay) of paused animation that defines states in keyframe ranges (for discrete states) or just keyframe points (for gradually changing states).
POC:
#keyframes progress_states {
/* "red up to 50%, then yellow above that, then green from 80% */
from, 50% { color: red; }
51%, 79% { color: gold; }
80%, to { color: green; }
/* ex. gradually changing something */
from { letter-spacing: 0; }
to { letter-spacing: .7rem; }
}
span {
animation-name: progress_states;
animation-play-state: paused;
animation-duration: 100ms;
animation-delay: calc(var(--progress_value) * -1ms);
animation-timing-function: linear;
animation-fill-mode: both;
}
<span style="--progress_value: 00">00</span> |
<span style="--progress_value: 55">55</span> |
<span style="--progress_value: 99">99</span> |
<span id="test">input below</span>
<p><input type="range" min="0" max="100" value="0"
oninput="
test.style.setProperty('--progress_value', this.valueAsNumber);
out.value = this.value;">
<output id=out>0</output>

Is there anyway to style html elements through html classes with variables?

I'm just curious to know if it is possible to have specific stylings based on the name of of a class.
For example, Bootstrap 4 has a helper class for margins and padding like:
<div class="m-t-1 p-a-0"></div>
This gives the div 1em of margin to the top, and removes padding from all sides.
I am sure they have pre-styled this class in their CSS to achieve this.
But I am curious if there is a way to use the class as a variable.
for example:
<div class="fs-x"></div>
where x can be any number, this class would then give the styling the font-size: x to the div.
Is this possible to do?
Thanks.
You can use a CSS pre-processor such as SASS or LESS to achieve this however it generates static classes within a specified range below is an example from the SASS documentation:
$class-slug: for !default
#for $i from 1 through 4
.#{$class-slug}-#{$i}
width: 60px + $i
Which emits this CSS:
.for-1 {
width: 61px;
}
.for-2 {
width: 62px;
}
.for-3 {
width: 63px;
}
.for-4 {
width: 64px;
}
All CSS classes must be explicitly defined. So every variation if X would need to exist in a .css file
you can use constant in css for example
$x = 10px;
img{
margin-bottom : $x;
}
but however you can declare variables with this way
:root {
--color-principal: #06c;
}
#foo h1 {
color: var(--color-principal);
}

Can CSS values changed relatively?

#foo{font-size:14px;}
Now #foo has 14px font size
#foo{font-size:$-2px} // Hypothetical code
Now #foo has 12px font size. (14px - 2px)
Is this possible by any means? To dynamically change the value of a selector.
You can use rem which will refer to the global font-size.
:root
{
font-size : 14px;
}
#foo
{
font-size : calc(1rem - 2px);
}
<div>
I am a 14px text according to the root font-size
</div>
<div id="foo">
I am a 12 pixel text according to the rem font-size
</div>
EXPLANATION
The rem will refer to the global css. So when processing (1rem - 2px), this is actually (14px - 2px).
1. Using calc() method
I don't understand what do you mean by dynamically changed. But to do relative calculation, use calc() method.
Example:
width: calc(100% - 80px);
2. Using preprocessor like SASS
You might also want to check Sass for preprocessing. One of the well supported features are, variables.
You can define variables and do some calculations.
$body-size: 200px;
body {
width: $body-size/2 ;
}
Here is a simple example I created: jsfiddle
Reference: SASS
3. Using jQuery
The OP mentioned about changing the sizes whenever the window size changed. One approach would be using jQuery
$(window).resize(function() {
var width = $(window).width();
var height = $(window).height();
$('#item').width(width);
});
4. Using vw and vh attributes
The OP mentioned about wanting to change the sizes according to the viewport in the comment.
vw and vh is relative to the viewport width and height respectively.
div.responsive {
width: 10vw; /* 10% of viewport width */
height: 10vh; /* 10% of viewport height */
background-color: black; /* Just to make it visible while testing */
}
My $ 2/100.
CSS as of now, doesn't allow cross-browser variables in truest of sense, but you may be interested in this CSS Variables Official Doc.
CSS not supporting variables, is one of the most important reason CSS Preprocessors exist. eg. SASS, LESS.
You can use font-size and then relative em to control some of the elements properties, but its somewhat whaky, and you will end up having to individually specify font-sizes on children elements.
.example {
font-size: 20px;
border-radius: .5em; // 10px (20*.5)
padding: 2em; // 40px (20*2)
}

use width inside of calc

I am trying to do something like this:
.my-style {
width: 50px;
margin-left: calc(50% - calc(width / 2));
}
Later I am changing the width to 90px and I want the margin grow accordingly.
It doesn't work. Is it possible?
The newest browser's SHOULD support it, I tried the following code.
This is a webkit example I made, so check it in chrome
CSS
p {
-webkit-var-a: -webkit-calc(1px + 3px);
margin-left:-webkit-calc(-webkit-var(a) + 5px);
}
HTML
<p>This text should have margin-left, but it doesn't</p>
FIDDLE
http://jsfiddle.net/uqE8b/
If you inspect the <p> element you can see that it DOES see the code as valid, it just doesn't do anything... So it seems that for now you have to use javascript, LESS or anything equivelent as it's still a experimental feature.
EDIT:
it DOES seem to work when you make the var a plain number:
p {
-webkit-var-a: 3px;
margin-left:-webkit-calc(-webkit-var(a) + 5px);
}
http://jsfiddle.net/uqE8b/1/
So to answer your question, yes this is possible, but I would not recommend it for now.
CSS
.my-style {
height:100px;
background-color:black;
-webkit-var-width: 50px;
margin-left: -webkit-calc(50% - -webkit-var(width) / 2);
}
FIDDLE
http://jsfiddle.net/ShsmX/
You can't do something like that with standard CSS, you should investigate an alternative such as LESS
Edit: I was wrong, CSS3 supports this if you use var() within calc():
.my-style {
width: 50px;
margin-left: calc(50% - (var(width) / 2));
}
I think should do it.
.my-style {
width: 50px;
margin-left: calc(100% - calc(width / 2));
}
Try like this, it worked wonder for me.

Height:100% is not considered

I would want to simulate the behavior of a table with div.
I have a struct of my layout divide into three columns:
div#wrapper {
width:800px;
float:left;
height:100%;
margin-top:7px;
text-align:center;
}
div#left {
width:167px;
float:left;
padding-bottom:50px;
margin-right:3px;
}
div#main {
width:454px;
float:left;
}
div#right {
width:167px;
float:left;
margin-left:3px;
}
wrapper is the container of three columns left,main,right
div "main" have a variable content so in some case is more long and in other case is very short. When the content vary,div wrapper is adapted and it's ok but left and right columns don't adapt to wrapper.
P.S Without doctype there is no problem, infact I set the height of left, main and right to 100% but when I insert transional.dtd , the height of div is not considered.
How can resolve this problem?
Sorry for my english!!
I agree with #Neurofluxation so let's see what I can find on Google:
100% Height Layout Using CSS
and
CSS Faux Columns
You could try to insert:
min-height: 100%;
as well, to cover yourself :)
I try to use
min-height:100%;
but I can solve the problem.
I read in different forum that is not possibile with xhtml fixed height:100% with a div, and that the only one method to solve this problem is to use JQuery?
you should use jQuery
<script type="text/javascript">
$(this).load(function() {
alert(document.documentElement.clientHeight + '+' + $(window).height());
if ($(window).height() - 250 > 300)
$('#content').css('min-height', '224px');
else
$('#content').css('min-height', $(window).height() - 250);
}
);
$(this).resize(function() {
if ($(window).height() - 250 > 300)
$('#content').css('min-height', '224px');
else
$('#content').css('min-height', $(window).height() - 250);
}
);
</script>
<div id="content" style="min-height:350px;">
</div>
just change numeric digits of hights.