The CSS unit rem is short for “root em”. When used in CSS 2rem evaluates to “two times the font size on the root element” which in an HTML document is two times the font size on the HTML element. I know that I can change the font size on the HTML element by specifying it in e.g. html { font-size: 10px; }. But does it make any sense to do so using rem units? What does it even mean? Does the spec say?
If font-size is not specified, browser will use the default size (which is in most cases 16px, but I can't find it being specified anywhere in the CSS specification).
Now what using rem in root element will do is using that default value and multiplying it, 1rem = 16px, 2rem = 32px.
The spec seems to confirm that: https://www.w3.org/TR/css-values-4/#rem
rem unit
Equal to the computed value of font-size on the root element. When specified on the font-size property of the root element, the rem units refer to the property’s initial value.
I wouldn't say it makes any sense, since relying on browser's default values in CSS isn't necessarily a good idea, but if you want to multiply the browser's default font size you can.
Related
Let's say that end user has issues reading smaller text, so they've set their browser to default to 20px. If I set the rem size like this:
html {
font-size: max(1rem, 2.5vh);
}
Will it override their preference, or would it set "rem" to their preference (20px, in this case)? I don't want to break accessibility, but also want to scale the font with the screen-size. It seems to work on my end, but I want to be sure this is the best method.
"rem" refers to computed value of font-size of the root element, so the result of the font-size: max(1rem, 2.5vh); setting.
1rem applied to the font-size of the root element = 1em, so the rem size is the result of max(20px, 2.5vh) if the user has set the default to 20px.
To cite MDN on the <length> unit rem
rem
Represents the font-size of the root element (typically <html>). When used within the root element font-size, it represents its initial value (a common browser default is 16px, but user-defined preferences may modify this).
I have a simple question, where do you declare the base size that rem is calculated from?
<body>
<h1>Something</h1>
</body>
I can see that the font-size is <body> is set to 16px and the <h1> is set to 3rem, yet the font is rendering at 30px when I'd expect 48px. Can any parent redefine the base?
rem
Represents the font-size of the root element (typically <html>).
When used within the root element font-size, it represents its initial
value (a common browser default is 16px, but user-defined preferences
may modify this).
Source
In other words, change the font size of your html element, and the calculation base for rem will change.
Example:
<html style="font-size: 10px">
...
</html>
rem units are based on the font-size of the html element, not the body element. The default size is usually 16px on html, however that's not guaranteed, and users can change that default value. A common practice is to manually set the font-size explicitly on html, usually to that 16px value, and then use rems in other places to set the final display value.
However, that practice has accessibility problems for when users want or need to increase the default font size, so you should design your pages and layouts so that they can adapt to different sizes.
From https://developer.mozilla.org/en-US/docs/Web/CSS/font-size:
rem values are relative to the root html element, not the parent element. In other words, it lets you specify a font size in a relative fashion without being affected by the size of the parent, thereby eliminating compounding.
Just set the font size for the html element:
html {
font-size: 10px;
}
You are setting the root font size when you do this so the rem measurement will be influenced by this when setting a font size.
To add a best practice to previous answers: root font size should be expressed as a percentage.
html {
font-size: 110%;
}
This practice scales the font relative to the users system/browser settings. Your site will be consistently sized up/down compared to other websites. (assuming those websites also follow best practices).
Even more respectful to the user is to not touch the root font size at all so that they have a consistent reading experience across websites and can reliably use accessibility settings.
Look at this fiddle:
function toggle(event) {
var element = document.getElementById('changeme');
element.innerText = element.innerText ? '' : 'some text';
}
button = document.getElementById('button');
button.onclick = toggle;
#changeme {
min-height: 1em;
outline: 1px solid red;
}
<input id=button type=button value='Toggle content'>
<p id=changeme>dynamically changing content
<p>This should not move (up and down)
I have a text element there (it is a <p>, but could be a <div>) which I sometimes set to be empty. (Use the button to toggle between empty and some content.)
What height does this element with a line of text have? I want a generic answer so I can set its min-height to that value so that the element doesn’t collapse when empty. I thought 1em is what I’m looking for, but 1em seems to be the size of letters like “W” without the space below the baseline for letters like “g”.
I’m looking for a neat trick to give the possibly empty element a constant height, without putting into it. (At the moment I use 1.5em.)
The exact calculation of heights of lines is complicated (see CSS 2.1 section 10 Visual formatting model details), but in a simple case like this, the height is determined by the line-height value when the element is not empty. When it is empty, the height would be empty, but the min-height setting forces the height to the font size (1em).
The initial value of line-height is browser-dependent, and it is expected to depend on the font, too. The default is in practice always larger than the font size. This explains what happens here.
To keep the height constant, it is best to explicitly set its line-height and to set min-height to the same value, e.g.
#changeme {
line-height: 1.25em;
min-height: 1.25em;
}
Note: The em unit means the size of the font, which is by definition the height of the font. This is a reference quantity and does not normally correspond to the height (or width) of any letter; the height of most letters is smaller than the font size (though this varies by letter and by font).
The default line-height is normal (valid CSS value for that property). You can’t set min-height to that value unfortunately.
Apart from normal, line-height can have fixed length values (which are of no interest here) or factors which work relative to the font-size. The numeric equivalent of normal is not just browser dependent, interestingly. It commonly ranges between 1.0 and 1.5 (without unit) for different font faces and font-sizes!
So set the min-height to something beautiful between 1em and 1.5em. Then set line-height to the same value to make sure it is actually the same.
Note that for line-height a value with em-unit or unit less mean the same: the former is a fixed length relative to the current font-size and the latter is a factor relative ... to the font-size.
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.
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.