Monday 13 October 2014

CSS measurement unit

CSS has two forms of measurement, absolute and relative. As a general rule, relative units are preferentially used for responsive and mobile design; absolute units tend to be used for fixed-width designs.
AbsoluteRelative
CSS Unit CSS AbbreviationCSS UnitCSS Abbreviation
PixelspxPercent%
PointsptEmem
InchesinExex
CentimeterscmRoot emrem
PicaspcViewport widthvw


Viewport heightvh


Viewport minimumvm


characterch


Gridgd
rem, vh, vw are CSS3 measurement units, supported by modern browsers.
1em is the width of the m character in the default font set for that browser. (ex is the height of the x character in a font). rem allows you to set a root font size for size for the entire page, with sizes for elements relative to this measurement:
html { font-size: 62.5%; }
body { font-size: 1.4rem; }
h1 { font-size: 2.4rem; }
(The measurements above are used because they map exactly to pixels: with a base font-size of 62.5% for a page, the body size maps to 14 pixels, and h1 to 24 pixels.)
The viewport is the browser window: vh, vw and vm can scale elements to its current size. This could be used to restrict the upper scaled size of images, for example:
img { max-width: 90vw; }
ch is the equivalent of em, but applied to the width 0 numeral of the chosen font.
gd relates to the CSS3 grid; unfortunately, only IE10 browser yet supports the grid module at this time.
You never need to specify units when declaring a value of 0: zero centimeters is the same as 0 pixels. In all other cases, units of measurement should be declared 2em, 2px, etc, not 2.
With the exception of pixels, all systems of measurement can take floating point values: 2.25em, 5.3cm, etc.
Generally speaking, CSS written for screen display devices should use relative units (percent, em and ex), with few exceptions (such as fixed-with bitmapped images, and hairlines (i.e. 1 to 5 pixel width borders)).

Fluid Image techanique, for responsive design

“Responsive design” is not a single technology but a set of techniques* that allow web pages to serve the needs of both mobile and desktop users. The core components are:
  • CSS @media queries
  • Fluid images and video
  • JavaScript, often triggered by window.matchMedia
  • Server-side solutions
  • SVG to create resolution-free images
A responsive site may utilize one, some, or all of these technologies, depending on the intentions of its designers. I’ve covered the basics of media queries in past articles; now it’s time to look at fluid images.
Web page text is fluid by default: as the browser window narrows, text reflows to occupy the remaining space. Images are not naturally fluid: they remain the same size and orientation at all configurations of the viewport, and will be cropped if they become too large for their container. This creates a conundrum when displaying images in a mobile browser: because they remain at their native size, images may be cut off or displayed out-of-scale compared to the surrounding text content as the browser narrows.

Simple Fluid Images

One way around this is to size images in relative units, rather than absolute pixel dimensions. The most common relative solution is to set the max-width of the image at 100%:
<img src="royal-enfield-motorcycle.jpg" style="max-width:100%;height:auto;">
Images with this CSS will display at their native dimension so long as there is enough room in the HTML container to do so; as the browser window narrows, the images will scale to fit, as you can see in the illustration above.
This works well, as with a few limitations:
  • A large image (over ~ 420 pixels wide) will increasingly dominate the document as the view-port shrinks down, as its native size is greater than the width of most smartphones. Scaling means that the image won’t be cut off, but it may be large relative to text at small view-port sizes.
  • The initial layout and setup of the document is affected: because you are not setting the image’s height and width explicitly in the CSS, the browser cannot reserve any space for the image in the page. This will often cause the layout to “pop” when the user visits the page for the first time, as fluid images are loaded and forced to fit into their newly determined size.
  • Unless the image is already the full width of its container, this approach does not work well for HiDPI/Retina images: the image’s “actual size” will be shown as twice the width that you want it to be.
The basic max-width fluid image approach is a very good approach for article header and “hero” images, but for illustrations in body text, a more subtle approach is often required.

A Better Fluid Image Solution

A better, albeit more complex approach to fluid images is to measure the width of the image as a percentage of the overall width of the page.
For example, let’s say you had an image that had a natural size of 500px × 300px in a 1200px wide document. Below 1200px, the document will be fluid. The calculation of how much width the image takes up as a percentage of the document is easy: (500 / 1200 ) × 100 = 41.66%
We can plug this number in as the width for the image; typically, this would be done inline, as each image will often be a different dimension:
<img src="emample.jpg" style="float: right; width:41.66%;margin-left:2rem">
 
This accommodates Retina pixel-doubled images, but can run into issues at extremes of large or small viewport sizes, when the image might appear too big or small relative to the text. To get around this, we can place a max and/or min width on the image in pixels as upper and lower limits:
<img src="emample.jpg"style="float: right; width:41.66%;margin-left:2rem;max-width:500px;"> The type of approach you use will depend on both the kind of image and the overall design of the site; there is also the possibility of transitioning the flexible images between breakpoints with a hybrid technique that utilizes media queries: we’ll look at that in the next article.

Improving Browser Performance

Specifying only the width of images may cause a doubling or tripling of the cycles that many browsers must process to layout the new, resized page. While each of these cycles typically take less than a millisecond, they stack up, especially if there are multiple scalable elements on the page. Addressing height in the same declaration can reduce this issue:
<img src="emample.jpg" style="max-width:100%;height:auto;">

Image Optimization

Optimizing your website images can save a lot of bandwidth and improve page speed considerably. All you need is a little time and a few tools.
Recommendations reflect what I stick to on websites, after considering the pros and cons. Where appropriate a link to a discussion is provided so you can form your own opinion.
This tutorial focuses on directly optimizing the images used. It does not discuss server side image processing, which is a different topic altogether.

Covered in this tutorial

  1. Which image format for which usage?
  2. Which JPEG format to use, baseline or progressive?
  3. Size considerations and compression
  4. What about high resolution and retina screens?
  5. Making images responsive in your design
  6. Free tools for (batch) optimizing images on Windows
  7. Optimizing existing website images in bulk
  8. General recommendations and recap

1. Choosing image file formats

.GIF (Graphic Interchange Format)
  • Loss-less file format, limited to 256 colors, supports transparency and animation.
  • Only use this for very small things like flags or icons.
  • Otherwise very 1998 ...
.JPG or .JPEG (Joint Photographic Experts Group)
  • Lossy compression file format, no transparency.
  • Use for photographs and complex big images.
  • Two of the main types in this format are baseline and progressive.
  • See below under "2. Which JPEG format to use, baseline or progressive?" and under "3. Size considerations and compression"
.PNG (Portable Network Graphics)
  • Loss-less data compression, supports transparency.
  • Excellent for smaller images like category images, menu images, flags, etc.
  • Usually not recommended for big photographs (because of bigger file size).
.WEBP (Weppy)
  • Both lossy and loss-less compression file format, developed by Google.
  • Native browser support on Chrome and Opera, plugins needed for most other browsers.
  • Native support in most CMS's (including Joomla).
  • The average WebP file size is 25% – 34% smaller compared to jpeg file size.
  • Image quality and support considerations make me not choose it, despite file size improvements.
.SVG (Scaleable Vector Graphics)
  • Loss-less data compression. Defined in XML text files. Can be searched, indexed, scripted, and compressed.
  • Supported by all major modern browsers. Scale without loss of quality, support animation.
  • Use for simpler images, complex images and photographs encoded in SVG result in enormous file sizes.
  • For IE9 they can be used to solve an issue with a gradients & rounded corners combination (CSS3 gradients poke through element borders with IE9).
Click here for details on browser support for various file formats.

2. Which JPEG format to use, baseline or progressive?

Baseline JPEG renders the image directly in the quality used.
Progressive JPEG renders a lowers image first and then progressively enhances the quality on further download. On Google images you can see this effect these days, fuzzy first, clear later. I do not care for it much myself...
Lately there has been renewed interest in the old progressive JPEG format because it is recommended by Google's Page Speed and because many people argue it's better to present mobile users (with limited bandwidth) with a lower resolution image first.
Another argument for progressive JPEG states that it prevents jumbling of website elements before the image is completely loaded. Which can and should be avoided anyway by properly setting at least the image width on the elements in your CSS.
My personal take on this is that I prefer to use baseline, as the bandwidth factor is offset by the 3x increased memory and processing requirement for mobile users when using progressive JPEG.
Here is a good and very lengthy discussion on the pros and cons of each if you want to form an opinion of your own (read all the comments too):

3. Size considerations and compression choices

Image size influences page rendering speed and bandwidth usage, so the smaller the better as long as image quality is preserved. In practice, 60-70% jpeg quality is a good balance between quality and size.
Image   Dimensions   Quality   Format   Size      After tools
peony   800x429      100%      PNG      466 KB    445 KB
peony   800x429      100%      JPG      256 KB    224 KB
peony   800x429       60%      JPG       65 KB     64 KB
peony   800x429       30%      JPG       30 KB     30 KB
peony   400x215      100%      PNG      133 KB    127 KB
peony   400x215      100%      JPG       69 KB     69 KB
peony   400x215       60%      JPG       22 KB     21 KB
For the 800x429px JPEG the difference between 100% and 60% quality is a whopping 256 - 64 = 192 KB saved. In a folder with 15 images that means 2880 KB page load / bandwidth saved. The quality is reasonable however at 60%.

4. What about high resolution and retina screens?

Create separate images for highers (retina) screens if needed. Make them 150-200 percent in size with a 30-40 percent quality (and specify width and auto-height in the CSS to scale them down again). The result is a JPEG with good quality and reasonable size (in our example image 30KB for 800x419 at 30%, 21KB for 400x215 at 60%). Try it out yourself to check the quality of the end result.

5. Making images responsive in your design

At present there is no foolproof way of providing responsive images server side without some hacks or compromises. When standards catch up with responsive images things will probably change big time. Click this link for a discussion on this subject.
Some solutions provide the responsiveness by applying classes to the img tag in CSS, which is not very neat. Until there is a standards compliant technique available, I recommend letting the browser engine do this trick for you, at least for now. Even if there are some drawbacks (letting the client do the resizing work) I feel it is preferable to use non-validating hacks.
Simply set max-width and auto height for the img tag in the element involved, like this:
img { max-width: 100%; /* or px or ems or rems instead of percentage */ height: auto; }