Safari 6 (desktop) is rendering all of my fonts at a smaller size than what I'm assigning in my stylesheets.
The (mis)calculation is always proportional and affects every font on my site. Fonts that should be 18px are 16px, 28px is calculated as 25px, 24px is appearing as 21px, etc.
I'm using the 62.5% font-sizing technique with rems:
html {
font-size: 62.5%;
}
body {
font: normal normal 400 18px/1 sans-serif;
font-size: 1.8rem;
}
h1 {
font-size: 28px; // renders at 28px if the next line is disabled
font-size: 2.8rem; // renders at 25px
}
Web Inspector shows that all of my font-size rules are being enforced:
But for the same body element, it is showing a calculated font size of 16px:
No other browsers are doing this, including Mobile Safari on iOS 7.
If I disable the rem font-size rule in Web Inspector, fonts display as they should.
I thought it might be related to my use of the shorthand rule on the body element, but switching to long-form has no effect.
I checked other sites (besides my own) to make sure it wasn't a browser setting I wasn't aware of, and it's occurring on both local development sites and in live production.
Has anyone else run into this or can anyone see why this might be occurring?
Related
I'm experiencing the following issue in both Safari and Chrome.
body {
font-size: 15px;
line-height: 1.2;
}
body, .same-font {
font-family: Helvetica, sans-serif;
}
code {
font-family: Courier New, sans-serif;
}
<ul>
<li>Without any code - 18px height.</li>
<li>With <code>code</code> - 20px height.</li>
<li>With <code class="same-font">code.same-font</code> - 18px height.</li>
</ul>
Run the above snippet and the inspector. You can notice that the code element doesn't have anything modifying its font-size or line-height except body which it's inheriting from.
It's not adhering to that inherit though, because the height of its containing li is 20px, not 18 like the others... I'm not sure where that height is coming from, because the code element itself has a height of 17px (which is also of unknown origin).
When the normal/body is applied to the code element (like on the third list item), it goes back to 18px like normal. To me this means it's not any other properties that the user agent has imposed on the code element affecting the height - solely the font-family.
EDIT: For reference, something in StackOverflow's styles prevent this behaviour. The following list items all have the same height:
One
two
Three
EDIT 2: Apparently not.. if you change their monospace font to Courier New then the same problem would persist.
How can this change in size be prevented? i.e. How can you specify a line height that will be used even if the fonts within that line continue to change?
An example use case would be in a design with vertical rhythm - each line's height and the total height used by an element should be a multiple of 18px (i.e., if using that grid size) - a 20px line throws off the rhythm.
I ended up solving my own problem (to an acceptable extent) by simply tweaking with the font family and size until it worked for me:
body {
font-size: 15px;
line-height: 1.2;
}
body, .same-font {
font-family: Helvetica, sans-serif;
}
code {
font-family: Menlo, Courier New, sans-serif;
font-size: 0.9333em; /* 14/15 */
line-height: 1.28571; /* 18/14 */
}
<ul>
<li>Without any code - 18px height.</li>
<li>With <code>code</code> - 18px height.</li>
<li>With <code class="same-font">code.same-font</code> - 18px height.</li>
</ul>
Why Menlo?
I noticed that StackOverflow used Menlo and that didn't have this problem. When I tried it, it also solved the problem, however the font isn't built in on Windows.
So simply using Menlo solved the problem on Mac and didn't change anything on Windows.
Why the different font-size?
The different size changed nothing (except the font size...) when Menlo is in use - it still adhered to the line height, so Mac is all good.
However this font-size in combination with the Courier New fallback on Windows somehow got it adhering to the line height there too!
If I used 14px instead of 0.9333em it'd still work fine, but if I used 18px for the line-height instead of 1.28571, it wouldn't work. That doesn't bother me as I use relative values in my designs anyway.
So...
The Menlo font in combination with a Courier New fallback with a different font-size worked to solve my problem to a good-enough extent on Mac (Safari and Chrome) and Windows (Chrome).
My situation is lenient - a pixel difference wouldn't break my design, but just my rhythm. In cases where pixel perfection is required, I wouldn't feel safe with this voodoo method of playing with fonts and sizes...
If anybody can still explain where all of these numbers are coming from and what makes the actual difference here, that'd be great.
I have some icons that are set via pseudoelement in CSS, like this:
.button a:before {
font-size: 1.3em;
font-family: font-awesome;
content: "*";
}
And there are other, similar declarations elsewhere, like
.button .otherclass a:before {
font-size: 1.35em;
}
This works fine with modern web browsers, but IE >= 9 compounds all the font sizes, so that the resulting icon is enormous (like 5 times its size). How can I prevent this from happening?
(BTW, the actual code with the problem is here.)
This is a bug in IE, as reported on the Microsoft Connect page mentioned by #Aibrean, but the page also shows that Microsoft does not admit that this is a bug (they say they cannot reproduce it). It can be reproduced in IE 11 on Win 7 with the following simple document:
<style>
.foo, .bar:before {
font-size: 2em;
content: "X";
}
.bar:before {
font-size: 5em;
}
</style>
X<span class=foo>X</span>
<span class=bar>bar</span>
The second X should be 5 times as big as normal X, but it is actually 10 times as big in IE, since IE incorrectly multiplies the effects of 2em and 5em.
The workaround, it seems, is to organize your style sheet so that the font size of generated content is set once only for each element. That is, so that there are no two font-size declarations that apply to the same :before or :after pseudo-element.
There is a slightly better solution than using absolute font-sizes, and that is to use rem inside the :before or :after declaration.
em and rem units are based of the default font-size (commonly 16px, so 1rem = 1em = 16px) so if the user changes their default font then your font will change too. However rem units do not compound.
rem support is growing but you can use both (if you don't need compounding):
font-size: 2em
font-size: 2rem
and then those browsers (e.g. IE8) that don't support rem will use em. And as IE8 doesn't have the compounding issue to which you refer, this actually works nicely.
I'm working on mobile first framework. The project has a broad range of requirements, with a mass of browsers and devices over various locations to cater for.
One of my key locations to target is India, where the browser and device usage trends differ greatly to that in the UK or US.
India browser usage
http://gs.statcounter.com/#all-browser-IN-monthly-201301-201312-bar
UK Browser usage
http://gs.statcounter.com/#all-browser-GB-monthly-201301-201312-bar
The browsers that I need to target for india region are opera, android, uc browser and nokia, but each of those have their little quirks. With that the range of devices differ
Opera mini - does not support rems
Android (prior to chrome) v2-v4 has problems with both rems and ems
http://www.quirksmode.org/css/units-values/mobile.html
-- Am I right in assuming that more recent versions of Android come pre installed with Chrome and the OS web browser?
I'd ideally like to use rems, as it removes the issues of nested content inheriting the em scale of its parent element. However based on the research on http://www.quirksmode.org, I need to have a fall back set.
So I'm going to need to declare a px value.
For example, can I do this:
h1 {font-size: 24px; line-height: 30px; margin-bottom: 10px; font-size: 1.846rem; line-height: 2.308rem; margin-bottom: 0.769rem} /* 24px / 30px / 10px */
Or do I have to do something like this?
h1 {font-size: 24px; line-height: 30px; margin-bottom: 10px}
h1 {font-size: 1.846rem; line-height: 2.308rem; margin-bottom: 0.769rem} /* 24px / 30px / 10px */
Or is there something else that is better?
I have seen a few js poly-fills, such as https://github.com/chuckcarpenter/REM-unit-polyfill, but there maybe cases where JavaScript is not enabled so this won't work.
Additionally I am try to focus on performance, so I want to keep the number of requests to a minimum and the keep the css a clean as possible.
Thanks
Both of your style declarations will work fine. CSS renders code in a cascading fashion, this means if one value is declared after another, the latter will be used. If a browser can render px but cannot render rem, the rem values will simply be ignored. If a browser can render both px and rem, the latter of the two will be used:
h1 {
font-size: 12px; /* 1. Font size set to 12px */
font-size: 1rem; /* 2. Font size set to 1rem, overriding previous value */
}
In this example, rem will be used on browsers which support that unit, and px will be used on those which do not.
h1 {
font-size: 1rem; /* 1. Font size set to 1rem */
font-size: 12px; /* 2. Font size set to 12px, overriding previous value */
}
In this example, px will be used on both browsers which support rem and browsers which do not.
Can I Use... will give you a better overview of which browsers support this unit.
As for performance, each character contained within a CSS file equates to 1 byte. The more bytes contained within your stylesheet, the longer it will take a browser to download it. So of course, adding px values alongside rem values will ultimately add to the download time, but most of the time this is negligible.
As for whether Android devices come bundled with Chrome: no, this is not the case. This is entirely up to the manufacturer.
Either style declaration will work for you - if a browser doesn't support rems it will fall back to the pixel value.
This is one of those situations where I set the html font-size to 62.5% to take the base font-size down to 10px. This makes the calculations very straight forward and is easy to spot errors in your type declarations.
html {
font-size: 62.5%;
}
body {
font-size: 14px;
font-size: 1.4rem;
}
UPDATE: Please note that I am seeing this issue only in Chrome (latest version). Everything seems to be fine in Firefox.
By definition:
The rem unit is relative to the root—or the <html>—element. That means
that we can define a single font size on the <html> element and define
all rem units to be a percentage of that.
Let me explain my situation with an example...
Relevant CSS:
html {
font-size: 87.5%;
}
body {
font-size: 17px;
font-size: 1.21428571rem;
}
code {
font-size: 14px !important;
font-size: 1rem !important;
}
I am using the !important declaration to override the font-size of inline code.
The thing is, I noticed that the font-size of code blocks is much smaller than 14px, most probably 12px. But if I remove the !important declaration and set the font-size on a specific code element (styling a specific inline code element), the fonts-size is nice and fine at what appears to be 14px.
Does you have any idea as to how !important declarations may affect sizing in rem's? (Especially considering in my case.)
First off !important is lazy coding and dangerous to maintainability. It's toxic and breaks the nature of CSS (the Cascading portion). Avoid it at all costs.
Second:
code {
font-size: 14px !important;
font-size: 1rem !important;
}
Might as well be written:
code {
font-size: 1rem !important;
}
The second rule overrides the first (again, the Cascading nature of CSS)
rem stands for root em, which is the font-size of the top level element (i.e., html)
and what your rule is saying 1 x the em of the html element, with is 87.5% of the browser default.
EDIT:
Your <p> tags have a font-size of 100% inherited from the parent element which is eventually inherited from body and body has a 1.2142857rem which is roughly 17px This is why you're seeing a difference in font sizes, which is also exacerbated by the the difference of monospace and sans serif fonts.
Okay, the issue was with (1) font-family not defined for code and pre blocks, which meant Chrome and other webkit browsers chose some monospace font that appears smaller (2) line-height was smaller (almost equal to the font-size).
Fixing these two has solved the problem.
I have no idea why Chrome Dev Tools Web Inspector's "Computed Style" shows 11px as the font-size (also applies to any webkit browser, including Safari). I can confirm that it's showing the wrong value because by changing the font to Arial I could easily tell that it's 14px.
Also, after setting the font-family on code and pre blocks, Chrome now shows the correct computed font-size value.
I noticed that in Chrome and Safari, my Courier text is tiny. In Internet Explorer and Firefox, the Courier text is comparable in size to the rest of my text. Is there something wrong with my CSS?
#article pre,
#article code {
display: block;
font-family: courier, monospace;
background: #f7f7f7;
padding: 0.6em;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border: 1px solid #ddd;
margin: 0 0 1em 0;
}
Yeah, WebKit has separate default font size preferences for normal and monospaced fonts. When you use a font size derived from a relative font size (ie none of the text's ancestor elements have an absolute font size), you get different sizes for monospaced and normal fonts.
(This wouldn't necessarily be a bad thing, except that the default preference of much smaller monospaced fonts isn't really sensible and most users won't have changed it.)
I think this has changed over different versions; originally IIRC the different base font size for monospaced fonts was applied to any element whose font-family list had monospace in it. Now this behaviour only seems to happen when the font-family property is set to exactly monospace. Your example of courier, monospace doesn't trigger it for me; weirdly, neither does it happen with monospace, sans-serif, even though then the font will always be monospace and sans-serif will never be used. This behaviour matches Firefox.
You're probably not defining a font-size anywhere, so it's falling back to browser default.