Question

With the following CSS:

* {
    margin: 0;
    padding: 0;
    font-family:"Segoe UI";
    font-variant: small-caps;
}
.red {
    color: hsl(0, 100%, 50%);
    font-size: 3em;
}
.orange {
    color: hsl(30, 100%, 50%);
    font-size: 3em;
}
.yellow {
    color: hsl(60, 100%, 50%);
    font-size: 3em;
}
.green {
    color: hsl(120, 100%, 50%);
    font-size: 3em;
}
.blue {
    color: hsl(210, 100%, 50%);
    font-size: 3em;
}
.indigo {
    color: hsl(230, 100%, 50%);
    font-size: 3em;
}
.violet {
    color: hsl(274, 100%, 50%);
    font-size: 3em;
}

...the attributes in the * selector work fine - they apply to all of the classes; however, if I move font-size there, the text grows to tyrannosauric proportions. You can see this by moving the font-size from the individual classes to the * class here: http://jsfiddle.net/NvTvr/8/

Why does this happen?

UPDATE

So this is the way to go, then:

* {
    margin: 0;
    padding: 0;
    font-family:"Segoe UI";
    font-variant: small-caps;
    font-size: 48px;
}
.red {
    color: hsl(0, 100%, 50%);
}

...etc. (no font-size specified within the color classes); as seen in http://jsfiddle.net/NvTvr/10/

Was it helpful?

Solution

Because em is relative to the context.

As font-size is inherited from the context, each descendant element with em font-size will multiply the current font-size up to the element that contains text content.

Let's see in practice, assuming:

* { font-size: 3em }

You're applying that (relative to context) font-size to all elements.

That means, the html element will have 3 times the default browser font-size. The body will have 3 times font-size of its container (html) which corresponds to 9 times the default font-size. And so forth for each element's ancestors.

There's a new unit that does not have this issue, rem which is relative to root. But this is not as widely supported (no IE<=8 support).


Going a bit off-topic for the em x px x rem debate in this section of the answer.

Quoting this answer:

Use em when you specifically want the size of something to depend on the current font size.

Modern browsers can scale px units just fine. em was used mostly when old IE was predominant and didn't scale the px font-size when zooming.

Still, em has it uses in web design. Say, when making CSS-icons that should scale relatively to the font-size of the text. But for overall layout, I go with rem/px which do not generate compound issues and headaches, or percentages when making fluid layouts.

The issue with px for font-size is that, if you ever need to change the overall size of the page's text, you will have to change every single font-size declaration that uses px. That's where rem comes to aid.

There's always an heated discussion about which unit to use for the font-size. Go with the one that gives less headaches and suffices for your project.

So in sum, it depends on personal preference and project requirements.


References:

Definitions and explanations

More discussions

OTHER TIPS

It's because when you use the "*" selector you are applying font-size:3em to the parents of ".red",".green" etc, (in this case the body ) as well; em is a compounding unit so with the way you are declaring font size you are applying font-size:3em to body (48px assuming 16px browser default) and then font-size:3em to your classes which means the font size will be 144px.

hope my explanation makes sense.

The em unit, when using in the value of the font-size property, denotes the font size of the parent element. So declaring * { font-size: 3em } makes the font size of each element three times the font size of its parent element.

If you want to use a font size that is three times the browser’s default font size (which can be anything), then the simplest way is to declare body { font-size: 3em } and not declare font-size for other elements.

Thanks to Jukka's explicit and implied* suggestions, the CSS is now:

* {
    margin: 0;
    padding: 0;
    /*font-family: Consolas;*/
    /*font-family: Candara;/*
    /*font-family: Calibri;*/
    font-family:"Segoe UI";
    font-variant: small-caps;
}
body { font-size: 3em }
.red { color: hsl(0, 100%, 50%); }
.orange { color: hsl(30, 100%, 50%); }
.yellow { color: hsl(60, 100%, 50%); }
.green { color: hsl(120, 100%, 50%); }
.blue { color: hsl(210, 100%, 50%); }
.indigo { color: hsl(230, 100%, 50%); }
.violet { color: hsl(274, 100%, 50%); }

Update jsfiddle is http://jsfiddle.net/NvTvr/11/

  • Although, if you select TidyUp in jsfiddle, it vertically expands the one-line class and element declarations (I like the idea of keeping it all on one line if only one attribute is being set).
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top