Im reading about optimal font sizing and layout sizing...and Im looking into em instead of px.
From what I understand, if I make the css like this;
html {
font-size: 16px;
}
body {
font-size: 1em;
}
It will force the browser to make 16px = 1em, and that will enable me to do width and height properties by calculating desired pixels/16, right?
Almost all browsers gave their default font size as 16px.
So if you simply set font-size:100% on your body tag then work from that you'll be golden.
Here's a good site that I use for calculating font-sizes from your base size:
http://riddle.pl/emcalc/
In the settings tabs simply change it to 16px and that's you set.
You are correct, and so is #Billy Moat.
You're not really gaining anything by explicitly declaring the 16px value on the HTML element - browsers tend to do that anyway.
Another trick that you can use is the "62.5%" trick.
If you declare:
body { font-size: 62.5% }
You can make further declarations in em's that map neatly to pixel measurements. e.g.:
h1 { font-size: 3em; /* equals 30px */ }
h2 { font-size: 2.4em; /* equals 24px */ }
.nav { width: 50.5em /* equals 505px */ }
That's because 10/16 = .625. So with this trick, you can rebase your measurements and not have to do the math later of dealing with a 16px base.
The only trick of this method is that once you declare a font size for an element, all children elements have to have their em values based on that parent's value (this is true of all relative units of measurement).
Related
When using rem units in Google Chrome (or firefox), the result is unexpected. I'v set up a page with the root font-size set to 10px to make it easier the translate a pixel based design to html/css.
This is my css. My expectation would be a page with one 500px wide box and if the screen is wider than 500px the background should turn red.
html {
font-size: 10px;
}
#media screen and (min-width: 50rem){
body{
background-color: red;
}
}
.test{
width: 50rem;
background: black;
height:100px;
}
But, despite both values being defined as 50rem, the results is a 500px wide box with the page turning red at 800px.
https://jsfiddle.net/tstruyf/puqpwpfj/4/
What am I doing wrong or why is this?
It's meant to work like this, it's just a little confusing if you don't know what's going on.
If you're not using rem in media query declarations then they are based off the root html base font size. If you don't declare this, then in most modern web browsers it's 16px.
As you have declared it as 10px a rem will be 10px throughout your code. Unlike em units, where it is based on the closest parent declaration size.
The confusion comes in that media queries declarations do not base themselves on the declared font-size that you apply to html and instead always use the default size - which as I said is 16px in pretty much all browsers.
That's why 50rem is coming out as 800px - 16px * 50.
Note, this is only for the declaration of the media query breakpoint, if you assign something to be 1rem tall inside the media query, then it will base itself on the base html size.
html {
font-size: 10px;
}
#media screen and (min-width: 50rem){ // 800px (uses base font-size)
div.somediv {
width: 50rem; // 500px (uses the declared html font-size)
}
}
You're not doing anything wrong, this is how rem in media queries are meant to work. As per the spec:
Relative units in media queries are based on the initial value, which
means that units are never based on results of declarations. For
example, in HTML, the em unit is relative to the initial value of
font-size, defined by the user agent or the user’s preferences, not
any styling on the page.
So any styling you apply to the base font size doesn't have an effect on the media query calculation.
Here's the relevant part of the spec.
If you really want to use rem and have them use a font-size basis of 10px, you could always write a SASS mixin to do the conversion for you. Other than that, it might be less confusing to stick with px for media queries.
The size of 1rem in media queries is not affected by changes to the base font size. But you could calculate the correct breakpoint yourselves. You can calculate the breakpoint in pixels based on your new base font size and the desired size in rems.
pixels = desired-rem-value * current-base-font-size
For example for a base font size of 18px and a breakpoint at 20 "rem":
20 * 18px = 360px
There are a few options how to calculate the pixel value:
1. calculate by hand:
html {
font-size: 18px;
}
/* For a breakpoint at 20 times your base font size*/
#media(min-width: 360px) {
...
}
2. Use calc():
#media(min-width: calc(20 * 18px)) {
...
}
3. Use a CSS prepocessor function:
(For example in scss or something similar.)
$base-font-size: 18px;
html {
font-size: $base-font-size;
}
#function media-rem($rem) {
#return $rem * $base-font-size; // $rem must be unitless
}
#media(min-width: media-rem(20)) {
...
}
Based on the rem CSS Specification:
When used outside the context of an element (such as in media
queries), these units refer to the computed font metrics corresponding
to the initial values of the font property.
So, in this case, which media query, rem refers to the initial values of the font property (Default browser's font-size = 16px).
When I tried to use em units with media queries I noticed that the unit is based on browser's default font size, not on the html root.
It working odd when I'm gonna to set 20em for element width when breakpoint is min-width: 20em. Both units in this case ar not equal because the element's 20em is based on the html font-size and media query is based on the default browser font size.
Is there a way to achieve the same size for both using em unit without defining additional, separate variable only for breakpoints (#bp-size: 16.250em)?
html {
font-size: 0.813em; // 13px (assume default browser font-size: 16px)
}
.box {
width: 1em; // 13px x 13px
height: 1em;
background-color: #000;
// Problem
#size: 20em;
#media screen and (min-width: #size) { // 320px (20 x 16px) why not 260px?
width: #size; // 260px (20 x 13px)
background-color: #f00;
}
}
<div class="box"></div>
I asked this question not long after yours. I finally found the definitive answer from the html-gods buried deep in the Media Queries page.
Relative units in media queries are based on the initial value, which means that units are never based on results of declarations. For example, in HTML, the ‘em’ unit is relative to the initial value of ‘font-size’.
It doesn't matter what you set in your html, media queries will always be set on the browsers initial font-size attribute.
This is very possible -- What you're looking for is rem rather than em:
#size: 20rem;
rem is relative to the root element, whereas em is relative to the current element. See W3 and TutsPlus for further information in this regard.
Hope this helps! :)
Is there any method to create a css tag which increases the font size? Something like:
<style>
p {
font-size: 100%;
}
lrg {
font-size: +40%;
}
</style>
<p>Hi <lrg>Tom</lrg>!</p>
In the above example, the default text size is 100% but the text size of that inside the tag is 140% (100+40).
Is there any way to receive similar results??
You can use em units:
span {
font-size: 1.4em; /* 40% bigger than the parent */
}
<p>Hi <span>Tom</span>!</p>
The correct way to do is the following:
<style>
p {
font-size: 100%; /* This is actually redundant as it does not change the font size */
}
.lrg {
font-size: 140%; /* 40% increase */
}
</style>
Then use it like this:
<p>Hi <span class="lrg>Tom</span>!</p>
Think about it this way: the percentages multiply and setting a value above 100% increases the previously set font size, while setting a value below 100% decreases the previously set font size.
Same goes for using em units. Use a number above 1.0em to increase and number below 1.0em to decrease font size.
In addition to the other answers, consider using font-size: larger. However, you cannot randomly invent your own new HTML tags. That's what classes are for:
/* Define a CSS class that makes the font larger */
.lrg { font-size: larger; }
<!-- Use a span tag with the new class -->
<p>Hi <span class="lrg">Tom</span>!</p>
A straight-forward css question. Let's say we have this styles:
body {
font-size : 16px;
}
p {
font-size : 0.875em; // relative to parent, 14px
line-height : 1em; //relative to this element, 14px
margin-bottom : 1em; //relative to this element, 14px
}
This will mean that <p>s will have a font-size of 14px, a line-height of 14px and a margin-bottom of 14px.
What I would like is the equivalent of:
body : {
font-size : 16px;
}
p {
font-size : 0.875em; // relative to parent, 14px;
line-height : 1em; // relative to parent line-height, 16px;
margin-bottom : 1em; // relative to parent margin-bottom, 16px;
}
The reason I want this is because I want to have a responsive font size which respects its baseline.
Technically, you could use the rem, though it refers to the font size of the html element (so you would need to use the html selector, not body, and let body inherit from html). However, browser support is limited.
So it’s a better idea to use the em unit, just taking into account of your other settings. If p has font-size: 0.875em, then to set a margin to a value that its the font size of the parent (calculating 1/0.875), you would use the inverse value: margin-bottom: 1.143em.
On the other hand, it is natural to regard the font size of the body element as the size of copy text, and p elements are normally copy text. So it would be more natural to set font-size of body (if you set it at all) to the desired copy text size. This would make things a bit easier.
If you always know your parent element's size and your child element's size, then I can offer you a solution with Sass.
#function em2baseline($font-size, $size: 1em, $base-size: 1em) {
$collector: ();
#each $s in $size {
$collector: append($collector, ($s / $font-size * $base-size));
}
#return $collector;
}
$font-size is the size of the child element, $base-size is a list of sizes relative to my $base-size (a list so I can use it with margin/padding shorthand), and $base-size is the size I want to make it relative to.
#debug em2baseline(2em);
// 0.5em
#debug em2baseline(2em, 1.5em);
// 0.75em
If you aren't into using Sass, you can still do the math on your own:
[size you want] / [child size] * [base size]
I was reading about rem units in CSS3, and was a little confused. If you use rem, do you still use em or does that replace it?
For example:
.selector {
margin-bottom:24px;
margin-bottom:2.4rem;
font-size:16px;
font-size:1.6rem;
}
or
.selector {
margin-bottom:24px;
margin-bottom:2.4em;
margin-bottom:2.4rem;
}
Just trying to figure out if rem takes the place of em, or if it's just another unit.
Rem is the em size for the root (html) element. That means once you define the html element's font-size, you can define all rem units relative to that.
For example:
html { font-size: 62.5%; }
body { font-size: 1.4rem; } /* =14px */
h1 { font-size: 2.4rem; } /* =24px */
Rem is supported in Safari 5, Chrome, Firefox 3.6+, and even Internet Explorer, but for older browsers you still have to use em, percent or px.
No, it’s a different unit. em is based on the font-size of the parent, while rem is based on the root font-size, which I believe is the font-size of the html element.
Rem is just one more unit, it doesn't replace em like em didn't replace pixel.
Oldish topic, but I think it needs some more clarity.
Both em and rem are relative units, but rem is always relative to the html font size (the “root” element) rather than the inherited font size.
Never use px, or pt for that matter, on the screen. By hard coding the font size, you ignore the user’s personal preferred font settings and make zooming less cooperative.
Both em and rem have a useful role to play. Neither is perfect for all occasions. Here are some examples:
Use rem to avoid compounding sizing:
ul#something li { font-size: 1.2rem; }
… or …
ul#something li { font-size: 1.2rem; }
The first one will result in nested lists having progressively larger sizes, since the em unit will inherit from a parent li element.
Use rem to set sizes independently:
article { font-size: .8rem; } /* article base font size */
article>h2 { font-size: 2rem; } /* … except for h2 */
And, of course you can use both:
div#something { font-size: 1.2rem; } /* based on html size */
div#something>h2 { font-size: 2em; } /* based on div#something */
Two years down the track, now, and we can use it, safely ignoring Legacy Browsers.