How to avoid fraction rem value to be less than 1px? - css

Let us suppose we have a project where font size is calculated dynamically using calc CSS function. Moreover we want to have a border which width is going to be expressed in rem (relative to font size).
In some cases pixel size of the border width is less than 1px therefore it's impossible to render.
How to set the border width to be not less than 1px?

Generally, setting a min() isn’t fully supported in most modern browsers, but looking at the CSS 4 spec; there are functions for max and min.
https://www.w3.org/TR/css-values-4/#calc-notation
Example:
.type {
/* Set font-size to 10x
the average of vw and vh,
but don’t let it go below 12px. */
font-size: max(10 * (1vw + 1vh) / 2, 12px);
}
Alternatively you can use a CSS preprocessor or perhaps even a post processor to min the value from the calc;

Related

How to work with percentage rates instead of px rates in responsive design?

So I've applied for a front end job few months ago and got interviewed and they've given me a test task. One of the requirements of this task is that they want the website to be infinitely variable scalable like this one.
To quote the task description it says:
If you scale down the browser window, everything fits perfectly because everything scales in the same ratio. For that you have to work with percentage rates instead of px rates.
Now, my problem is I am a PX guy, I mean I build all of my projects using px and not that confident on using different unit such as em, vw, rem etc. Well I've use other unit like vh but I don't use it often.
So what's the best way to learn or any roadmap that'll help me to migrate from px to percentage. Should I just use tools like px to em?
Practice does make perfect
The short answer is... Start practicing using percentage-based units as that's how you'll learn the little catches. This is a good career move anyway as the idea of matching pixels to a design was crushed long ago with HiDPI screens, mobile devices, etc all rendering pixels differently.
Getting Started
Practically, you need a place to start and that means learning a few new CSS tools.
First
Use rem as a substitute for pixels.
Unlike an em that's relative to its parent font-size, a Rem is relative to the font-size of the root element (usually body) which means its GLOBAL. You can use rems everwhere (font-size, margin, padding, position, etc) and they're ALL based on the root size.
So let's say the root font size is 16px (typical browser default). That means 1rem = 16px. Now a 16px base isn't overly useful when you're doing math in your head. Jonathan Snook wrote about why this works years ago but the basic formula is set the base font size to 62.5% (of 16px) this means that 1rem = 10px and it's much easier to do the math.
Here's what that looks like in code:
body {
font-size: 62.5%;
}
h1 {
font-size: 2.4rem;
/* 2.4rem = 24px */
}
p {
font-size: 1.2rem;
/* 1.2rem = 12px */
}
.padding-left {
padding-left: 2rem;
/* 2rem = 20px */
}
You get the idea...
Fun tip: once you like the layout you can change the body font-size and make everything bigger or smaller. This is useful for things like a small screen where you want the fonts to be a bit larger
Next
CSS Calc() Is your friend. It's designed to help you do math operations on mixed unit values. For example, the browser can then do this type of math: 33.33% - 200px.
.element {
width: calc(33.33% - 20px);
/* maybe you need responsive columns with 10 px of padding on either side */
}
Finally
Start doing all your layout in percents. For example instead of a 3 column layout set to 300px wide (not responsive). You should make them 100/3 or 33.3333333% wide. Percents like this are always based on the parent so 100% = parent's width (regardless of the parent's units).
As a side note, I rarely need to use vh/vw, not because they aren't useful but in general, elements overflow their window in very predictable ways and percents are easier to wrap your head around.
vw and vh are going to be your best bet if it needs to be a percentage of the screen. rem and em are still relative to a starting point (i.e. body { font-size: 16px; } and scaled from there. vw and vh do have some issues on smaller device screens though, but it looks like your demo website has this issue. You can fix this with media queries, but it doesn't look like your example did, it "infinitely" scales as you mentioned.

Dynamically convert em to px inside of css?

I need to know the current em, based on the context, inside of a css style sheet. Is that possible?
I want to calculate the number of pixels for two items: one is in pixels and the other is em:
--item-min-width: 250px;
--gap: 3em; (note: this might be different and is not known until runtime)
--max-number-items: 3;
Now I need the total width of those three items, plus the gap. Something sort of like this (which of course won't work because I can't add pixels (item-min_width) and em (gap)):
#media (min-width: calc(
var(--max-number-items) * var(--item-min-width) + var(--gap)
))
The goal is to convert the gap (3em) to pixels dynamically. Is it possible to figure out the current em of an element?
You don't need to convert units, calc can handle that:
calc(100% + 10px)
calc(2rem - 1%)
calc(var(some-var) + var(another-var))
https://developer.mozilla.org/en-US/docs/Web/CSS/calc
To get the em value in px. Set default font size for the body (browsers have the default font size of 16px).
EM value compound with nesting of elements, refer the MDN docs(link given below).
So, let say you have set the default font size of 16px.
1 em = 16px.
Now you have a gap of 3em. So 3*16px = 48px.
3*250px + 48px = 798px.
Please have a look at this article from MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/font-size#Ems
and this article from w3schools(Set Font Size With Em): https://www.w3schools.com/css/css_font.asp

CSS height in terms of line-height

Using CSS, how can I size a box's height in terms of its (or its parent's) line-height?
This would allow easily making regions of text an exact multiple of a number of lines, e.g. to allow showing exactly three lines.
I don't want a javascript solution as those are generally slow and interact poorly with dynamically re-rendered layouts.
Edit: The line-heights in my case are specified in unit-less numbers, as recommended on MDN, so it'd be handy if line-height units weren't required to get this to work.
I'm not sure I've entirely understood the question, but couldn't you just use relative units - ems?
If the line height is, for example, 2ems (or unitless) and you want the total height of the box to be 3 "lines" high (presumably not taking into account padding) then you could set the height to be 6ems. This way, the line height is flexible based on your base unit (font size) and the height will also be fluid using the same base unit.
Here's an example:
.myBox {
line-height: 2; // this will be twice the value of the font-size
height: 6ems; // equivalent to 3 lines high
To achieve the same thing in SASS you could write:
$lineheight: 2; // this value can be unitless or a unit like ems, px or percentage
$numberoflines: 3;
.myBox {
line-height: $lineheight;
height: $lineheight * $numberoflines;
}
This would have the flexibility for you to move your variables into a settings file so that you (or someone else) can easily alter the values without having to find all the selectors that use the variables.

EM's for line-height

I would like to convert my new website from pixels to ems. My question is, should I also apply ems to my text line-height property?
Assuming that “converting to ems” means using the em unit for font-size, then you should set line-height in a manner that also adapts to the font size. The two properties are closely related, and if you set one of them in em and the other (e.g.) in px or pt, then the page will break if the font size is changed. So it would work against the very idea of “using ems” to use essentially different units for essentially connected properties.
For example, if you set font-size: 1.5em and line-height: 18px, then things will depend on the font size of the element’s parent and may go very wrong if that size is much smaller or much larger than expected.
Whether you use the em unit or a pure number is a different issue. Using just a number, as in line-height: 1.2, is primarily equivalent to using the em unit, as in line-height: 1.2em. But there is the difference that when line-height is inherited, it is the pure number that gets inherited, not the computed value.
For example, if an inner element has twice the font size of its parent, then the inherited value 1.2 means that 1.2 times its own font size is used, which is OK. But if the parent had line-height: 1.2em, then the child would inherit a value that 1.2 times the parent’s font size – which is much smaller than its own font size.
for more explanation end examples see line-height # Mozilla Developer Network
line-height can be set in px, em's, every unit will fit.
line-height works best and future proof if you use a factor/multiplier, meaning no unit, but only a number that is multiplying your font-size.
.foo {
font-size: 1.3em; /* based that 1em == 10px */
line-height: 1.3; /* 16.9px line-height */
}
So, Yes, you can, to answer you question: no you should not.
just go for the factor based line-height to be future proof.
It is recommended to use the unitless number for line-height (to prevent inheritance issues). The computed line-height will then be the product of the unitless value multiplied by the element's font size.
It may be more convenient to use the font CSS shortcut, like so (example taken from the Mozilla CSS docs):
div { font: 10pt/1.2 Georgia,"Bitstream Charter",serif }
A good example of why the unitless value is preferable is given here: Prefer unitless numbers for line-height values.

Isn't it okay to define relative font-sizes for child elements when the parent element uses Pixels (px)?

1) I came across THIS ARTICLE today, which states:
The most popular method in working with em values is to set the
font-size on the body to 62.5%. Because the default browser font-size
is 16px, this makes it 10px (without hard-setting it to 10px, which
wouldn't cascade).
What I just quoted (above) essentially means that, I CAN'T set the font-size of the body to 10px directly and then define the font-sizes of other elements in em or % based on that. Isn't it what it meant, or did it get it wrong?
For example, I have body {font-size: 10px;}. And now I set p {font-size: 1.4em;}. Doesn't it mean, the font-size of p is actually 14px? Isn't that cascading? (or is this going to cause me problems on other devices? - - mobiles, tablets, etc.)
2) For any given element, defining its font-size as 1.8em or 180% makes no difference what-so-ever, right? I mean precisely, for an element (whose size we are defining), an em is essentially a decimalized form of %, isn't it?
EDIT: 3) 'em' is often referred to as a very mobile-friendly sizing unit. How about %? Is it just as good, considering Q2?
1) The article is wrong when it says that font size in pixels “wouldn’t cascade” (and this reflects a misunderstanding of what the cascade is). You can use em or % for the font sizes of inner elements if you like. You would be setting font size in pixels for them, just indirectly. The flexibility you get is that things will be easier if you later change the base font size set in pixels. On the other hand, em or % settings may imply rounding that will be treated differently by different browsers in some cases.
If you set body {font-size: 10px;} p {font-size: 1.4em;}, then (unless other style sheets interfere), the font-size of p will be 14px. But this has nothing to do with the cascade. It’s a consequence of basic definitions for units and font-size.
2) For font-size, 1.8em and 180% have the same meaning by definitions. There used to be reasons to favor one or the other, due to browser bugs with the other, but these considerations have lost significance.
3) Yes, using % is just as good.

Resources