Icon font rendering inside auto centered div is blurry/crisp based on browser width - css

i wanted to jump on the icon font train, but was quickly put off by the renderer.
When an icon is sitting inside a div that has either percentage width or is automatically centered the icon can be aligned to a half pixel causing it to be rendered blurry.
I was in contact with Icomoon support who intoduced me to a bug that said it is Chrome specific. (https://bugs.chromium.org/p/chromium/issues/detail?id=426333) unfortunately I was able to reproduce the issue in all of the major browsers.
The recommendation I got was to avoid auto margin and to use only float left which in today's world isn't really possible. And even if I do that i'd still clash with precentage widths.
Question
Is there any way to preven't the blur from occuring? I guess using inline-svgs would be an option right? But that kinda beats the whole purpose of the Icon Font. Or having a script that rounds everything up to whole pixels but that sounds extreme as well.
Steps to reproduce the issue
I have created a 24px set of icon on Icomoon, downloaded the set which comes with a demo.html. Then I just to the main wrapper of the demo, and gave it a fix width and margin 0 auto. Then by resizing the browser width I was able to make the icons blur or be crisp..
Chrome
Blurry:
Crisp:
Firefox
Blurry:
Crisp:
Opera
Blurry:
Crisp:
Edge
Blurry:
Crisp:
Internet Explorer
Blurry:
Crisp:

If someone can provide evidence that this is what's actually happening in the browser implementations that would be ideal, but this answer is based on your even/odd pixel values you mentioned in the question and is what I believe to be the most likely cause.
Fonts and Icon Fonts are Vectors
On a basic level, icon fonts are vectors. This allows the icons to scale regardless of font size and not become blurry. Blurriness can however occur when the edges of the vectors do not line up with the edges of pixels.
Vector vs Pixel Rendering
To steal from the Font Awesome Icon Design Tips Guide, you can see two demonstrations below. The top image is a vector with a bunch of 1px wide lines, spaced 1px apart, but they're offset by 0.5px. When rendered as pixels without being zoomed in, this causes them to become blurred as the pixel must take 50% of the line colour, and 50% of the background colour.
Vector edges that don't line up with the pixel edges. (The blue representing the 0.5px offset from the pixel edge).
On the other hand, the image below has the vectors lined up, so that either edge of the lines/bars, lines up with the edges of the pixels. Therefore when rendering at a pixel level, no pixels have to merge the background and line colours.
Correctly aligned vectors
To see more examples to explain this in more detail, I'd recommend reading the full guide which also explains crisp diagonal edges too.
Browser Rendering and High DPI Screens
Browsers now have to deal with high DPI/retina screens, which make it really easy to have "centered" text because you have 2 actual pixels per CSS px width; therefore you can draw crisp lines every 0.5px.
Judging by your images, you're using a regular DPI screen to view the fonts, and therefore when the browser is forced to render the icon at a 0.5px value, the edge of the vector lies in the middle of a pixel, rather than half way, meaning that pixel has to take 50% of the background colour, and 50% of the icon colour, causing the blurred edge.
As for a solution, I sadly don't have a lower res monitor on hand to test. Your aim is to make the edge of the icon render on the edge of the pixel boundary which will require some fiddling, but here are some things you could try:
Setting your icon to display: inline-block instead of the default display: inline that text tends to have. (Unlikely to work, but it might).
Wrapping your icon in a fixed-width div just larger than the icon size that can then be centered.
If using the div method, try the difference with left aligning or center aligning the text.

In my experience, blurry fonts are often the result of how the icon was created. Font Awesome has some good tips on designing crisp icon fonts.

Related

How to implement padding-free sprites in css?

While learning how to use css sprites, I quickly noticed and/or read that it is best to have 1 or 2 empty pixel space between all images inside a sprite to avoid other images bleeding through when the user zooms in or out.
While looking at the apple homepage, I noticed that they don't do this, without suffering from bleeding images. I did not find any reason in their css that would explain this.
How is that possible? ;)
There's no need for padding between sprites if you know exactly what size the containing element is going to be. The problem comes from when something inside the element causes it to grow. For example, if the text inside that element has to use a fall-back font it may end up causing the container to grow.
The reason padding between sprites is recommended is that there's no real downside to it. It doesn't increase the file size by any meaningful amount and it gives you a bit of a safety margin when a browser does something slightly different than you expect.
It seems like it is indeed necessary, because when the browser deems it necessary to scale the cropped areas (for example, if one zooms in or out or if an animation temporarily changes the size) the browser will use anti aliasing to smoothen the scaled image. Since anti aliasing uses surrounding pixels, the most outer pixels of a crop will be influenced by those that lie outside of the cropped area.
The transparent padding ensures that this doesn't happen since the transparent padding wouldn't affect the resulting color. Without padding, the cropped pictures would affect each other.
This can easily be tested by filling the (theoretically invisible) padding area with a color like magenta and then zoom in or out in one's page, all crops will have a bit of magenta on their edges.

Background Image not scaling in td

I am on a team trying to convert our Flash Application into HTML5 and Css, and I am running into a bug affecting WebKit and wanted some help trying to figure it out. The basic idea is that there is a table with a single cell with a background image and a background color and for whatever reason when the image is exactly the right size background-size: 100% 100% the image actually shrinks to reveal the background color. This also repeats if I use pixel values instead of % values.
Before anyone tells me to just use a div (since its only one cell anyway), this content is authored by other people who are using an existing tool to create a custom xml document that gives us tables and I have to get my solution to work on the pre-existing content we already have.
This is the fiddle which shows it and follows are image in various browsers:
http://jsfiddle.net/CEvnx/2/
Flash (Reference)
Firefox (working)
Chrome (the image shrinks)
Safari (the image grows)
P.S. Ignore the height and font differences as those aren't in any way relevant to the problem.
has to do with the table's border-width, if you set border-width at 2px or less the background sizes correct (in Chrome/Safari). Quite strange that Chrome shrinks and Safari grows. There must be some odd math or image resize logic in webkit and probably worth submitting a bug report.

Firefox not anti-aliasing scaled background svg

I'm working on a responsive design that requires the header graphic to scale with the width of the viewport. I've gone for an svg thinking that this would scale well. (I test for svg support in the full site, and replace a gif with the svg).
In Firefox (13.0 on Windows 7) it's not antialiasing it at small sizes. It occassionally looks good at some sizes, and does if I fix the dimensions, but I want to avoid doing that.
Chrome and Safari do anti-alias the image, and it looks good.
I'm setting the background-size: 100% 100% to scale to the container, I've tried things like cover as well, but seems to make no difference.
I've tried adding image-rendering: optimizeQuality; as well, but this doesn't seem to have helped.
I've set up a test page at http://axminster.digital.linneydesign.com/svg/ - the top one is the background image, and the one beneath is exactly the same file, but added in the html directly as an img. Scaling the browser down to small sizes, you'll see the top one pixelate, but the bottom one will stay smooth.
Any thoughts on how I can smooth this background image without fixing its dimensions?
thanks.
Give the outer <svg> element in the svg file (sophie-conran.svg) a width and height of 100%.
What happens is that the svg image is rasterised at the width and height you give it i.e. 1000px x 350px and that bitmap is then converted to the required size. If you make the width and height percentages then the bitmap is created at final size and there's no bitmap scaling.
Update:
This is all moot with Firefox 24 and beyond though, you can do what you like and it will always work properly i.e. without pixellation.
The solution is to include the SVG as a tag, not as an external file.
Firefox will apply the anti-aliasing correctly.

CSS border scaling

I have a set of A tags with display set to block. Each each is specifically has a border on the right. They fit perfectly into a container. However, when the page is zoomed out using the browser's zoom control, everything but the borders scale and the layout is broken. Is there a way to fix this?
This behavior can be replicated in Firefox 3.6.10 and Safari 4.
I had never before noticed that the borders do not scale.
try to set the border-with in em instead of px - if your font-size is 12px, you could write
border-width: 0.09 em;
this will be 1px width in normal size, and hopefully it scales correct (can't test it now, sorry).
There are other things that won't scale either -- radio buttons and select boxes are the classic ones, though it does differ between browsers.
Also, you'll get different effects depending on the sizing units you use for your CSS -- ie whether you use %, px or em, etc. Again, this will vary between browsers.
So the bottom line is that using the browser's zoom function is likely to break things on your layout. I honestly wouldn't expect things to be perfect with zoom, nor the same results in different browsers.

Why do dpi settings over 96 screw up my site?

I noticed that when the dpi is set high than 96 to like 120 my site gets messed up using either Firefox or IE7. The CSS basically breaks. Anyone know how to fix this?
Link to web-site
Thanks
The site uses a fixed-size layout, but mixes the units px and pt. When changing the dpi of your screen, the relative size of these units changes, ie the site is broken by design.
What you should do:
don't use pt for screen layouts - pt is for printing only
read up on liquid layouts and the relative unit em
There's not really a fix that can prevent anything happening if a user has adjusted their Windows DPI setting. Altering Windows to 'large fonts' mode, or setting it to a DPI setting other than the default, affects all layout in IE.
However, this should never cause a site to massively break. A few things shall be slightly misaligned, perhaps, due to rounding of values.
The site you've pointed to indeed does break quite massively when the font size is changed - for instance, change the default font in the browser (or set Firefox to "Zoom Text Only"). Text from the buttons completely leaves the buttons and starts hovering elsewhere.
It looks like the main cause of this, at least with the buttons across the top, is that the whole row of buttons is single background image and the text inside them are floated elements which match up with the background image only at a given font size - any adjustment to their size and position and they become out of whack with their background.
When designing, always change the zoom setting (in IE7 and Firefox) and the font size (eg in Firefox using "Zoom Text Only") and make sure that those things that do change in size, don't break the site. In some conditions, things specified in "pt" will scale while things specified in "px" won't.
How you could fix it
It's clear that you've designed everything to be a certain size in pixels, including the header and all the buttons/tabs. If you want to do this, declare the header DIV to be position: relative, and position the H1, H2, and UL inside it absolutely, using pixel values (relative to the containing div). Remove the margins, padding etc from the DIV to simplify. Specify widths, heights and top margins of the LI elements using pixels.
What I would do
Normally, I would build things like this to be flexible, so that if for some reason a person had really big fonts enabled on their browser, it would stretch nicely to handle it. That isn't really possible with your background images, because they are build especially for one given size only. So I'd have a repeatable background on the header, and I'd do each background for each button separately. Obviously, this is going to be more work.

Resources