I'd like to try and convert my designs from pixels to ems. I've read so many tutorials that... and I'll leave it right there.
Starting with this as my base:
body {
font-size: 62.5%;
line-height: 1.4;
}
... now this is where I get lost...
Should I be defining my font-size like this:
div#wrapper { font-size: 1.5em; }
... or like this:
blockquote, li, p, dt, dd, etc { font-size: 1.5em }
And then the next thing I don't really understand is where ELSE should I be using ems in addition to font-size and line-height? I will be using a fixed-width layout using 960.gs.
line-height: 1.4em;
Probably isn't what you want. The line-height will stay at the same computed height for the size of an ‘em’ on that element, even when you change the font-size on a descendant element.
line-height has a special case where it allows a unitless number:
line-height: 1.4;
Which makes each descendant line-height depend on its own font-size rather than the ancestor's.
Should I be defining my font-size [on a wrapper or on many element types]?
Well that rather depends on what you're trying to do. With relative font-sizes it is generally best to keep the number of declarations down to a minimum, because they nest: that is, with your blockquote { font-size: 1.5em; }, if you put a blockquote inside a blockquote you'd get a font-size of 1.5*1.5=2.25em compared to the body font size. Is that what you want? Maybe, maybe not.
where ELSE should I be using ems
Anywhere you want the size of an element to respond to the user's preferred font-size. One common example would be something like:
#maintext {
width: 60%;
min-width: 8em;
max-width: 40em;
}
to try to restrict text lines to a reasonable column width when doing liquid layout.
But if you are limiting yourself to a fixed-width layout it may not make sense to make element widths font-size-dependent.
You may find How to size text using ems an interesting and helpful read. The thing that I try to remember is my conversion from ems to pixels.
In your example:
body {
font-size: 62.5%;
line-height: 1.4em;
}
1 em is equal to 10 pixels if the browser default text-size is 16px. The line height would then be equal to 14 pixels. Like bobince beings out, I would use a unitless line-height value.
To help you with your calculations, you can use an Em Calculator. It allows you to easily convert between ems and pixels.
The problem with em is that it is a relative unit. Inheritance and relativity don't mix well in HTML documents. What I do is use px for font size and box dimensions / positioning, but try to use em for line-height, margin / padding, etc...
I'm sure it's not the "proper" way to do it, but the system was pretty poorly designed from the start, if you ask me.
ems are relative, so if you set:
body {
font-size: .6em;
}
Everything will be relative to that.
Which means (and this is where my head starts to hurt too) that if an h1 has a default font size of 250% larger than most other text (p, li), the header will now be 60% of that default size. So it will still be 2.5 times bigger than the other stuff, but it will be 60% smaller than if you hadn't set the rule at all.
Now, if you then say that :
h1 {
font-size: 1.2em;
}
The h1 will now be 20% larger than what it would be if you hadn't set the rule, so it's 20% larger than the already shrunken down 60% smaller from the first rule. This means that it will no longer be in direct proportion to the browser's default for h1 and other elements.
So basically, you should set your font-size up front for the whole document (like in the first rule I showed), and this is your baseline. After that, you set how you want any individual elements to be sized in relationship to each other (basically in relationship to what they already are)...
So if you know you want all of the fonts in the #wrapper div to be 1.5em from their default, setting it there is perfect. But if you want to change the size of blockquote so that it's a tad smaller, you'd still set the rule for #wrapper, but then make a second rule for blockquote.
If you want to set up page width by using em's, follow this pattern provided by YUI development team
Divide your desired pixel width by 13; the result is your width in ems for all non-IE browsers. For IE, divide your desired pixel with by 13.3333 to find the width in ems for IE.
Here's an example of a custom page width of 600px, and here's what the CSS looks like:
600 px / 13 = 46.15 (non-IE browsers)
600 px / 13.33 = 45.00 (IE browsers)
#custom-doc {
margin:auto;text-align:left; /* leave unchanged */
width:46.15em;/* non-IE */
*width:45.00em;/* IE */
min-width:600px;/* optional but recommended */
}
regards,
Related
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.
I have an h1 I want to fit the entire width of the viewport which consists of 13 characters in a monospaced font. After reading the CSS-Tricks article on viewport sized typography it seems like logically if I want to achieve this I simply have to set my h1's styles to:
h1 {
font-size: 13vw;
font-family: monospace;
}
This however is rendering with a bit of space left over (highlight the text to see the white space):
(There would be an image here but I don't have enough rep so click here for the JSFiddle)
I have tried other sizes, font-size: 14vw; is slightly too big, font-size: 13.99vw; seems just right, but strangely font-size: 13.999vw; is still too big?
Can someone explain what is going on here? Why would each character of a 13 character length string in a monospaced font require more than (100/13)% of the viewport width to fit the entire viewport width?
Before I begin I'm just going to say that I'm not going to give you a workaround due to issues I've raised in comments on Stoyan Dekov's answer. Instead I'm only going to answer your question of Can someone explain what is going on here?
font-size != width
The problem here is that you're assuming font-size is the same thing as width. It isn't. The CSS Fonts Module defines font-size as:
...the desired height of glyphs from the font.
This means that font-size is more comparable to height than it is to width.
This isn't specific to the vw unit, either. If you specify a font-size in pixels you'll also notice that the computed width does not match the font-size.
But even then it all depends on which font-family you're using anyway, as the same paragraph continues to say:
For scalable fonts, the font-size is a scale factor applied to the EM unit of the font. (Note that certain glyphs may bleed outside their EM box.) For non-scalable fonts, the font-size is converted into absolute units and matched against the declared font-size of the font, using the same absolute coordinate space for both of the matched values.
The key words here being scalable and non-scalable.
Even if a non-scalable font was being used though, 13vw would not reflect each character's width. This would never work with vw, but it may work with vh but only if the aspect ratio of each individual character matched the screen's aspect ratio.
The problem is if a text is the exact same size as the parent container, it will span across a second line.
body {
margin: 0;
width:100px
}
h1 {
font-family: monospace;
width:100px;
}
That will cause the text to go onto a new line as they are both 100px. That's why 14vw is too big, but 13.99 is just enough: Fiddle DEMO
However, you can use text-align: justify; to achieve what you want.
Take a look at this Fiddle DEMO.
Im using em font sizes, which is working fine for everywhere apart from the sidebar.
In the main content the em size is great. If I copy this em size to the sidebar the text becomes larger.
Im using a html/body size of 17px. Then 1.412em to get the size I would like. To see a live link of the sidebar font bigger go to this link. If you look at the twitter feed on the right sidebar you will see its using the same em but you view it a lot larger.
Using em as measurement value would just not inhert but increases accordingly.
Here's an example:
<div>
<p>
<span>foo bar</span>
</p>
</div>
body{
font-size: 1em;
}
div{
font-size: 1.5em;/*1.5em of 1em == 1.5em*/
}
div > p{
font-size: 1.5em;/*1.5em of 1.5em inherited from div == 2.25em*/
}
div > p > span{
font-size: 1.5em; /*1.5em of 2.25em inherited from p == 3.375em*/
}
So, I would recommend you to use px as measurement value.
Use ems to make scalable style sheets only.
If you want to know more about px, em, and % please follow this link and this link
Don't use em for font-size, that's just about the only place where you should never use it.
1em is the size of an m in the current standard font. You can use this to set paddings/margins, for example between paragraphs or around text blocks, that need to scale according to font size, to cater for people using custom settings at OS/browser level, or just as an easy way to keep a 'good' distance without having to worry about precise pixels.
Scaling a font to a relative size to the m of the current standard font makes no sense at all, unless you want to achieve this effect. If you would want to, it would be more logical to specify font-size:110%, for a single element or block. As a rule, use pt or px to specify font sizes.
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.
There are many articles and questions about percentage-sized vs other-sized fonts. However, I can not find out WHAT the reference of the percent-value is supposed to be. I understand this is 'the same size in all browsers'. I also read this, for instance:
Percent (%): The percent unit is much like the “em” unit, save for a few fundamental differences. First and foremost, the current font-size is equal to 100% (i.e. 12pt = 100%). While using the percent unit, your text remains fully scalable for mobile devices and for accessibility.
Source: http://kyleschaeffer.com/best-practices/css-font-size-em-vs-px-vs-pt-vs/
But if you say "ie 12 pt = 100%", then it means you first have to define font-size: 12pt. Is that how it works? You first define a size in an absolute measure, and then refer to this as '100%'? Does not make a lot of sense, as many samples say it is useful to put:
body {
font-size: 100%;
}
So by doing this, WHAT is the font size relative to? I notice that the size I see on my screen differs for every font. Arial looks way bigger than Times New Roman, for instance. Also, if I would just do this, body size = 100%, would that mean that it will be the same on all browsers? Or only if I first define an absolute value?
UPDATE, SAT JUL 23
I am getting there, but please bear with me.
So, the % value relates to the default browser font size, if I understand correctly. Well, that is nice but gives me again several other questions:
Is this standard size always the same for every browser version, or do they vary between versions?
I ! found (see image below) the settings for Google Chrome (never looked at this before!), and I see standard "serif", "sans-serif" and "monospace" settings. But how do I interpret this for other fonts? Say I define font: 100% Georgia;, what size will the browser take? Will it look up the standard size for serif, or has the "Georgia" font a standard size for the browser
On several websites I read things like Sizing text and line-height in ems, with a percentage specified on the body [..], was shown to provide **accurate, resizable text across all browsers** in common use today. But from what I am learning now I believe that you should actually choose between either resizable text (using % or em, like what they recommend in this quote), or having 'accurate, consistent font-sizes across browsers' (by using px or pt as a base). Is this correct?
Google Settings:
This is how I think things could look like if you do not define the size in absolute values.
The browser default which is something like 16pt for Firefox, You can check by going into Firefox options, clicking the Content tab, and checking the font size. You can do the same for other browsers as well.
I personally like to control the default font size of my websites, so in a CSS file that is included in every page I will set the BODY default, like so:
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 14px
}
Now the font-size of all my HTML tags will inherit a font-size of 14px.
Say that I want a all divs to have a font size 10% bigger than body, I simply do:
div {
font-size: 110%
}
Now any browser that view my pages will autmoatically make all divs 10% bigger than that of the body, which should be something like 15.4px.
If I want the font-size of all div's to be 10% smaller, I do:
div {
font-size: 90%
}
This will make all divs have a font-size of 12.6px.
Also you should know that since font-size is inherited, that each nested div will decrease in font size by 10%, so:
<div>Outer DIV.
<div>Inner DIV</div>
</div>
The inner div will have a font-size of 11.34px (90% of 12.6px), which may not have been intended.
This can help in the explanation:
http://www.w3.org/TR/2011/REC-CSS2-20110607/syndata.html#value-def-percentage
My understanding is that when the font is set as follows
body {
font-size: 100%;
}
the browser will render the font as per the user settings for that browser.
The spec says that % is rendered
relative to parent element's font size
http://www.w3.org/TR/CSS1/#font-size
In this case, I take that to mean what the browser is set to.
A percentage in the value of the font-size property is relative to the parent element’s font size. CSS 2.1 says this obscurely and confusingly (referring to “inherited font size”), but CSS3 Text says it very clearly.
The parent of the body element is the root element, i.e. the html element. Unless set in a style sheet, the font size of the root element is implementation-dependent. It typically depends on user settings.
Setting font-size: 100% is pointless in many cases, as an element inherits its parent’s font size (leading to the same result), if no style sheet sets its own font size. However, it can be useful to override settings in other style sheets (including browser default style sheets).
For example, an input element typically has a setting in browser style sheet, making its default font size smaller than that of copy text. If you wish to make the font size the same, you can set
input { font-size: 100% }
For the body element, the logically redundant setting font-size: 100% is used fairly often, as it is believed to help against some browser bugs (in browsers that probably have lost their significance now).
Sorry if I'm late to the party, but in your edit you make a remark about font: 100% Georgia, which the other answers haven't responded to.
There is a difference between font: 100% Georgia and font-size:100%; font-family:'Georgia'. If that was all the shorthand method did, the font-size part would be meaningless. But it also sets a lot of properties to their default values: the line height becomes normal (or around 1.2), ditto for the style (non-italic) and weight (non-bold).
That's all. The other answers already mentioned everything else there was to mention.
It's relative to default browser font-size unless you override it with a value in pt or px.
As you showed convincingly, the font-size: 100%; will not render the same in all browsers. However, you will set your font face in your CSS file, so this will be the same (or a fallback) in all browsers.
I believe font-size: 100%; can be very useful when combining it with em-based design. As this article shows, this will create a very flexible website.
When is this useful? When your site needs to adapt to the visitors' wishes. Take for example an elderly man that puts his default font-size at 24 px. Or someone with a small screen with a large resolution that increases his default font-size because he otherwise has to squint. Most sites would break, but em-based sites are able to cope with these situations.
According to ALL THE SPECS DATING BACK TO 1996, percentage values on font-size refer to the parent element's (computed) font-size.
<style>
div {
font-size: 16px;
}
span {
font-size: 75%;
}
</style>
<div><span>this font size is 12px!</span></div>
It's that easy.
What if the div declares a relative font-size, like ems, or even worse, another percentage?? See “computed” above. Whatever absolute unit the relative unit converts to.
The only question that remains is what happens when you use a percentage value on the root element, which has no parent:
html {
font-size: 62.5%; /* 62.5% of what? */
}
In that case, see the “duplicate” of this question. TLDR: percentages on the root element refer to the browser default font size, which might be different per user.
References:
CSS 1 spec (1996)
CSS 2.1 spec (2011)
CSS Fonts Level 3 spec (2013)
CSS Fonts Level 3 editor’s draft (2017)
Relative to the default size defined to that font.
If someone opens your page on a web browser, there's a default font and font size it uses.
As to my understanding it help your content adjust with different values of font family and font sizes.Thus making your content scalable. As to the issue of inhering font size we can always override by giving a specific font size for the element.