The key to handling images is to use relative widths to prevent them from accidentally overflowing the container and eventually the viewport, so it is better to pre-set the width of all image tags to 100%. In fact it is recommended to do that on img
, video
, embed
and object
elements:
img, video,
embed, object {
max-width:100%;
}
and in case you want to have multiple images in one row , just use relative widths.
E.G. Let's say you have two images and want each one to takes up half the viewport with a 10px margin between them calc()
gives us the ability to mix absolute and relative values:
img {
max-width: calc((100% - 10px)/2);
margin-right: 10px;
}
img:last-of-type {
margin-right: 10px;
}
1- The srcset
and size
attribute gives you the ability to provide multiple images that will be served by the browser depending on viewport width/hight or device resolution within the img element.
To use the srcset
provide a comma separated string with:
- The path to the image file
- A space
- The pixel density with
nx
or width withw
of the image
srcset
with pixel density:
<img src="[filename].[ext]"
srcset="[filename]-2x.[ext] 2x,
[filename]-3x.[ext] 3x,
[filename]-4x.[ext] 4x">
The nx
denotes the pixel density (DPR), where n is an integer.
Note: the image in the src
tag is assumed to be 1x and also works as a fallback incase the browser doesn't support srcset
.
srcset
with width:
<img src="[filename].[ext]"
srcset="[filename]-[width-1].[ext] [width-1]w,
[filename]-[width-2].[ext] [width-2]w,
[filename]-[width-3].[ext] [width-3]w">
Note: it's a good practice to include the width and pixel density of the image in image filename.
2- The sizes
attribute only works in conjuction with the width value of the srcset
and it allows us to set some media conditions in which the right image size will be used.
<img src="one.png"
srcset="[filename]-[width-1].[ext] [width-1]w,
[filename]-[width-2].[ext] [width-2]w,
[filename]-[width-3].[ext] [width-3]w"
sizes="[media condition] [width-1],
[media condition] [width-2],
<optional default image width>">
Note: you can specify absolute (px, em, ..), relative (vw) width values or both with calc()
, but not percentages.
Putting it all together:
<img srcset="myImage-320w.jpg 320w,
myImage-480w.jpg 480w,
myImage-800w.jpg 800w"
sizes="(max-width: 320px) 280px,
(max-width: 480px) 440px,
800px"
src="myImage-800w.jpg" alt="My image description">
The HTML
picture
element serves as a container for zero or moresource
elements and one img element to provide versions of an image for different display device scenarios.
<picture>
<source media="(min-width: 800px)"
srcset="myImage.jpg, myImage-2x.jpg 2x">
<source media="(min-width: 450px)"
srcset="myImage-small.jpg, myImage-small-2x.jpg 2x">
<img src="myImage-fallback.jpg"
srcset="myImage-fallback-2x.jpg 2x"
alt="My image description">
</picture>
Looking at the media condition in the media
attribute and the pixel density in the srcset
, the picture
element will choose the right image to display, and in case the picture element is not supported or none of the media conditions returned true.
Note: The alt
attribute and css manipulation should be done through the img
element and not the picture
or source
elements.
The picture
element can also be used to serve different image types depending on the browser support. So for example if you want to serve WebP format format, but you want to set a fallback for browsers that don't support it:
<picture>
<source srcset="myImage.webp" type="image/webp">
<img src="myImage.jpg" alt="My image description">
</picture>
Of course this can be mixed with media conditions, image widths or pixel density.
Note: If you want to know which image has been chosen by the browser with javascript use image.currentSrc
. Of course if you want to a fallback for older browsers just use image.currentSrc || image.src
, this case you'll handle all cases.
Make sure to always provide the img element with meaningful descriptions via the alt
attribute; these help make your site more accessible by giving context to screen readers and other assistive technologies.
-
alt
attributes should be descriptive for important images. -
alt
attributes should be empty for images that are just decorationsalt=""
. -
alt
attributes should be set on every image.
An optimized resource is a resource not sent.
this rule applies to images too.
That said, a well-placed image can also communicate more information than a thousand words.
You should consider if there is an alternative technology that could deliver the desired results:
- CSS effects (animations, gradients, shadows, ...etc.) can be used to produce resolution-independent assets that always look sharp at every resolution and zoom level, often at a fraction of the bytes required by an image file.
- web fonts can be used instead of encoding text in images, which enables the use of beautiful typefaces while preserving the ability to select, search, and resize text - a significant improvement in usability.
Note:
Although CSS effects are in some cases a great alternative to images, be aware that there is a processing and rendering cost to using them (CSS effects) especially on mobile, use them sparingly.
If that image resource is necessary to your design, then, the next thing to do is choose the appropriate format and it comes down to two choices Raster Graphics or Vector Graphics.
Vector:
- How it works: uses lines, points, and polygons to represent an image.
- Is it zoom/resolution independent?: Yes! Vector Graphics deliver sharp results at every resolution and zoom setting, which makes them an ideal format for high-resolution screens and assets that need to be displayed at varying sizes.
- Ideal for: vector formats are ideally suited for images that consist of simple geometric shapes (for example, logos, text, icons, and so on).
Raster:
- How it works: Raster Graphics represent an image by encoding the individual values of each pixel within a rectangular grid.
- Is it zoom/resolution independent?: No. When you scale up a raster image you'll see jagged and blurry graphics. As a result, you may need to save multiple versions of a raster image at various resolutions to deliver the optimal experience to your users.
- Ideal for: Photographic images or images with complicated scenes.
Also Vector images have small file sizes compared to Raster images.
High resolution screens require high resolution images, but that's not the case for vector images since they are zoom/resolution independent. On the other hand raster images encode image data on a per-pixel basis, that's why the larger the number of pixels, the larger the filesize of a raster image.
That said choose vector images over raster images whenever possible as they are resolution independent and always deliver sharp results, and if a raster image is required, deliver and optimize multiple variants of each image with the help of srcset and picture.
- Do you need animation? If so, GIF is the only universal choice.
- GIF is the right answer only when animation is required.
- Do you need to preserve fine detail with highest resolution? Use PNG.
- PNG produce the highest quality image, but at a cost of significantly higher filesize than other formats. Use judiciously.
- If the image asset contains imagery composed of geometric shapes, consider converting it to a vector (SVG) format!
- If the image asset contains text, stop and reconsider. Text in images is not selectable, searchable, or "zoomable". If you need to convey a custom look (for branding or other reasons), use a web font instead.
- Are you optimizing a photo, screenshot, or a similar image asset? Use JPEG.
- Try several JPEG quality levels to find the best quality vs. filesize tradeoff for your asset.
One of the simplest and most effective image optimization techniques is to ensure that we are not shipping any more pixels than needed to display the asset at its intended size in the browser. So, you should ensure that the number of unnecessary pixels is minimal, and that your large assets in particular are delivered as close as possible to their display size.
And here is why
Screen resolution | Natural size | Display size (CSS px) | Unnecessary pixels |
---|---|---|---|
1x | 110 x 110 | 100 x 100 | 110 x 110 - 100 x 100 = 2100 |
1x | 410 x 410 | 400 x 400 | 410 x 410 - 400 x 400 = 8100 |
1x | 810 x 810 | 800 x 800 | 810 x 810 - 800 x 800 = 16100 |
2x | 220 x 220 | 100 x 100 | 220 x 220 - (2 x 100) x (2 x 100) = 8400 |
2x | 820 x 820 | 400 x 400 | 820 x 820 - (2 x 400) x (2 x 400) = 32400 |
2x | 1620 x 1620 | 800 x 800 | 1620 x 1620 - (2 x 800) x (2 x 800) = 64400 |
You can reduce the number of file requests by inlining images as svg or data uri (of course not all images can be svg, unfortunately) and knowing the right time to take advantage of this technique over external images (and vice-versa) can be beneficial to your website's performance.
Data URI is commonly used to embed images and web fonts onto html to reduce network requests and it works by embeding the base64-encoded data directly into the HTML or CSS, using the following format:
data:[MIME-type][;charset=encoding][;base64],[data]
and it works like this in HTML:
<img alt="" src="data:[MIME-type][;charset=encoding][;base64],[data]" />
& in css like this
.some-elem {
background-image: url(data:[MIME-type][;charset=encoding][;base64],[data]);
}
SVG can also be embeded inline, but only in HTML. To embed svg in a stylesheet you need to convert it to data uri.
Now to go back to the question, Should you use inline or external?
- Are re-using the image? It'd be better if it's external. That way you'll be able to cache it and not reload it everytime a user vists a new page.
- Are you intending to use responsive images? It makes more sense to use external, cause inlining images can limit your responsive options.
Note: Always make sure to test both inline and external images to see which one is best suited for your case.
This is only used as personal notes following the Udacity Mobile Web Specialist and other articles that will be listed below. If you find a mistake please be kind to point it out :).
- Udacity course on Responsive Images
- Google Web Training - Responsive Images
- Image Optimization
- How To Make Your Websites Faster On Mobile Devices
- Responsive Images - The srcset and sizes Attributes
- srcset and size
- MDN - Responsive Images
- Responsive Images: Use Cases and Documented Code Snippets to Get You Started
- Formatting your images for display on the web
- High DPI Images for Variable Pixel Densities