I am pretty new to CSS, and would like to know if there is/are some sort of rule/rules of thumb for determining when to use different units to define layouts. Currently I have everything defined in %, because I thought that'd be good for window resizing. That is not the case, text starts to overflow, images get screwed around and so on.
Any help will be appreceiated.
Typically, I use the following
Layouts - Pixel (Unless something needs to be a % width/height)
Fonts - Pixel (Sometimes % for accessibility, but it is a nightmare to maintain)
Generally speaking, you can use pixels most of the time. The font issue is a more complex one. For instance, if you want the "increase font-size" features to work within a browser without resizing the rest of the page, you need to use %'s. However, when using % font sizes, a child element always inherits the parents font-size, so you get the following:
body { font-size:87%; }
h1 { font-size:87%; }
This will mean that the h1 is actually 87% of 87%. This can be quite annoying. As you end up with percentages > 100%. It gets very thick fast, and is best avoided.
I'm not sure if em's work in the same way, I've never looked into them in great detail.
Using percentages to have a layout work in different size viewports is a very advanced technique, and is often done dynamically using javascript. Until you are more familiar with CSS, and can look at working percentage based layouts and understand enough to replicate it, you are better sticking to PX.
If you are going the javascript route it is really quite simple. For a start use jQuery as it makes resizing your layout a breeze compared to trying to do it with native javascript. Then $(window).height(); gives you the height of the viewport; $(window).width(); gives you the width. You set a default px width for your container, and then use percentages for all other block level elements (containers, within the container, sidebar, main etc) and do this:
function percentagize() {
var height = $(window).height()-100;
var width = $(window).width()-20;
$("div#container").css({
'height' : height+'px',
'width' : width+'px',
'margin': '0 auto'
});
}
$(document).ready(function() {
percentagize();
$(window).bind('resize','percentagize');
})
This should give you an idea: http://w3schools.com/cssref/css_units.asp
% is not explained properly on that page, but it means x% of the containing block.
You should use ems for fonts so that they are always relatively sized... by default they are 1 em or 16px... you can set play with this by setting body { font-size: 75% } which makes 1em the equivalent of 12px The PxtoEm calculator is great. From here you can do things like
h1 { font-size: 3em }
p { font-size: 1em }
now no matter what you set that body font size to the h1 tag will always be 3 times larger than a paragraph. It gives more flexibility and keeps yout type hierachy proportional.
For layouts it really depends on the layout type... for the classic fixed with central column then use pixels.... for fluid or adaptive layouts then use percentages (or a mix of fixed width, i.e. left hand nav bar andpercentages)
Use em as much as possible, since this is the most maintainable. The em unit depends on the font size of the current element, so if you change the base font size, em-units scale along.
Use px in screen style sheets when you need a fixed size. Typically you would specify the size of the base font in pixels. Image sizes should also be specified in px, since an image should not scale up or down just because you change a font - it will just make the image blurry. Also border thicknesses should probably be specified in pixels, since you don't want it to depend on font sizes.
Use pt, pc, in, cm, mm only in print media style sheets. You probably wouldn't to mix metric and imperial in the same style sheet, so decide on either in or cm/mm.
% is tricky since it means something different depending on the property. For font-sizes, 100% = 1em, so its just a matter of preference if you like % or em. (I prefer em for font sizes, since % have different meaning in other contexts.) It is not affected by window scaling though. The font size doesn't scale with the window size, and neither does em or % units.
For width and height on boxes, % refers to percent of the size of the parent box, which for the root element is depending on the window size. This is much less useful than it sounds! For example if you have a flow of text without any specified width, the lines will become too long to read comfortably. If you specify the width of the text box in em's you can give it a nice readable line-length, on any screen. But if you specify the width in % it will scale with the size of the window, which means it can still be too long on some screens and to short on others. Scaling with the window size sounds good in theory, but is rarely what you want.
Related
I'm experiencing some pretty bizarre behaviour from my CSS font-size rules. I'm probably doing something silly myself [this must be the case ;-) ], but I hope someone can point it out for me.
Currently (for testing purposes) I have only one rule for font-size in the stylesheet, that regulates ALL font-sizes, and this is it:
p, div, a, span {
font-size:3em;
}
Now I know 3em is a pretty big font-size (for all I know it should correspond to a width of about 3*16 = 48 pixels on the big screen browsers), but what you see in reality is simply ridiculous. Have a look: http://www.svvreewijkdevaan.nl/nl/
If you think the font size in the menu (which you see on top of the page) is big, scroll down a bit, and you'll find that the letters become so huge that they're not really recognizable as letters anymore.
And in fact, looking in the Firefox inspection tool, I find that '3em' letters are computed to have a font-size of (get this) 34992px, i.e. almost 35 thousand. What does that even mean?
In fact, the real (displayed) font-size (i.e. the width) seems to grow - at the very least - exponentially with the specified em number, rather than proportionally. So for example, if I replace 3em by 3.5em, the displayed font-size becomes at least two times as wide (actually more). Conversely, if I reduce the specified font-size to 1em I get the - normal and expected - size of about 16px. But if I make it 0.7em, the width reduces to maybe 2px (absolutely unreadably small).
Why don't the real (displayed) font-sizes grow proportionally with font-size (in terms of 'em') specified in my stylesheet?
em is based on the font-size of the parent element. Now, if you nest elements for which you have set the font-size in em into each other – those values get multiplied.
Either don’t nest element with font-sizes set in em that much;
set it for less elements (for example only for div or p, and let the descendants inherit the size);
or look into the rem unit instead.
I have a project where IE9 is the minimal compatibility browser. That means that I can use the rem unit.
In my experience on large projects, involving many dev, the use of "em" creates quite a mess. I do not say that it is bad in itself, just that it seems to "naturally" happened on over time, when there is different people with varying skills working on a project. Dom elements tend to pile up, and that do not work well with the compounding behavior of "em".
After having looked at a lot of resources online, it seems that there is a lot of cargo cult on the question.
there is the temptation of solution 1:
start with this (suggested here css3files.com comment - David Buell ):
solution 1 :
html { font-size: 10px;}
body { font-size: 1.3rem;}
Rem for anything text-related and px for the rest.
But even though, I am not sure where I am really contrained to use another unit than "rem". I did some zooming test, and did not notice differences between "rem" and "px". The advantage of "rem" over "px" seems to be that "rem" will be relative to the a size set with "%" on the body, and this allows to change all text sizes in one line for a specific breakpoint.
Default text size change IS seemingly an issue, since "px" and "rem" text remains unchanged. But I wonder is there is usage statistics about this (this SO user thinks nobody). If it is really used then, I think I should drop the "easy math" font-size definition on the html tag.
solution 2 :
body { font-size: 0.8125rem;}
That gives 13px size with the browsers default size of 16px - and users can still change the default setting. (and maths aren't that hard starting with 16)
What I am really unsure of is the case of different screen resolution, and the case of different pixel density (which I know can be changed on windows).
to sum up:
No need to accomodate anything below IE9.
reponsive design.
handle zoom well.
handle user text size change if that's really used.
no magic, as barebone as possible (I use a css preprocessor but I want to avoid crazy use of it).
I think many frontend developer adapt their interface to browser zoom. But what is the practice with text-only zoom ? Its a somewhat more hidden browser feature. How many devs actually test it and code for it ?
I see that SO supports it but that it sorta breaks beyond a certain scale.
What the right base setup for a IE9+ interface, that supports responsive web design?
keep a rule - All font sizes must be specified using rem only with a pixel fall back. Do not use percentages, ems or pixels alone.
font-size: 14px; /* pixel fall back rule should come first */
font-size: 1.4rem;
more infor - https://github.com/stubbornella/oocss-code-standards
I did some testing here : http://codepen.io/Olivvv/full/aGDzI
a few interpretations :
solution 1 : WRONG
html { font-size: 10px;}
prevents the permanent browser/user font-size setting to be applied. If the user has requested a bigger font-size,it should take effect.
See here with the SO website, things break a little with very big fonts, but at least the user gets the font-size increase.
solution 2: OK
body { font-size: 0.8125rem;}
is actually the same as
body { font-size: 0.8125em;}
since the can only inherit from the element "em" as the same value as "rem" ("rem" stands for root em, the em value of the root element, i.e the element)
solution 3: INTERESTING
html{font-size: 62.5%;}
body{font-size: 1.6em;}
---> 1 rem == 10px
(if the browser is set to default, i.e 16px; - (62.5/100)*16 == 10)
Now about the possible strategies :
1. rem only
html{font-size: 6.25%;}
body{font-size: 16em;}
+ only working with rem; for font-size, width, padding, margin, borders. This seems to be the easiest way to go.
Here 1 rem equates to 1px in defaut setting. It responds to user change of the default setting, so it is accessible.
When doing responsive design, the interface can be zoomed by changing the % value of the . for instance:
html
the whole interface is zoomed. Zoom is vertical and horizontal.
div.foo{
font-size: 16rem;
border: 16rem solid;
width: 350rem;
border-color: limegreen;
}
That will create a box that expands both vertically and horizontally.
Issue: What about vertical zoom ?
2. rem and em (in order to get vertical zoom)
rem -> interface elements, width essentially
em -> text (can be resized independently from interface elements (which are in rem) by changing the font-size value on the body)
px -> seperators, borders essentially
This way we achieve interfaces that respond well to both browser zoom and browser font-size setting
Some comments on ideas read on some blogs and
"just use px, if your brain works in pixel" --> Very Wrong. Font-size in px will be unreadable for some users who have explicitely requested bigger font size. (and what about dpi different from 96 ?)
"layout in em" --> average wrong, since a different user font size will make appear horizontal scrollbars or not use the full viewport space. Such behavior relates to zoom, not font size. (note that I am not considering browsers older than IE9 - just let them fall back on their default values )
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.
I'm having trouble writing maintainable CSS code when font size is specified with EM units as opposed to PX units. I've been accustomed to writing CSS code like this:
body {font-size: 12px;}
body .sidebar {font-size:11px;}
body .sidebar .loadmore {font-size:10px;}
body .sidebar .warning {font-size:13px;}
The idea is that on many pages through out the site, there's a lot of text that should have 12 pixel font-size. I take advantage of the rules of specificity to override the 12px font size in special areas of the site.
Let's say I rewrote the above code as:
body {font-size: 12em;}
body .sidebar {font-size:11em;}
body .sidebar .loadmore {font-size:10em;}
body .sidebar .warning {font-size:13em;}
If I replaced px with em in the code above, my understanding is that I lose the advantage of rules of specificity. Line 3 of the code would be interpreted as " 10 em of 11 em of 12 em" which is not at all the same meaning as " override all previous rules and use 10 em of (what is the default?)". Is what I've stated correct?
edit If what I've said is correct, then how does one write a font size rule such as "use font size X for all elements, but use font size Y on side bars"?
John the specificity that you are talking about will occur in the way that you have stated. A reference as to why can be seen: http://kyleschaeffer.com/best-practices/css-font-size-em-vs-px-vs-pt-vs/.
Edit As a reply to your edit please consider what jnylen posted in the comments of your original post.
A font size of 12 em as you have listed for body {font-size: 12em;} is going to scale the default font size to 12x it's current size. If you would like to use em's you need to consider at what scale rate you wish to use them and do the math. If you want to set fixed sizes with nested statements you need to stick to fixed attributes (pixels). The advantage of em's as stated in the article that I linked is that you can set a default size, say 12 px and then use em to scale them. For example in mobile based websites.
Yes, em values "multiply" together when the elements they apply to are nested. It's not necessarily a specificity issue - if you specified the rules individually for .loadmore and .sidebar you would see the same issue, since .sidebar contains .loadmore.
Here's an example of a way to work with this: http://jsfiddle.net/PJWrW/
I usually use either px or percentage units for font sizes, to make it explicit that I'm setting an absolute font size or modifying the parent font size.
I sometimes use em units for defining dimensions like paddings and widths, since an em unit is basically the width of a letter at the current font size.
As far as I know, if you're using em's for font size, there is no one way to set a standard font size for elements in a left hand side bar (or elsewhere for that matter) whilst setting the specific size of some elements in that side bar. If you use em's you'll have to specify the sizes of all elements in that side bar.
Personally I usually use px for font sizing, simply because you can set a standard font size for certain elements as you say in your post.
The only convincing arguments I have heard for using em over px regard scaling issues that are no longer really a problem (IE6 doesn't allow you to change font size manually if you use px but most people stopped hacking for IE6 a while back) The only real situation I can see using em as an advantage is if you want to implement functionality whereby the user can change the font size via JavaScript like here
We have a CSS file with some rules similar to the following:
.directory-result ul
{
margin-top: 20px;
width: 60em;
}
.about-text
{
margin-top: 1em;
margin-bottom: 1em;
}
Everything is working ok, but we're wondering specifically about the inconsistencies between the margin-top values. One is 20px and the other is 1em.
Which is the best one to go with? What are the points I should consider when deciding which to use? Thanks.
em units are used for better scalability of the page when the size of the elements depend on the page's scale. It's especially important for old browsers (e.g. IE6) and mobile platforms.
px units are used for absolute values, while em is relative to the font size of the particular element.
1em means one font-line, e.g. you have a box with font-size 12px that means that 1em will be equal to 12px
Also, using px seems easier because you know the exact value, but em units inherit the value of their container.
<p>Text</p>
<div class="box">
<p>Lorem</p>
</div>
p {
font-size: 1.2em;
}
.box {
font-size: 1.2em;
}
In this case, the first <p> will have font-size equal to the basic font-size * 1.2, and the second <p> will display with font-size * 1.2 * 1.2.
They're simply two different ways of measuring. Em is linked to the font size (traditionally, 1em is roughly the width of the letter M in a given typeface), while px is pixels.
If you build everything using em, everything will scale accordingly when the user adjusts their font size (e.g. using IE's Page > Text Size menu). It also makes it easier to work to a vertical rhythm.
Pixels are better when you want to build something "pixel-perfect". Be aware that a CSS pixel doesn't always equal a screen pixel - mainly because modern browsers and mobile devices allow for zooming. This isn't usually a problem though because the entire page is scaled accordingly.
Whatever you do, make sure you're consistent throughout - it makes life much easier later on.
The ems unit is relative to the current font size in the browser. So if the user increases the font size*, or if you change an element’s font size in the CSS, the margins should still look “right” in proportion to the text.
*(This ceases to matter if the user zooms the page instead of increasing the text size (as is the default in Firefox and Chrome now, and is an option in IE).
If you're using a margin to position something a set number of pixels away from something else, then you should obviously stick with pixels.
Also here is a very good in depth tutorial:
px – em – % – pt – keyword
In this example directory-result ul represents a block - some sort of list/menu where pixel dimensions are quite important. We can’t always rely on em which defines the text size, because if we need 20px space due to some background image – well, we need 20px, no compromises.
Note that you can't create and save the image i.e. 10em wide, therefore I see no reason why should I use different units on a web page. It just creates confusion and later on it is very difficult to maintain the layout.
There is a one place though, where using em is advisable – I’m talking about text blocks. I’m guessing in your code about-text is placed within other text where adding top/bottom margin of 1em (height of text) makes sense. It’s like in any text editor (i.e. line spacing in MS Word) – text looks best when spacing between lines is defined by multiplying the height of text
So in my opinion – everywhere where you deal with design and you use images by default measured in pixels – usepixels for all padding/margin.
Everywhere where you deal with text inside a text block, and you want to add even spacing between the text nodes – useem.