CINXE.COM
Responsive images | Articles | web.dev
<!doctype html> <html lang="en" dir="ltr"> <head> <meta name="google-signin-client-id" content="157101835696-ooapojlodmuabs2do2vuhhnf90bccmoi.apps.googleusercontent.com"> <meta name="google-signin-scope" content="profile email https://www.googleapis.com/auth/developerprofiles https://www.googleapis.com/auth/developerprofiles.award"> <meta property="og:site_name" content="web.dev"> <meta property="og:type" content="website"><meta name="theme-color" content="#3740ff"><meta charset="utf-8"> <meta content="IE=Edge" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="manifest" href="/_pwa/web/manifest.json" crossorigin="use-credentials"> <link rel="preconnect" href="//www.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.googleapis.com" crossorigin> <link rel="preconnect" href="//apis.google.com" crossorigin> <link rel="preconnect" href="//www.google-analytics.com" crossorigin><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"> <link rel="stylesheet" href="//fonts.googleapis.com/css2?family=Material+Icons&family=Material+Symbols+Outlined&display=block"><link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/css/app.css"> <link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/css/dark-theme.css" disabled> <link rel="shortcut icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/favicon.png"> <link rel="apple-touch-icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/touchicon-180.png"><link rel="canonical" href="https://web.dev/articles/responsive-images"><link rel="search" type="application/opensearchdescription+xml" title="web.dev" href="https://web.dev/s/opensearch.xml"> <link rel="alternate" hreflang="en" href="https://web.dev/articles/responsive-images" /><link rel="alternate" hreflang="x-default" href="https://web.dev/articles/responsive-images" /><link rel="alternate" hreflang="ar" href="https://web.dev/articles/responsive-images?hl=ar" /><link rel="alternate" hreflang="bn" href="https://web.dev/articles/responsive-images?hl=bn" /><link rel="alternate" hreflang="zh-Hans" href="https://web.dev/articles/responsive-images?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant" href="https://web.dev/articles/responsive-images?hl=zh-tw" /><link rel="alternate" hreflang="fa" href="https://web.dev/articles/responsive-images?hl=fa" /><link rel="alternate" hreflang="fr" href="https://web.dev/articles/responsive-images?hl=fr" /><link rel="alternate" hreflang="de" href="https://web.dev/articles/responsive-images?hl=de" /><link rel="alternate" hreflang="he" href="https://web.dev/articles/responsive-images?hl=he" /><link rel="alternate" hreflang="hi" href="https://web.dev/articles/responsive-images?hl=hi" /><link rel="alternate" hreflang="id" href="https://web.dev/articles/responsive-images?hl=id" /><link rel="alternate" hreflang="it" href="https://web.dev/articles/responsive-images?hl=it" /><link rel="alternate" hreflang="ja" href="https://web.dev/articles/responsive-images?hl=ja" /><link rel="alternate" hreflang="ko" href="https://web.dev/articles/responsive-images?hl=ko" /><link rel="alternate" hreflang="pl" href="https://web.dev/articles/responsive-images?hl=pl" /><link rel="alternate" hreflang="pt-BR" href="https://web.dev/articles/responsive-images?hl=pt-br" /><link rel="alternate" hreflang="ru" href="https://web.dev/articles/responsive-images?hl=ru" /><link rel="alternate" hreflang="es-419" href="https://web.dev/articles/responsive-images?hl=es-419" /><link rel="alternate" hreflang="th" href="https://web.dev/articles/responsive-images?hl=th" /><link rel="alternate" hreflang="tr" href="https://web.dev/articles/responsive-images?hl=tr" /><link rel="alternate" hreflang="vi" href="https://web.dev/articles/responsive-images?hl=vi" /><link rel="alternate" hreflang="en-cn" href="https://web.developers.google.cn/articles/responsive-images" /><link rel="alternate" hreflang="x-default" href="https://web.developers.google.cn/articles/responsive-images" /><link rel="alternate" hreflang="ar-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=ar" /><link rel="alternate" hreflang="bn-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=bn" /><link rel="alternate" hreflang="zh-Hans-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=zh-tw" /><link rel="alternate" hreflang="fa-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=fa" /><link rel="alternate" hreflang="fr-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=fr" /><link rel="alternate" hreflang="de-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=de" /><link rel="alternate" hreflang="he-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=he" /><link rel="alternate" hreflang="hi-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=hi" /><link rel="alternate" hreflang="id-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=id" /><link rel="alternate" hreflang="it-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=it" /><link rel="alternate" hreflang="ja-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=ja" /><link rel="alternate" hreflang="ko-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=ko" /><link rel="alternate" hreflang="pl-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=pl" /><link rel="alternate" hreflang="pt-BR-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=pt-br" /><link rel="alternate" hreflang="ru-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=ru" /><link rel="alternate" hreflang="es-419-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=es-419" /><link rel="alternate" hreflang="th-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=th" /><link rel="alternate" hreflang="tr-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=tr" /><link rel="alternate" hreflang="vi-cn" href="https://web.developers.google.cn/articles/responsive-images?hl=vi" /><title>Responsive images | Articles | web.dev</title> <meta property="og:title" content="Responsive images | Articles | web.dev"><meta name="description" content="A picture is worth 1000 words, and images play an integral part of every page. But they also often account for most of the downloaded bytes. With responsive web design not only can our layouts change based on device characteristics, but images as well."> <meta property="og:description" content="A picture is worth 1000 words, and images play an integral part of every page. But they also often account for most of the downloaded bytes. With responsive web design not only can our layouts change based on device characteristics, but images as well."><meta property="og:url" content="https://web.dev/articles/responsive-images"><meta property="og:locale" content="en"><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Article", "dateModified": "2014-04-29", "headline": "Responsive images" } </script><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{ "@type": "ListItem", "position": 1, "name": "Articles", "item": "https://web.dev/articles" },{ "@type": "ListItem", "position": 2, "name": "Responsive images", "item": "https://web.dev/articles/responsive-images" }] } </script> <link rel="stylesheet" href="/extras.css"></head> <body class="" template="page" theme="web-theme" type="article" appearance layout="docs" display-toc pending> <devsite-progress type="indeterminate" id="app-progress"></devsite-progress> <section class="devsite-wrapper"> <devsite-cookie-notification-bar></devsite-cookie-notification-bar><devsite-header role="banner"> <div class="devsite-header--inner nocontent"> <div class="devsite-top-logo-row-wrapper-wrapper"> <div class="devsite-top-logo-row-wrapper"> <div class="devsite-top-logo-row"> <button type="button" id="devsite-hamburger-menu" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Navigation menu button" visually-hidden aria-label="Open menu"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="webDev" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="web.dev"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/lockup.svg" class="devsite-site-logo" alt="web.dev"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> <div class="devsite-top-logo-row-middle"> <div class="devsite-header-upper-tabs"> <devsite-tabs class="upper-tabs"> <nav class="devsite-tabs-wrapper" aria-label="Upper tabs"> <tab > <a href="https://web.dev/about" track-metadata-eventdetail="https://web.dev/about" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - about" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: About" track-name="about" > About </a> </tab> <tab > <a href="https://web.dev/html" track-metadata-eventdetail="https://web.dev/html" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - html" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: HTML" track-name="html" > HTML </a> </tab> <tab > <a href="https://web.dev/css" track-metadata-eventdetail="https://web.dev/css" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - css" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: CSS" track-name="css" > CSS </a> </tab> <tab > <a href="https://web.dev/javascript" track-metadata-eventdetail="https://web.dev/javascript" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - javascript" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: JavaScript" track-name="javascript" > JavaScript </a> </tab> <tab > <a href="https://web.dev/blog" track-metadata-eventdetail="https://web.dev/blog" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - blog" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Blog" track-name="blog" > Blog </a> </tab> <tab > <a href="https://web.dev/learn" track-metadata-eventdetail="https://web.dev/learn" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - learn" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Learn" track-name="learn" > Learn </a> </tab> <tab > <a href="https://web.dev/explore" track-metadata-eventdetail="https://web.dev/explore" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - explore" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Explore" track-name="explore" > Explore </a> </tab> <tab > <a href="https://web.dev/patterns" track-metadata-eventdetail="https://web.dev/patterns" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - patterns" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Patterns" track-name="patterns" > Patterns </a> </tab> <tab > <a href="https://web.dev/case-studies" track-metadata-eventdetail="https://web.dev/case-studies" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - case studies" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Case studies" track-name="case studies" > Case studies </a> </tab> </nav> </devsite-tabs> </div> <devsite-search enable-signin enable-search enable-suggestions enable-query-completion project-name="Articles" tenant-name="web.dev" > <form class="devsite-search-form" action="https://web.dev/s/results" method="GET"> <div class="devsite-search-container"> <button type="button" search-open class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Open search"></button> <div class="devsite-searchbox"> <input aria-activedescendant="" aria-autocomplete="list" aria-label="Search" aria-expanded="false" aria-haspopup="listbox" autocomplete="off" class="devsite-search-field devsite-search-query" name="q" placeholder="Search" role="combobox" type="text" value="" > <div class="devsite-search-image material-icons" aria-hidden="true"> </div> <div class="devsite-search-shortcut-icon-container" aria-hidden="true"> <kbd class="devsite-search-shortcut-icon">/</kbd> </div> </div> </div> </form> <button type="button" search-close class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Close search"></button> </devsite-search> </div> <devsite-appearance-selector></devsite-appearance-selector> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> <devsite-user enable-profiles id="devsite-user"> <span class="button devsite-top-button" aria-hidden="true" visually-hidden>Sign in</span> </devsite-user> </div> </div> </div> <div class="devsite-collapsible-section devsite-header-no-lower-tabs "> <div class="devsite-header-background"> </div> </div> </div> </devsite-header> <devsite-book-nav scrollbars hidden> <div class="devsite-book-nav-filter" hidden> <span class="filter-list-icon material-icons" aria-hidden="true"></span> <input type="text" placeholder="Filter" aria-label="Type to filter" role="searchbox"> <span class="filter-clear-button hidden" data-title="Clear filter" aria-label="Clear filter" role="button" tabindex="0"></span> </div> <nav class="devsite-book-nav devsite-nav nocontent" aria-label="Side menu"> <div class="devsite-mobile-header"> <button type="button" id="devsite-close-nav" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Close navigation" aria-label="Close navigation"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="webDev" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="web.dev"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/lockup.svg" class="devsite-site-logo" alt="web.dev"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> </div> <div class="devsite-book-nav-wrapper"> <div class="devsite-mobile-nav-top"> <ul class="devsite-nav-list"> <li class="devsite-nav-item"> <a href="/about" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: About" track-name="about" data-category="Site-Wide Custom Events" data-label="Responsive Tab: About" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > About </span> </a> </li> <li class="devsite-nav-item"> <a href="/html" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: HTML" track-name="html" data-category="Site-Wide Custom Events" data-label="Responsive Tab: HTML" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > HTML </span> </a> </li> <li class="devsite-nav-item"> <a href="/css" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: CSS" track-name="css" data-category="Site-Wide Custom Events" data-label="Responsive Tab: CSS" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > CSS </span> </a> </li> <li class="devsite-nav-item"> <a href="/javascript" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: JavaScript" track-name="javascript" data-category="Site-Wide Custom Events" data-label="Responsive Tab: JavaScript" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > JavaScript </span> </a> </li> <li class="devsite-nav-item"> <a href="/blog" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Blog" track-name="blog" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Blog" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Blog </span> </a> </li> <li class="devsite-nav-item"> <a href="/learn" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Learn" track-name="learn" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Learn" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Learn </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Explore" track-name="explore" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Explore" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Explore </span> </a> </li> <li class="devsite-nav-item"> <a href="/patterns" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Patterns" track-name="patterns" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Patterns" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Patterns </span> </a> </li> <li class="devsite-nav-item"> <a href="/case-studies" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Case studies" track-name="case studies" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Case studies" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Case studies </span> </a> </li> </ul> </div> </div> </nav> </devsite-book-nav> <section id="gc-wrapper"> <main role="main" class="devsite-main-content" has-sidebar > <div class="devsite-sidebar"> <div class="devsite-sidebar-content"> <devsite-toc class="devsite-nav" role="navigation" aria-label="On this page" depth="2" scrollbars ></devsite-toc> <devsite-recommendations-sidebar class="nocontent devsite-nav"> </devsite-recommendations-sidebar> </div> </div> <devsite-content> <article class="devsite-article"> <div class="devsite-article-meta nocontent" role="navigation"> <ul class="devsite-breadcrumb-list" aria-label="Breadcrumb"> <li class="devsite-breadcrumb-item "> <a href="https://web.dev/" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="" > Home </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://web.dev/articles" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="2" track-type="globalNav" track-name="breadcrumb" track-metadata-position="2" track-metadata-eventdetail="Articles" > Articles </a> </li> </ul> <devsite-thumb-rating position="header"> </devsite-thumb-rating> </div> <h1 class="devsite-page-title" tabindex="-1"> Responsive images </h1> <devsite-feature-tooltip ack-key="AckCollectionsBookmarkTooltipDismiss" analytics-category="Site-Wide Custom Events" analytics-action-show="Callout Profile displayed" analytics-action-close="Callout Profile dismissed" analytics-label="Create Collection Callout" class="devsite-page-bookmark-tooltip nocontent" dismiss-button="true" id="devsite-collections-dropdown" dismiss-button-text="Dismiss" close-button-text="Got it"> <devsite-bookmark></devsite-bookmark> <span slot="popout-heading"> Stay organized with collections </span> <span slot="popout-contents"> Save and categorize content based on your preferences. </span> </devsite-feature-tooltip> <div class="devsite-page-title-meta"><devsite-view-release-notes></devsite-view-release-notes></div> <devsite-toc class="devsite-nav" depth="2" devsite-toc-embedded > </devsite-toc> <div class="devsite-article-body clearfix "> <p>A picture is worth 1000 words, and images play an integral part of every page. But they also often account for most of the downloaded bytes. With responsive web design not only can our layouts change based on device characteristics, but images as well.</p> <p> <div class="wd-authors" translate="no"> <div class="wd-author"> <img class="devsite-landing-row-item-icon" alt="Pete LePage" src="https://web.dev/images/authors/petelepage.jpg" decoding="async" height="64" loading="lazy" width="64"> <div> <span> Pete LePage </span> <div class="wd-author__links"> <a href="https://twitter.com/petele" aria-label="Pete LePage on X" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 300 271"> <title>X</title> <path fill="currentColor" d="m236 0h46l-101 115 118 156h-92.6l-72.5-94.8-83 94.8h-46l107-123-113-148h94.9l65.5 86.6zm-16.1 244h25.5l-165-218h-27.4z"></path> </svg></a> <a href="https://github.com/petele" aria-label="Pete LePage on GitHub" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 32.6 31.8"> <title>GitHub</title> <path d="M16.3 0C7.3 0 0 7.3 0 16.3c0 7.2 4.7 13.3 11.1 15.5.8.1 1.1-.4 1.1-.8v-2.8c-4.5 1-5.5-2.2-5.5-2.2-.7-1.9-1.8-2.4-1.8-2.4-1.5-1 .1-1 .1-1 1.6.1 2.5 1.7 2.5 1.7 1.5 2.5 3.8 1.8 4.7 1.4.1-1.1.6-1.8 1-2.2-3.6-.4-7.4-1.8-7.4-8.1 0-1.8.6-3.2 1.7-4.4-.1-.3-.7-2 .2-4.2 0 0 1.4-.4 4.5 1.7 1.3-.4 2.7-.5 4.1-.5 1.4 0 2.8.2 4.1.5 3.1-2.1 4.5-1.7 4.5-1.7.9 2.2.3 3.9.2 4.3 1 1.1 1.7 2.6 1.7 4.4 0 6.3-3.8 7.6-7.4 8 .6.5 1.1 1.5 1.1 3V31c0 .4.3.9 1.1.8 6.5-2.2 11.1-8.3 11.1-15.5C32.6 7.3 25.3 0 16.3 0z" fill-rule="evenodd" clip-rule="evenodd" fill="currentColor" /> </svg></a> <a href="https://glitch.com/@petele" aria-label="Pete LePage on Glitch" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 32 32"> <title>Glitch</title> <path fill="currentColor" d="M31.734 16.76c-.385-.198-4.536 1.865-5.427 1.693-2.24-.401-1.828-.667-4.839-1.359-1.203-.266-1.031-.109-1.297-.307-.172-.135-.344-.161-.599-.401 4-.719 6.026-1.693 6.734-1.839.76-.146 5.161 1.958 5.427 1.469.266-.495-.964-1.578-.401-3.031.589-1.464-.693-2.422.016-3.583.719-1.161.573-2.932.396-3.026-.396-.203-4.531 1.865-5.438 1.693-2.24-.417-1.828-.682-4.839-1.359-1.203-.271-1.031-.12-1.297-.323-.266-.198-.521-.13-1.036-.974-.521-.839-6.51-2.13-6.906-2.13-.828 0-2.375 2.13-2.375 2.13s-.599 0-2.401.094c-1.802.094-3.375.896-5.495 2.563C-.173 9.737.134 11.414.134 11.414s1.969.667 1.969 1.042c0 .359-1.729.802-1.729.802 1.12 1.411 4.583 2.745 5.464 2.745h.693c-1.438.281-2.823 1.068-4.583 2.438-2.12 1.698-1.813 3.375-1.813 3.375s1.969.667 1.969 1.026-1.729.802-1.729.802c1.12 1.427 4.583 2.76 5.464 2.76.844 0 1.427.026 2.495-.172.078.172.906 1.932 2.599 2.292 1.786.385 2.776.078 2.776.078s.094-.786-.323-1.573c1.547.161 3.307.203 5.026-.068 4.76-.719 7.12-1.865 7.896-2.01.76-.161 5.161 1.948 5.427 1.464.266-.505-.964-1.583-.385-3.036.573-1.469-.708-2.417 0-3.589.719-1.161.573-2.932.396-3.026zM4.615 11.828a1.446 1.446 0 0 1-.297-.042h-.052c-.026-.01-.052-.026-.078-.042l-.052-.01-.083-.042h-.052a.418.418 0 0 1-.068-.042l-.068-.052-.063-.036-.057-.042c-.021-.016-.042-.036-.063-.052l-.042-.042c-.026-.026-.047-.052-.068-.078l-.026-.031a1.954 1.954 0 0 1-.094-.104l-.026-.026c-.021-.036-.036-.073-.052-.109l-.026-.036-.057-.083c-.005-.021-.016-.042-.026-.063l-.026-.083-.026-.052-.016-.094-.01-.068c-.01-.026-.021-.052-.026-.078v-.068c.094.573.557 1.016 1.104 1.016.63 0 1.146-.573 1.146-1.297 0-.719-.505-1.307-1.146-1.307-.625 0-1.13.573-1.146 1.281 0-.932.667-1.693 1.495-1.693.823 0 1.479.745 1.479 1.682 0 .932-.667 1.693-1.479 1.693zm-1-1.265c0-.203.13-.365.318-.365s.307.161.307.365c0 .198-.135.344-.307.344s-.318-.161-.318-.344zm1 11.651a.712.712 0 0 1-.146 0l-.057-.016a.6.6 0 0 1-.094-.01l-.052-.016-.078-.026-.052-.026c-.031-.005-.057-.016-.083-.026l-.052-.026c-.021-.016-.047-.026-.068-.042L3.881 22l-.068-.052-.052-.042-.068-.052-.042-.042c-.031-.031-.063-.057-.089-.094a.671.671 0 0 1-.094-.12l-.031-.026c-.016-.031-.036-.063-.052-.094l-.026-.052c-.016-.026-.036-.052-.052-.078l-.026-.057-.026-.094-.026-.052-.031-.094-.01-.052c-.01-.031-.021-.063-.026-.094v-.068c.094.573.557 1.016 1.104 1.016.63 0 1.146-.573 1.146-1.292 0-.724-.505-1.297-1.146-1.297-.625 0-1.13.563-1.146 1.266 0-.932.667-1.693 1.495-1.693.823 0 1.479.76 1.479 1.682 0 .917-.667 1.693-1.479 1.693zm-1-1.266c0-.188.13-.349.318-.349s.307.161.307.349c0 .188-.135.344-.307.344s-.318-.146-.318-.344zm6.77-7.333v-.042l.042-.078.078-.297c.182-.583.344-1.172.479-1.771.161-.708.229-1.281.203-1.599-.016-.12-.031-.245-.052-.359a8.276 8.276 0 0 0-.521-1.724l-.083-.172-.026-.068c-.12-.266.057-.573.323-.557h.188l.531.036 2.104.109 1.151.078a28.24 28.24 0 0 1 10.573 2.828l.891.401c.172.078.266.307.188.505-.068.188-.266.292-.438.214l-.896-.401a27.695 27.695 0 0 0-10.359-2.786l-1.146-.068-.51-.026-1.599-.094h-.156c.188.51.339 1.031.453 1.562l.063.427c.042.453-.036 1.078-.224 1.88l-.203.823a23.62 23.62 0 0 1-.385 1.323l-.026.078v.042c-.068.188-.266.292-.438.214-.177-.068-.271-.292-.203-.495zm-2-6.349a.307.307 0 0 1 .479.026c.208.26.396.536.563.828.292.531.495 1.068.547 1.615.026.307 0 .651-.052 1.026a8.718 8.718 0 0 1-.271 1.104c-.094.313-.208.62-.333.922-.078.188-.276.266-.453.172-.172-.094-.24-.318-.156-.521l.026-.052.068-.172c.073-.198.146-.396.214-.599.099-.328.182-.661.24-1 .052-.307.063-.573.052-.802a3.47 3.47 0 0 0-.453-1.292 4.794 4.794 0 0 0-.443-.667l-.036-.042a.417.417 0 0 1 .026-.531zm1.537 13.869c-.063.38-.151.76-.271 1.13a9.549 9.549 0 0 1-.333.906c-.078.188-.276.266-.453.177-.172-.094-.24-.323-.156-.521l.026-.057.068-.172c.073-.198.146-.396.214-.599.099-.328.182-.661.24-1 .052-.307.063-.573.036-.802a3.365 3.365 0 0 0-.438-1.276 4.794 4.794 0 0 0-.443-.667l-.036-.057a.417.417 0 0 1 .026-.531.3.3 0 0 1 .464 0c.214.266.396.547.563.839.292.536.495 1.083.547 1.615.026.307 0 .651-.052 1.026zm16.531.157c-.068.188-.266.297-.438.214l-.896-.401a27.695 27.695 0 0 0-10.359-2.786l-1.135-.063h-.063l-.458-.026c-.583-.036-1.172-.068-1.755-.094l.036.078c.234.615.396 1.255.479 1.906.042.453-.036 1.078-.224 1.88l-.203.828a24.99 24.99 0 0 1-.385 1.333l-.026.068v.036c-.068.203-.266.297-.438.229a.42.42 0 0 1-.203-.51v-.026l.042-.078.078-.292c.182-.589.344-1.177.479-1.776.161-.708.229-1.281.203-1.599-.016-.12-.031-.24-.052-.359a7.996 7.996 0 0 0-.521-1.708l-.052-.12-.031-.068-.026-.063c-.12-.271.057-.578.323-.563h.188l.531.042 2.12.104 1.135.083a28.14 28.14 0 0 1 10.573 2.823l.891.401c.172.078.266.307.188.505z"/> </svg></a> <a href="https://techhub.social/@petele" aria-label="Pete LePage on Mastodon" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 16 16"> <title>Mastodon</title> <path fill="currentColor" d="M 15.659 9.592 C 15.424 10.72 13.553 11.956 11.404 12.195 C 10.283 12.32 9.18 12.434 8.003 12.384 C 6.079 12.302 4.56 11.956 4.56 11.956 C 4.56 12.13 4.572 12.297 4.595 12.452 C 4.845 14.224 6.478 14.33 8.025 14.379 C 9.586 14.429 10.976 14.02 10.976 14.02 L 11.04 15.337 C 11.04 15.337 9.948 15.884 8.003 15.984 C 6.93 16.039 5.598 15.959 4.047 15.576 C 0.683 14.746 0.104 11.4 0.015 8.006 C -0.012 6.998 0.005 6.048 0.005 5.253 C 0.005 1.782 2.443 0.765 2.443 0.765 C 3.672 0.238 5.782 0.017 7.975 0 L 8.029 0 C 10.221 0.017 12.332 0.238 13.561 0.765 C 13.561 0.765 15.999 1.782 15.999 5.253 C 15.999 5.253 16.03 7.814 15.659 9.592 Z M 13.124 5.522 L 13.124 9.725 L 11.339 9.725 L 11.339 5.646 C 11.339 4.786 10.951 4.35 10.175 4.35 C 9.317 4.35 8.887 4.867 8.887 5.891 L 8.887 8.124 L 7.113 8.124 L 7.113 5.891 C 7.113 4.867 6.683 4.35 5.825 4.35 C 5.049 4.35 4.661 4.786 4.661 5.646 L 4.661 9.725 L 2.876 9.725 L 2.876 5.522 C 2.876 4.663 3.111 3.981 3.582 3.476 C 4.067 2.971 4.703 2.712 5.493 2.712 C 6.406 2.712 7.098 3.039 7.555 3.695 L 8 4.39 L 8.445 3.695 C 8.902 3.039 9.594 2.712 10.507 2.712 C 11.297 2.712 11.933 2.971 12.418 3.476 C 12.889 3.981 13.124 4.663 13.124 5.522 Z" style="stroke:none;stroke-miterlimit:10;fill-rule:evenodd;"></path> </svg></a> <a href="https://petelepage.com/" aria-label="Pete LePage's homepage" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 30 30"> <title>Homepage</title> <circle cx="14.5" cy="14.5" r="13.5" stroke-width="2" stroke-miterlimit="10" fill="none" stroke="currentColor" /> <ellipse cx="14.5" cy="14.5" rx="6.1" ry="13.5" stroke-width="2" stroke-miterlimit="10" fill="none" stroke="currentColor" /> <path d="M1.6 9.6h25.8M1.6 19.4h25.8" stroke-width="2" stroke-miterlimit="10" fill="none" stroke="currentColor" /> </svg></a> </div> </div> </div> </div></p> <p>Responsive web design means that not only can our layouts change based on device characteristics, but content can change as well. For example, on high resolution (2x) displays, high resolution graphics ensure sharpness. An image that is 50% width may work just fine when the browser is 800px wide, but uses too much real estate on a narrow phone, and requires the same bandwidth overhead when scaled down to fit a smaller screen.</p> <h2 id="art_direction" data-text="Art direction" tabindex="-1">Art direction</h2> <figure> <img src="/static/articles/responsive-images/image/art-direction-example-2a99df174349c.png" alt="Art direction example" width="600" height="328" srcset="https://web.dev/static/articles/responsive-images/image/art-direction-example-2a99df174349c_36.png 36w,https://web.dev/static/articles/responsive-images/image/art-direction-example-2a99df174349c_48.png 48w,https://web.dev/static/articles/responsive-images/image/art-direction-example-2a99df174349c_72.png 72w,https://web.dev/static/articles/responsive-images/image/art-direction-example-2a99df174349c_96.png 96w,https://web.dev/static/articles/responsive-images/image/art-direction-example-2a99df174349c_480.png 480w,https://web.dev/static/articles/responsive-images/image/art-direction-example-2a99df174349c_720.png 720w,https://web.dev/static/articles/responsive-images/image/art-direction-example-2a99df174349c_856.png 856w,https://web.dev/static/articles/responsive-images/image/art-direction-example-2a99df174349c_960.png 960w,https://web.dev/static/articles/responsive-images/image/art-direction-example-2a99df174349c_1440.png 1440w,https://web.dev/static/articles/responsive-images/image/art-direction-example-2a99df174349c_1920.png 1920w,https://web.dev/static/articles/responsive-images/image/art-direction-example-2a99df174349c_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> </figure> <p>Other times the image may need to be changed more drastically: changing the proportions, cropping, and even replacing the entire image. In this case, changing the image is usually referred to as art direction. See <a href="https://responsiveimages.org/demos/">responsiveimages.org/demos/</a> for more examples.</p> <h2 id="responsive_images_2" data-text="Responsive Images" tabindex="-1">Responsive Images</h2> <p><a href="https://www.udacity.com/course/responsive-images--ud882"> <figure> <img src="/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5.png" alt="Udacity Course Screenshot" width="360" height="220" srcset="https://web.dev/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5_36.png 36w,https://web.dev/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5_48.png 48w,https://web.dev/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5_72.png 72w,https://web.dev/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5_96.png 96w,https://web.dev/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5_480.png 480w,https://web.dev/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5_720.png 720w,https://web.dev/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5_856.png 856w,https://web.dev/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5_960.png 960w,https://web.dev/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5_1440.png 1440w,https://web.dev/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5_1920.png 1920w,https://web.dev/static/articles/responsive-images/image/udacity-course-screenshot-434dec66b55e5_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> </figure> </a></p> <p>Did you know that images account for more than 60% of the bytes on average needed to load a web page?</p> <p>In this course you will learn how to work with images on the modern web, so that your images look great and load quickly on any device.</p> <p>Along the way, you will pick up a range of skills and techniques to smoothly integrate responsive images into your development workflow. By the end of the course, you will be developing with images that adapt and respond to different viewport sizes and usage scenarios.</p> <p>This is a free course offered through <a href="https://www.udacity.com">Udacity</a></p> <p><a href="https://www.udacity.com/course/responsive-images--ud882">Take Course</a></p> <h2 id="images_in_markup" data-text="Images in markup" tabindex="-1">Images in markup</h2> <p>The <code translate="no" dir="ltr">img</code> element is powerful—it downloads, decodes, and renders content—and modern browsers support a range of image formats. Including images that work across devices is no different than for desktop, and only requires a few minor tweaks to create a good experience.</p> <h3 id="summary" data-text="Summary" tabindex="-1">Summary</h3> <ul> <li>Use relative sizes for images to prevent them from accidentally overflowing the container.</li> <li>Use the <code translate="no" dir="ltr">picture</code> element when you want to specify different images depending on device characteristics (a.k.a. art direction).</li> <li>Use <code translate="no" dir="ltr">srcset</code> and the <code translate="no" dir="ltr">x</code> descriptor in the <code translate="no" dir="ltr">img</code> element to give hints to the browser about the best image to use when choosing from different densities.</li> <li>If your page only has one or two images and these are not used elsewhere on your site, consider using inline images to reduce file requests.</li> </ul> <h3 id="use_relative_sizes_for_images" data-text="Use relative sizes for images" tabindex="-1">Use relative sizes for images</h3> <p>Remember to use relative units when specifying widths for images to prevent them from accidentally overflowing the viewport. For example, <code translate="no" dir="ltr">width: 50%;</code> causes the image width to be 50% of the containing element (not 50% of the viewport or 50% of actual pixel size).</p> <p>Because CSS allows content to overflow its container, you may need to use max- width: 100% to prevent images and other content from overflowing. For example:</p> <pre class="prettyprint lang-css" translate="no" dir="ltr"><code translate="no" dir="ltr">img, embed, object, video { max-width: 100%; } </code></pre> <p>Be sure to provide meaningful descriptions via the <code translate="no" dir="ltr">alt</code> attribute on <code translate="no" dir="ltr">img</code> elements; these help make your site more accessible by giving context to screen readers and other assistive technologies.</p> <h3 id="enhance_imgs_with_srcset_for_high_dpi_devices" data-text="Enhance imgs with srcset for high DPI devices" tabindex="-1">Enhance <code translate="no" dir="ltr">img</code>s with <code translate="no" dir="ltr">srcset</code> for high DPI devices</h3> <p><devsite-video video-id="Pzc5Dly_jEM"></devsite-video></p> <p>The <code translate="no" dir="ltr">srcset</code> attribute enhances the behavior of the <code translate="no" dir="ltr">img</code> element, making it easy to provide multiple image files for different device characteristics. Similar to the <code translate="no" dir="ltr">image-set</code> <a href="#use_image-set_to_provide_high_res_images">CSS function</a> native to CSS, <code translate="no" dir="ltr">srcset</code> allows the browser to choose the best image depending on the characteristics of the device, for example using a 2x image on a 2x display, and potentially in the future, a 1x image on a 2x device when on a limited bandwidth network.</p> <pre class="prettyprint lang-html" translate="no" dir="ltr"><code translate="no" dir="ltr"><img src="photo.png" srcset="photo@2x.png 2x" ...> </code></pre> <p>On browsers that don't support <code translate="no" dir="ltr">srcset</code>, the browser simply uses the default image file specified by the <code translate="no" dir="ltr">src</code> attribute. This is why it is important to always include a 1x image that can be displayed on any device, regardless of capabilities. When <code translate="no" dir="ltr">srcset</code> is supported, the comma-separated list of image/conditions is parsed prior to making any requests, and only the most appropriate image is downloaded and displayed.</p> <p>While the conditions can include everything from pixel density to width and height, only pixel density is well-supported today. To balance current behavior with future features, stick with simply providing the 2x image in the attribute.</p> <h3 id="art_direction_in_responsive_images_with_picture" data-text="Art direction in responsive images with picture" tabindex="-1">Art direction in responsive images with <code translate="no" dir="ltr">picture</code></h3> <figure> <img src="/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646.png" alt="Art direction example" width="600" height="328" srcset="https://web.dev/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646_36.png 36w,https://web.dev/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646_48.png 48w,https://web.dev/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646_72.png 72w,https://web.dev/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646_96.png 96w,https://web.dev/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646_480.png 480w,https://web.dev/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646_720.png 720w,https://web.dev/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646_856.png 856w,https://web.dev/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646_960.png 960w,https://web.dev/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646_1440.png 1440w,https://web.dev/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646_1920.png 1920w,https://web.dev/static/articles/responsive-images/image/art-direction-example-a02acbd7a6646_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> </figure> <p>To change images based on device characteristics, also known as art direction, use the <code translate="no" dir="ltr">picture</code> element. The <code translate="no" dir="ltr">picture</code> element defines a declarative solution for providing multiple versions of an image based on different characteristics, like device size, device resolution, orientation, and more.</p> <aside class="note"><b>Note: </b> The <code translate="no" dir="ltr">picture</code> element is beginning to land in browsers. Although it's not available in every browser yet, we recommend its use because of the strong backward compatibility and potential use of the <a href="https://scottjehl.github.io/picturefill/">Picturefill polyfill</a>. See the <a href="http://responsiveimages.org/#implementation">ResponsiveImages.org</a> site for further details. </aside> <p><devsite-video video-id="QINlm3vjnaY"></devsite-video></p> <p>Use the <code translate="no" dir="ltr">picture</code> element when an image source exists in multiple densities, or when a responsive design dictates a somewhat different image on some types of screens. Similar to the <code translate="no" dir="ltr">video</code> element, multiple <code translate="no" dir="ltr">source</code> elements can be included, making it possible to specify different image files depending on media queries or image format.</p> <pre class="prettyprint lang-html" translate="no" dir="ltr"><code translate="no" dir="ltr"><picture> <source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x"> <source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x"> <img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" alt="a head carved out of wood"> </picture> </code></pre> <p><a href="https://googlesamples.github.io/web-fundamentals/fundamentals/design-and-ux/responsive/media.html" target="_blank" class="external">Try it</a> </p> <p>In the above example, if the browser width is at least 800px then either <code translate="no" dir="ltr">head.jpg</code> or <code translate="no" dir="ltr">head-2x.jpg</code> is used, depending on the device resolution. If the browser is between 450px and 800px, then either <code translate="no" dir="ltr">head-small.jpg</code> or <code translate="no" dir="ltr">head-small- 2x.jpg</code> is used, again, depending on the device resolution. For screen widths less than 450px and backward compatibility where the <code translate="no" dir="ltr">picture</code> element isn’t supported, the browser renders the <code translate="no" dir="ltr">img</code> element instead, and should always be included.</p> <h4 id="relative_sized_images" data-text="Relative sized images" tabindex="-1">Relative sized images</h4> <p>When the final size of the image isn’t known, it can be difficult to specify a density descriptor for the image sources. This is especially true for images that span a proportional width of the browser and are fluid, depending on the size of the browser.</p> <p>Instead of supplying fixed image sizes and densities, you can specify the size of each supplied image by adding a width descriptor along with the size of the image element, allowing the browser to automatically calculate the effective pixel density and choose the best image to download.</p> <pre class="prettyprint lang-html" translate="no" dir="ltr"><code translate="no" dir="ltr"><img src="lighthouse-200.jpg" sizes="50vw" srcset="lighthouse-100.jpg 100w, lighthouse-200.jpg 200w, lighthouse-400.jpg 400w, lighthouse-800.jpg 800w, lighthouse-1000.jpg 1000w, lighthouse-1400.jpg 1400w, lighthouse-1800.jpg 1800w" alt="a lighthouse"> </code></pre> <p><a href="https://googlesamples.github.io/web-fundamentals/fundamentals/design-and-ux/responsive/sizes.html">Try it</a></p> <p>The above example renders an image that is half the viewport width (<code translate="no" dir="ltr">sizes="50vw"</code>), and depending on the width of the browser and its device pixel ratio, allows the browser to choose the correct image regardless of how large the browser window is. For example, the table below shows which image the browser would choose:</p> <table class=""> <thead> <tr> <th data-th="Browser width">Browser width</th> <th data-th="Device pixel ratio">Device pixel ratio</th> <th data-th="Image used">Image used</th> <th data-th="Effective resolution">Effective resolution</th> </tr> </thead> <tbody> <tr> <td data-th="Browser width">400px</td> <td data-th="Device pixel ratio">1</td> <td data-th="Image used"><code translate="no" dir="ltr">200.jpg</code></td> <td data-th="Effective resolution">1x</td> </tr> <tr> <td data-th="Browser width">400px</td> <td data-th="Device pixel ratio">2</td> <td data-th="Image used"><code translate="no" dir="ltr">400.jpg</code></td> <td data-th="Effective resolution">2x</td> </tr> <tr> <td data-th="Browser width">320px</td> <td data-th="Device pixel ratio">2</td> <td data-th="Image used"><code translate="no" dir="ltr">400.jpg</code></td> <td data-th="Effective resolution">2.5x</td> </tr> <tr> <td data-th="Browser width">600px</td> <td data-th="Device pixel ratio">2</td> <td data-th="Image used"><code translate="no" dir="ltr">800.jpg</code></td> <td data-th="Effective resolution">2.67x</td> </tr> <tr> <td data-th="Browser width">640px</td> <td data-th="Device pixel ratio">3</td> <td data-th="Image used"><code translate="no" dir="ltr">1000.jpg</code></td> <td data-th="Effective resolution">3.125x</td> </tr> <tr> <td data-th="Browser width">1100px</td> <td data-th="Device pixel ratio">1</td> <td data-th="Image used"><code translate="no" dir="ltr">800.png</code></td> <td data-th="Effective resolution">1.45x</td> </tr> </tbody> </table> <h4 id="account_for_breakpoints_in_responsive_images" data-text="Account for breakpoints in responsive images" tabindex="-1">Account for breakpoints in responsive images</h4> <p>In many cases, the image size may change depending on the site’s layout breakpoints. For example, on a small screen, you might want the image to span the full width of the viewport, while on larger screens, it should only take a small proportion.</p> <pre class="prettyprint lang-html" translate="no" dir="ltr"><code translate="no" dir="ltr"><img src="400.png" sizes="(min-width: 600px) 25vw, (min-width: 500px) 50vw, 100vw" srcset="100.png 100w, 200.png 200w, 400.png 400w, 800.png 800w, 1600.png 1600w, 2000.png 2000w" alt="an example image"> </code></pre> <p><a href="https://googlesamples.github.io/web-fundamentals/fundamentals/design-and-ux/responsive/breakpoints.html">Try it</a></p> <p>The <code translate="no" dir="ltr">sizes</code> attribute, in the above example, uses several media queries to specify the size of the image. When the browser width is greater than 600px, the image is 25% of the viewport width; when it is between 500px and 600px, the image is 50% of the viewport width; and below 500px, it is full width.</p> <h3 id="make_product_images_expandable" data-text="Make product images expandable" tabindex="-1">Make product images expandable</h3> <figure> <img src="/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed.png" alt="J. Crews website with expandable product image" width="325" height="550" srcset="https://web.dev/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed_36.png 36w,https://web.dev/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed_48.png 48w,https://web.dev/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed_72.png 72w,https://web.dev/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed_96.png 96w,https://web.dev/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed_480.png 480w,https://web.dev/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed_720.png 720w,https://web.dev/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed_856.png 856w,https://web.dev/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed_960.png 960w,https://web.dev/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed_1440.png 1440w,https://web.dev/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed_1920.png 1920w,https://web.dev/static/articles/responsive-images/image/j-crews-website-expanda-68db8abcb92ed_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="wd-caption"> J. Crew's website with expandable product image. </figcaption> </figure> <p>Customers want to see what they're buying. On retail sites, users expect to be able to view high resolution closeups of products to get a better look at details, and <a href="https://developers.google.com/web/fundamentals/getting-started/principles/#make-product-images-expandable">study participants</a> got frustrated if they weren't able to.</p> <p>A good example of tappable, expandable images is provided by the J. Crew site. A disappearing overlay indicates that an image is tappable, providing a zoomed in image with fine detail visible.</p> <h3 id="other_image_techniques" data-text="Other image techniques" tabindex="-1">Other image techniques</h3> <h4 id="compressive_images" data-text="Compressive images" tabindex="-1">Compressive images</h4> <p>The <a href="http://www.html5rocks.com/en/mobile/high-dpi/#toc-tech-overview">compressive image technique</a> serves a highly compressed 2x image to all devices, no matter the actual capabilities of the device. Depending on the type of image and level of compression, image quality may not appear to change, but the file size drops significantly.</p> <p><a href="https://googlesamples.github.io/web-fundamentals/fundamentals/design-and-ux/responsive/compressive.html">Try it</a></p> <aside class="caution"><b>Caution: </b> Use caution with the compressive technique because of the increased memory and decoding costs it requires. Resizing large images to fit on smaller screens is expensive and can be particularly painful on low-end devices where both memory and processing is limited. </aside> <h4 id="javascript_image_replacement" data-text="JavaScript image replacement" tabindex="-1">JavaScript image replacement</h4> <p>JavaScript image replacement checks the capabilities of the device and "does the right thing." You can determine device pixel ratio via <code translate="no" dir="ltr">window.devicePixelRatio</code>, get screen width and height, and even potentially do some network connection sniffing via <code translate="no" dir="ltr">navigator.connection</code> or issuing a fake request. When you've collected all of this information, you can decide which image to load.</p> <p>One big drawback to this approach is that using JavaScript means that you will delay image loading until at least the look-ahead parser has finished. This means that images won't even start downloading until after the <code translate="no" dir="ltr">pageload</code> event fires. In addition, the browser will most likely download both the 1x and 2x images, resulting in increased page weight.</p> <h4 id="inlining_images_raster_and_vector" data-text="Inlining images: raster and vector" tabindex="-1">Inlining images: raster and vector</h4> <p>There are two fundamentally different ways to create and store images—and this affects how you deploy images responsively.</p> <p><strong>Raster images</strong> — such as photographs and other images, are represented as a grid of individual dots of color. Raster images might come from a camera or scanner, or be created with the HTML canvas element. Formats like PNG, JPEG, and WebP are used to store raster images.</p> <p><strong>Vector images</strong> such as logos and line art are defined as a set of curves, lines, shapes, fill colors and gradients. Vector images can be created with programs like Adobe Illustrator or Inkscape, or handwritten in code using a vector format such as SVG.</p> <h5 id="svg" data-text="SVG" tabindex="-1">SVG</h5> <p>SVG makes it possible to include responsive vector graphics in a web page. The advantage of vector file formats over raster file formats is that the browser can render a vector image at any size. Vector formats describe the geometry of the image—how it's constructed from lines, curves, and colors and so on. Raster formats, on the other hand, only have information about individual dots of color, so the browser has to guess how to fill in the blanks when scaling.</p> <p>Below are two versions of the same image: a PNG image on the left and an SVG on the right. The SVG looks great at any size, whereas the PNG next to it starts to look blurry at larger display sizes.</p> <div class="wd-switcher"> <figure> <img src="/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47.png" alt="HTML5 logo, PNG format" width="200" height="282" srcset="https://web.dev/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47_36.png 36w,https://web.dev/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47_48.png 48w,https://web.dev/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47_72.png 72w,https://web.dev/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47_96.png 96w,https://web.dev/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47_480.png 480w,https://web.dev/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47_720.png 720w,https://web.dev/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47_856.png 856w,https://web.dev/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47_960.png 960w,https://web.dev/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47_1440.png 1440w,https://web.dev/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47_1920.png 1920w,https://web.dev/static/articles/responsive-images/image/html5-logo-png-format-d92f93e643a47_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> </figure> <figure> <img src="/static/articles/responsive-images/image/html5-logo-svg-format-550784ff36e4b.svg" alt="HTML5 logo, SVG format" width="397" height="560"> </figure> </div> <p>If you want to reduce the number of file requests your page makes, you can code images inline using SVG or Data URI format. If you view the source of this page, you'll see that both logos below are declared inline: a Data URI and an SVG.</p> <p><img class="side-by-side" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiB BZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW 9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RUR CBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2 ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8 vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OT kveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iMzk2Ljc0cHgiIGhlaWdodD0iNTYwc HgiIHZpZXdCb3g9IjI4MS42MyAwIDM5Ni43NCA1NjAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcg MjgxLjYzIDAgMzk2Ljc0IDU2MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSINCgk+DQo8Zz4NCgk8Zz4 NCgkJPGc+DQoJCQk8cG9seWdvbiBmaWxsPSIjRTQ0RDI2IiBwb2ludHM9IjQwOS43MzcsMjQyLj UwMiA0MTQuMjc2LDI5My4zNjIgNDc5LjgyOCwyOTMuMzYyIDQ4MCwyOTMuMzYyIDQ4MCwyNDIuN TAyIDQ3OS44MjgsMjQyLjUwMiAJCQkNCgkJCQkiLz4NCgkJCTxwYXRoIGZpbGw9IiNFNDREMjYi IGQ9Ik0yODEuNjMsMTEwLjA1M2wzNi4xMDYsNDA0Ljk2OEw0NzkuNzU3LDU2MGwxNjIuNDctNDU uMDQybDM2LjE0NC00MDQuOTA1SDI4MS42M3ogTTYxMS4yODMsNDg5LjE3Ng0KCQkJCUw0ODAsNT I1LjU3MlY0NzQuMDNsLTAuMjI5LDAuMDYzTDM3OC4wMzEsNDQ1Ljg1bC02Ljk1OC03Ny45ODVoM jIuOThoMjYuODc5bDMuNTM2LDM5LjYxMmw1NS4zMTUsMTQuOTM3bDAuMDQ2LTAuMDEzdi0wLjAw NA0KCQkJCUw0ODAsNDIyLjM1di03OS4zMmgtMC4xNzJIMzY4Ljg1M2wtMTIuMjA3LTEzNi44NzF sLTEuMTg5LTEzLjMyNWgxMjQuMzcxSDQ4MHYtNDkuNjY4aDE2Mi4xN0w2MTEuMjgzLDQ4OS4xNz Z6Ii8+DQoJCQk8cG9seWdvbiBmaWxsPSIjRjE2NTI5IiBwb2ludHM9IjQ4MCwxOTIuODMzIDYwN C4yNDcsMTkyLjgzMyA2MDMuMDU5LDIwNi4xNTkgNjAwLjc5NiwyMzEuMzM4IDU5OS44LDI0Mi41 MDIgNTk5LjY0LDI0Mi41MDIgDQoJCQkJNDgwLDI0Mi41MDIgNDgwLDI5My4zNjIgNTgxLjg5Niw yOTMuMzYyIDU5NS4yOCwyOTMuMzYyIDU5NC4wNjgsMzA2LjY5OSA1ODIuMzk2LDQzNy40NTggNT gxLjY0OSw0NDUuODUgNDgwLDQ3NC4wMjEgDQoJCQkJNDgwLDQ3NC4wMyA0ODAsNTI1LjU3MiA2M TEuMjgzLDQ4OS4xNzYgNjQyLjE3LDE0My4xNjYgNDgwLDE0My4xNjYgCQkJIi8+DQoJCQk8cG9s eWdvbiBmaWxsPSIjRjE2NTI5IiBwb2ludHM9IjU0MC45ODgsMzQzLjAyOSA0ODAsMzQzLjAyOSA 0ODAsNDIyLjM1IDUzNS4yMjQsNDA3LjQ0NSAJCQkiLz4NCgkJCTxwb2x5Z29uIGZpbGw9IiNFQk VCRUIiIHBvaW50cz0iNDE0LjI3NiwyOTMuMzYyIDQwOS43MzcsMjQyLjUwMiA0NzkuODI4LDI0M i41MDIgNDc5LjgyOCwyNDIuMzggNDc5LjgyOCwyMjMuNjgyIA0KCQkJCTQ3OS44MjgsMTkyLjgz MyAzNTUuNDU3LDE5Mi44MzMgMzU2LjY0NiwyMDYuMTU5IDM2OC44NTMsMzQzLjAyOSA0NzkuODI 4LDM0My4wMjkgNDc5LjgyOCwyOTMuMzYyIAkJCSIvPg0KCQkJPHBvbHlnb24gZmlsbD0iI0VCRU JFQiIgcG9pbnRzPSI0NzkuODI4LDQ3NC4wNjkgNDc5LjgyOCw0MjIuNCA0NzkuNzgyLDQyMi40M TMgNDI0LjQ2Nyw0MDcuNDc3IDQyMC45MzEsMzY3Ljg2NCANCgkJCQkzOTQuMDUyLDM2Ny44NjQg MzcxLjA3MiwzNjcuODY0IDM3OC4wMzEsNDQ1Ljg1IDQ3OS43NzEsNDc0LjA5NCA0ODAsNDc0LjA zIDQ4MCw0NzQuMDIxIAkJCSIvPg0KCQkJPHBvbHlnb24gcG9pbnRzPSIzNDMuNzg0LDUwLjIyOS AzNjYuODc0LDUwLjIyOSAzNjYuODc0LDc1LjUxNyAzOTIuMTE0LDc1LjUxNyAzOTIuMTE0LDAgM zY2Ljg3MywwIDM2Ni44NzMsMjQuOTM4IA0KCQkJCTM0My43ODMsMjQuOTM4IDM0My43ODMsMCAz MTguNTQ0LDAgMzE4LjU0NCw3NS41MTcgMzQzLjc4NCw3NS41MTcgCQkJIi8+DQoJCQk8cG9seWd vbiBwb2ludHM9IjQyNS4zMDcsMjUuMDQyIDQyNS4zMDcsNzUuNTE3IDQ1MC41NDksNzUuNTE3ID Q1MC41NDksMjUuMDQyIDQ3Mi43NzksMjUuMDQyIDQ3Mi43NzksMCA0MDMuMDg1LDAgDQoJCQkJN DAzLjA4NSwyNS4wNDIgNDI1LjMwNiwyNS4wNDIgCQkJIi8+DQoJCQk8cG9seWdvbiBwb2ludHM9 IjUwOC41MzcsMzguMDg2IDUyNS45MTQsNjQuOTM3IDUyNi4zNDksNjQuOTM3IDU0My43MTQsMzg uMDg2IDU0My43MTQsNzUuNTE3IDU2OC44NTEsNzUuNTE3IDU2OC44NTEsMCANCgkJCQk1NDIuNT IyLDAgNTI2LjM0OSwyNi41MzQgNTEwLjE1OSwwIDQ4My44NCwwIDQ4My44NCw3NS41MTcgNTA4L jUzNyw3NS41MTcgCQkJIi8+DQoJCQk8cG9seWdvbiBwb2ludHM9IjY0Mi4xNTYsNTAuNTU1IDYw Ni42Niw1MC41NTUgNjA2LjY2LDAgNTgxLjQxMiwwIDU4MS40MTIsNzUuNTE3IDY0Mi4xNTYsNzU uNTE3IAkJCSIvPg0KCQkJPHBvbHlnb24gZmlsbD0iI0ZGRkZGRiIgcG9pbnRzPSI0ODAsNDc0Lj AyMSA1ODEuNjQ5LDQ0NS44NSA1ODIuMzk2LDQzNy40NTggNTk0LjA2OCwzMDYuNjk5IDU5NS4yO CwyOTMuMzYyIDU4MS44OTYsMjkzLjM2MiANCgkJCQk0ODAsMjkzLjM2MiA0NzkuODI4LDI5My4z NjIgNDc5LjgyOCwzNDMuMDI5IDQ4MCwzNDMuMDI5IDU0MC45ODgsMzQzLjAyOSA1MzUuMjI0LDQ wNy40NDUgNDgwLDQyMi4zNSA0NzkuODI4LDQyMi4zOTYgDQoJCQkJNDc5LjgyOCw0MjIuNCA0Nz kuODI4LDQ3NC4wNjkgCQkJIi8+DQoJCQk8cG9seWdvbiBmaWxsPSIjRkZGRkZGIiBwb2ludHM9I jQ3OS44MjgsMjQyLjM4IDQ3OS44MjgsMjQyLjUwMiA0ODAsMjQyLjUwMiA1OTkuNjQsMjQyLjUw MiA1OTkuOCwyNDIuNTAyIDYwMC43OTYsMjMxLjMzOCANCgkJCQk2MDMuMDU5LDIwNi4xNTkgNjA 0LjI0NywxOTIuODMzIDQ4MCwxOTIuODMzIDQ3OS44MjgsMTkyLjgzMyA0NzkuODI4LDIyMy42OD IgCQkJIi8+DQoJCTwvZz4NCgk8L2c+DQo8L2c+DQo8L3N2Zz4NCg=="> <svg class="side-by-side" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="396.74px" height="560px" viewBox="281.63 0 396.74 560" enable-background="new 281.63 0 396.74 560" xml:space="preserve"><g><g><g><polygon fill="#E44D26" points="409.737,242.502 414.276,293.362 479.828,293.362 480,293.362 480,242.502 479.828,242.502"/><path fill="#E44D26" d="M281.63,110.053l36.106,404.968L479.757,560l162.47-45.042l36.144-404.905H281.63z M611.283,489.176 L480,525.572V474.03l-0.229,0.063L378.031,445.85l-6.958-77.985h22.98h26.879l3.536,39.612l55.315,14.937l0.046-0.013v-0.004 L480,422.35v-79.32h-0.172H368.853l-12.207-136.871l-1.189-13.325h124.371H480v-49.668h162.17L611.283,489.176z"/><polygon fill="#F16529" points="480,192.833 604.247,192.833 603.059,206.159 600.796,231.338 599.8,242.502 599.64,242.502 480,242.502 480,293.362 581.896,293.362 595.28,293.362 594.068,306.699 582.396,437.458 581.649,445.85 480,474.021 480,474.03 480,525.572 611.283,489.176 642.17,143.166 480,143.166 "/><polygon fill="#F16529" points="540.988,343.029 480,343.029 480,422.35 535.224,407.445 "/><polygon fill="#EBEBEB" points="414.276,293.362 409.737,242.502 479.828,242.502 479.828,242.38 479.828,223.682 479.828,192.833 355.457,192.833 356.646,206.159 368.853,343.029 479.828,343.029 479.828,293.362 "/><polygon fill="#EBEBEB" points="479.828,474.069 479.828,422.4 479.782,422.413 424.467,407.477 420.931,367.864 394.052,367.864 371.072,367.864 378.031,445.85 479.771,474.094 480,474.03 480,474.021 "/><polygon points="343.784,50.229 366.874,50.229 366.874,75.517 392.114,75.517 392.114,0 366.873,0 366.873,24.938 343.783,24.938 343.783,0 318.544,0 318.544,75.517 343.784,75.517 "/><polygon points="425.307,25.042 425.307,75.517 450.549,75.517 450.549,25.042 472.779,25.042 472.779,0 403.085,0 403.085,25.042 425.306,25.042 "/><polygon points="508.537,38.086 525.914,64.937 526.349,64.937 543.714,38.086 543.714,75.517 568.851,75.517 568.851,0 542.522,0 526.349,26.534 510.159,0 483.84,0 483.84,75.517 508.537,75.517 "/><polygon points="642.156,50.555 606.66,50.555 606.66,0 581.412,0 581.412,75.517 642.156,75.517 "/><polygon fill="#FFFFFF" points="480,474.021 581.649,445.85 582.396,437.458 594.068,306.699 595.28,293.362 581.896,293.362 480,293.362 479.828,293.362 479.828,343.029 480,343.029 540.988,343.029 535.224,407.445 480,422.35 479.828,422.396 479.828,422.4 479.828,474.069 "/><polygon fill="#FFFFFF" points="479.828,242.38 479.828,242.502 480,242.502 599.64,242.502 599.8,242.502 600.796,231.338 603.059,206.159 604.247,192.833 480,192.833 479.828,192.833 479.828,223.682 "/></g></g></g></svg></p> <p>SVG has <a href="http://caniuse.com/svg-html5">great support</a> on mobile and desktop, and <a href="https://sarasoueidan.com/blog/svgo-tools/">optimization tools</a> can significantly reduce SVG size. The following two inline SVG logos look identical, but one is around 3KB and the other only 2KB:</p> <p><svg class="side-by-side" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="396.74px" height="560px" viewBox="281.63 0 396.74 560" enable-background="new 281.63 0 396.74 560" xml:space="preserve"><g><g><g><polygon fill="#E44D26" points="409.737,242.502 414.276,293.362 479.828,293.362 480,293.362 480,242.502 479.828,242.502"/><path fill="#E44D26" d="M281.63,110.053l36.106,404.968L479.757,560l162.47-45.042l36.144-404.905H281.63z M611.283,489.176 L480,525.572V474.03l-0.229,0.063L378.031,445.85l-6.958-77.985h22.98h26.879l3.536,39.612l55.315,14.937l0.046-0.013v-0.004 L480,422.35v-79.32h-0.172H368.853l-12.207-136.871l-1.189-13.325h124.371H480v-49.668h162.17L611.283,489.176z"/><polygon fill="#F16529" points="480,192.833 604.247,192.833 603.059,206.159 600.796,231.338 599.8,242.502 599.64,242.502 480,242.502 480,293.362 581.896,293.362 595.28,293.362 594.068,306.699 582.396,437.458 581.649,445.85 480,474.021 480,474.03 480,525.572 611.283,489.176 642.17,143.166 480,143.166 "/><polygon fill="#F16529" points="540.988,343.029 480,343.029 480,422.35 535.224,407.445 "/><polygon fill="#EBEBEB" points="414.276,293.362 409.737,242.502 479.828,242.502 479.828,242.38 479.828,223.682 479.828,192.833 355.457,192.833 356.646,206.159 368.853,343.029 479.828,343.029 479.828,293.362 "/><polygon fill="#EBEBEB" points="479.828,474.069 479.828,422.4 479.782,422.413 424.467,407.477 420.931,367.864 394.052,367.864 371.072,367.864 378.031,445.85 479.771,474.094 480,474.03 480,474.021 "/><polygon points="343.784,50.229 366.874,50.229 366.874,75.517 392.114,75.517 392.114,0 366.873,0 366.873,24.938 343.783,24.938 343.783,0 318.544,0 318.544,75.517 343.784,75.517 "/><polygon points="425.307,25.042 425.307,75.517 450.549,75.517 450.549,25.042 472.779,25.042 472.779,0 403.085,0 403.085,25.042 425.306,25.042 "/><polygon points="508.537,38.086 525.914,64.937 526.349,64.937 543.714,38.086 543.714,75.517 568.851,75.517 568.851,0 542.522,0 526.349,26.534 510.159,0 483.84,0 483.84,75.517 508.537,75.517 "/><polygon points="642.156,50.555 606.66,50.555 606.66,0 581.412,0 581.412,75.517 642.156,75.517 "/><polygon fill="#FFFFFF" points="480,474.021 581.649,445.85 582.396,437.458 594.068,306.699 595.28,293.362 581.896,293.362 480,293.362 479.828,293.362 479.828,343.029 480,343.029 540.988,343.029 535.224,407.445 480,422.35 479.828,422.396 479.828,422.4 479.828,474.069 "/><polygon fill="#FFFFFF" points="479.828,242.38 479.828,242.502 480,242.502 599.64,242.502 599.8,242.502 600.796,231.338 603.059,206.159 604.247,192.833 480,192.833 479.828,192.833 479.828,223.682 "/></g></g></g></svg><svg class="side-by-side" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="50%" height="560px" viewBox="281.63 0 396.74 560" enable-background="new 281.63 0 396.74 560" xml:space="preserve"><g><g><g><polygon fill="#E44D26" points="409.7,242.5 414.3,293.4 479.8,293.4 480,293.4 480,242.5 479.8,242.5"/><path fill="#E44D26" d="M281.63 110.053l36.106 404.968L479.757 560l162.47-45.042l36.144-404.905H281.63z M611.283 489.2 L480 525.572V474.03l-0.229 0.063L378.031 445.85l-6.958-77.985h22.98h26.879l3.536 39.612l55.315 14.937l0.046-0.013v-0.004 L480 422.35v-79.32h-0.172H368.853l-12.207-136.871l-1.189-13.325h124.371H480v-49.668h162.17L611.283 489.176z"/><polygon fill="#F16529" points="480,192.8 604.2,192.8 603.1,206.2 600.8,231.3 599.8,242.5 599.6,242.5 480,242.5 480,293.4 581.9,293.4 595.3,293.4 594.1,306.7 582.4,437.5 581.6,445.9 480,474 480,474 480,525.6 611.3,489.2 642.2,143.2 480,143.2"/><polygon fill="#F16529" points="541,343 480,343 480,422.4 535.2,407.4"/><polygon fill="#EBEBEB" points="414.3,293.4 409.7,242.5 479.8,242.5 479.8,242.4 479.8,223.7 479.8,192.8 355.5,192.8 356.6,206.2 368.9,343 479.8,343 479.8,293.4"/><polygon fill="#EBEBEB" points="479.8,474.1 479.8,422.4 479.8,422.4 424.5,407.5 420.9,367.9 394.1,367.9 371.1,367.9 378,445.9 479.8,474.1 480,474 480,474"/><polygon points="343.8,50.2 366.9,50.2 366.9,75.5 392.1,75.5 392.1,0 366.9,0 366.9,24.9 343.8,24.9 343.8,0 318.5,0 318.5,75.5 343.8,75.5"/><polygon points="425.3,25 425.3,75.5 450.5,75.5 450.5,25 472.8,25 472.8,0 403.1,0 403.1,25 425.3,25"/><polygon points="508.5,38.1 525.9,64.9 526.3,64.9 543.7,38.1 543.7,75.5 568.9,75.5 568.9,0 542.5,0 526.3,26.5 510.2,0 483.8,0 483.8,75.5 508.5,75.5"/><polygon points="642.2,50.6 606.7,50.6 606.7,0 581.4,0 581.4,75.5 642.2,75.5"/><polygon fill="#FFFFFF" points="480,474 581.6,445.9 582.4,437.5 594.1,306.7 595.3,293.4 581.9,293.4 480,293.4 479.8,293.4 479.8,343 480,343 541,343 535.2,407.4 480,422.4 479.8,422.4 479.8,422.4 479.8,474.1"/><polygon fill="#FFFFFF" points="479.8,242.4 479.8,242.5 480,242.5 599.6,242.5 599.8,242.5 600.8,231.3 603.1,206.2 604.2,192.8 480,192.8 479.8,192.8 479.8,223.7"/></g></g></g></svg></p> <h5 id="data_uri" data-text="Data URI" tabindex="-1">Data URI</h5> <p>Data URIs provide a way to include a file, such as an image, inline by setting the src of an <code translate="no" dir="ltr">img</code> element as a Base64 encoded string using the following format:</p> <pre class="prettyprint lang-html" translate="no" dir="ltr"><code translate="no" dir="ltr"><img src="data:image/svg+xml;base64,[data]"> </code></pre> <p>The start of the code for the HTML5 logo above looks like this:</p> <pre class="prettyprint lang-html" translate="no" dir="ltr"><code translate="no" dir="ltr"><img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiB BZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW ..."> </code></pre> <p>(The full version is over 5000 characters in length!)</p> <p>Drag 'n' drop tool such as <a href="https://jpillora.com/base64-encoder">jpillora.com/base64-encoder</a> are available to convert binary files such as images to Data URIs. Just like SVGs, Data URIs are <a href="http://caniuse.com/datauri">well supported</a> on mobile and desktop browsers.</p> <h5 id="inlining_in_css" data-text="Inlining in CSS" tabindex="-1">Inlining in CSS</h5> <p>Data URIs and SVGs can also be inlined in CSS—and this is supported on both mobile and desktop. Here are two identical-looking images implemented as background images in CSS; one Data URI, one SVG:</p> <style> .side-by-side { display: inline-block; margin: 0 20px 0 0; width: 45%; } span#data_uri { background: url(data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0D%0A%3C%21--%20Generator%3A%20Adobe%20Illustrator%2016.0.0%2C%20SVG%20Export%20Plug-In%20.%20SVG%20Version%3A%206.00%20Build%200%29%20%20--%3E%0D%0A%3C%21DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%0D%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0D%0A%09%20width%3D%22396.74px%22%20height%3D%22560px%22%20viewBox%3D%22281.63%200%20396.74%20560%22%20enable-background%3D%22new%20281.63%200%20396.74%20560%22%20xml%3Aspace%3D%22preserve%22%0D%0A%09%3E%0D%0A%3Cg%3E%0D%0A%09%3Cg%3E%0D%0A%09%09%3Cg%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23E44D26%22%20points%3D%22409.737%2C242.502%20414.276%2C293.362%20479.828%2C293.362%20480%2C293.362%20480%2C242.502%20479.828%2C242.502%20%09%09%09%0D%0A%09%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpath%20fill%3D%22%23E44D26%22%20d%3D%22M281.63%2C110.053l36.106%2C404.968L479.757%2C560l162.47-45.042l36.144-404.905H281.63z%20M611.283%2C489.176%0D%0A%09%09%09%09L480%2C525.572V474.03l-0.229%2C0.063L378.031%2C445.85l-6.958-77.985h22.98h26.879l3.536%2C39.612l55.315%2C14.937l0.046-0.013v-0.004%0D%0A%09%09%09%09L480%2C422.35v-79.32h-0.172H368.853l-12.207-136.871l-1.189-13.325h124.371H480v-49.668h162.17L611.283%2C489.176z%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23F16529%22%20points%3D%22480%2C192.833%20604.247%2C192.833%20603.059%2C206.159%20600.796%2C231.338%20599.8%2C242.502%20599.64%2C242.502%20%0D%0A%09%09%09%09480%2C242.502%20480%2C293.362%20581.896%2C293.362%20595.28%2C293.362%20594.068%2C306.699%20582.396%2C437.458%20581.649%2C445.85%20480%2C474.021%20%0D%0A%09%09%09%09480%2C474.03%20480%2C525.572%20611.283%2C489.176%20642.17%2C143.166%20480%2C143.166%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23F16529%22%20points%3D%22540.988%2C343.029%20480%2C343.029%20480%2C422.35%20535.224%2C407.445%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23EBEBEB%22%20points%3D%22414.276%2C293.362%20409.737%2C242.502%20479.828%2C242.502%20479.828%2C242.38%20479.828%2C223.682%20%0D%0A%09%09%09%09479.828%2C192.833%20355.457%2C192.833%20356.646%2C206.159%20368.853%2C343.029%20479.828%2C343.029%20479.828%2C293.362%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23EBEBEB%22%20points%3D%22479.828%2C474.069%20479.828%2C422.4%20479.782%2C422.413%20424.467%2C407.477%20420.931%2C367.864%20%0D%0A%09%09%09%09394.052%2C367.864%20371.072%2C367.864%20378.031%2C445.85%20479.771%2C474.094%20480%2C474.03%20480%2C474.021%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20points%3D%22343.784%2C50.229%20366.874%2C50.229%20366.874%2C75.517%20392.114%2C75.517%20392.114%2C0%20366.873%2C0%20366.873%2C24.938%20%0D%0A%09%09%09%09343.783%2C24.938%20343.783%2C0%20318.544%2C0%20318.544%2C75.517%20343.784%2C75.517%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20points%3D%22425.307%2C25.042%20425.307%2C75.517%20450.549%2C75.517%20450.549%2C25.042%20472.779%2C25.042%20472.779%2C0%20403.085%2C0%20%0D%0A%09%09%09%09403.085%2C25.042%20425.306%2C25.042%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20points%3D%22508.537%2C38.086%20525.914%2C64.937%20526.349%2C64.937%20543.714%2C38.086%20543.714%2C75.517%20568.851%2C75.517%20568.851%2C0%20%0D%0A%09%09%09%09542.522%2C0%20526.349%2C26.534%20510.159%2C0%20483.84%2C0%20483.84%2C75.517%20508.537%2C75.517%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20points%3D%22642.156%2C50.555%20606.66%2C50.555%20606.66%2C0%20581.412%2C0%20581.412%2C75.517%20642.156%2C75.517%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23FFFFFF%22%20points%3D%22480%2C474.021%20581.649%2C445.85%20582.396%2C437.458%20594.068%2C306.699%20595.28%2C293.362%20581.896%2C293.362%20%0D%0A%09%09%09%09480%2C293.362%20479.828%2C293.362%20479.828%2C343.029%20480%2C343.029%20540.988%2C343.029%20535.224%2C407.445%20480%2C422.35%20479.828%2C422.396%20%0D%0A%09%09%09%09479.828%2C422.4%20479.828%2C474.069%20%09%09%09%22%2F%3E%0D%0A%09%09%09%3Cpolygon%20fill%3D%22%23FFFFFF%22%20points%3D%22479.828%2C242.38%20479.828%2C242.502%20480%2C242.502%20599.64%2C242.502%20599.8%2C242.502%20600.796%2C231.338%20%0D%0A%09%09%09%09603.059%2C206.159%20604.247%2C192.833%20480%2C192.833%20479.828%2C192.833%20479.828%2C223.682%20%09%09%09%22%2F%3E%0D%0A%09%09%3C%2Fg%3E%0D%0A%09%3C%2Fg%3E%0D%0A%3C%2Fg%3E%0D%0A%3C%2Fsvg%3E%0D%0A) no-repeat; background-size: cover; height: 484px; } span#svg { background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' x='0px' y='0px' width='50%' height='560px' viewBox='281.63 0 396.74 560' enable-background='new 281.63 0 396.74 560' xml:space='preserve'><g><g><g><polygon fill='#E44D26' points='409.7,242.5 414.3,293.4 479.8,293.4 480,293.4 480,242.5 479.8,242.5'/><path fill='#E44D26' d='M281.63 110.053l36.106 404.968L479.757 560l162.47-45.042l36.144-404.905H281.63z M611.283 489.2 L480 525.572V474.03l-0.229 0.063L378.031 445.85l-6.958-77.985h22.98h26.879l3.536 39.612l55.315 14.937l0.046-0.013v-0.004 L480 422.35v-79.32h-0.172H368.853l-12.207-136.871l-1.189-13.325h124.371H480v-49.668h162.17L611.283 489.176z'/><polygon fill='#F16529' points='480,192.8 604.2,192.8 603.1,206.2 600.8,231.3 599.8,242.5 599.6,242.5 480,242.5 480,293.4 581.9,293.4 595.3,293.4 594.1,306.7 582.4,437.5 581.6,445.9 480,474 480,474 480,525.6 611.3,489.2 642.2,143.2 480,143.2'/><polygon fill='#F16529' points='541,343 480,343 480,422.4 535.2,407.4'/><polygon fill='#EBEBEB' points='414.3,293.4 409.7,242.5 479.8,242.5 479.8,242.4 479.8,223.7 479.8,192.8 355.5,192.8 356.6,206.2 368.9,343 479.8,343 479.8,293.4'/><polygon fill='#EBEBEB' points='479.8,474.1 479.8,422.4 479.8,422.4 424.5,407.5 420.9,367.9 394.1,367.9 371.1,367.9 378,445.9 479.8,474.1 480,474 480,474'/><polygon points='343.8,50.2 366.9,50.2 366.9,75.5 392.1,75.5 392.1,0 366.9,0 366.9,24.9 343.8,24.9 343.8,0 318.5,0 318.5,75.5 343.8,75.5'/><polygon points='425.3,25 425.3,75.5 450.5,75.5 450.5,25 472.8,25 472.8,0 403.1,0 403.1,25 425.3,25'/><polygon points='508.5,38.1 525.9,64.9 526.3,64.9 543.7,38.1 543.7,75.5 568.9,75.5 568.9,0 542.5,0 526.3,26.5 510.2,0 483.8,0 483.8,75.5 508.5,75.5'/><polygon points='642.2,50.6 606.7,50.6 606.7,0 581.4,0 581.4,75.5 642.2,75.5'/><polygon fill='#FFFFFF' points='480,474 581.6,445.9 582.4,437.5 594.1,306.7 595.3,293.4 581.9,293.4 480,293.4 479.8,293.4 479.8,343 480,343 541,343 535.2,407.4 480,422.4 479.8,422.4 479.8,422.4 479.8,474.1'/><polygon fill='#FFFFFF' points='479.8,242.4 479.8,242.5 480,242.5 599.6,242.5 599.8,242.5 600.8,231.3 603.1,206.2 604.2,192.8 480,192.8 479.8,192.8 479.8,223.7'/></g></g></g></svg>") no-repeat; background-size: cover; height: 484px; } </style> <p><span class="side-by-side" id="data_uri"></span> <span class="side-by-side" id="svg"></span></p> <h5 id="inlining_pros_cons" data-text="Inlining pros & cons" tabindex="-1">Inlining pros & cons</h5> <p>Inline code for images can be verbose—especially Data URIs—so why would you want to use it? To reduce HTTP requests! SVGs and Data URIs can enable an entire web page, including images, CSS and JavaScript, to be retrieved with one single request.</p> <p>On the downside:</p> <ul> <li>On mobile, Data URIs can be significantly slower to display on mobile than images from an external <code translate="no" dir="ltr">src</code>.</li> <li>Data URIs can considerably increase the size of an HTML request.</li> <li>They add complexity to your markup and your workflow.</li> <li>The Data URI format is considerably bigger than binary (up to 30%) and therefore doesn't reduce total download size.</li> <li>Data URIs cannot be cached, so must be downloaded for every page they're used on.</li> <li>They're not supported in IE 6 and 7, incomplete support in IE8.</li> <li>With HTTP/2, reducing the number of asset requests will become less of a priority.</li> </ul> <p>As with all things responsive, you need to test what works best. Use developer tools to measure download file size, the number of requests, and the total latency. Data URIs can sometimes be useful for raster images—for example, on a homepage that only has one or two photos that aren't used elsewhere. If you need to inline vector images, SVG is a much better option.</p> <h2 id="images_in_css" data-text="Images in CSS" tabindex="-1">Images in CSS</h2> <p>The CSS <code translate="no" dir="ltr">background</code> property is a powerful tool for adding complex images to elements, making it easy to add multiple images, and causing them to repeat, and more. When combined with media queries, the background property becomes even more powerful, enabling conditional image loading based on screen resolution, viewport size, and more.</p> <h3 id="summary_2" data-text="Summary" tabindex="-1">Summary</h3> <ul> <li>Use the best image for the characteristics of the display, consider screen size, device resolution, and page layout.</li> <li>Change the <code translate="no" dir="ltr">background-image</code> property in CSS for high DPI displays using media queries with <code translate="no" dir="ltr">min-resolution</code> and <code translate="no" dir="ltr">-webkit-min-device-pixel-ratio</code>.</li> <li>Use srcset to provide high resolution images in addition to the 1x image in markup.</li> <li>Consider the performance costs when using JavaScript image replacement techniques or when serving highly compressed high resolution images to lower resolution devices.</li> </ul> <h3 id="use_media_queries_for_conditional_image_loading_or_art_direction" data-text="Use media queries for conditional image loading or art direction" tabindex="-1">Use media queries for conditional image loading or art direction</h3> <p>Media queries not only affect the page layout; you can also use them to conditionally load images or to provide art direction depending on the viewport width.</p> <p>For example, in the sample below, on smaller screens only <code translate="no" dir="ltr">small.png</code> is downloaded and applied to the content <code translate="no" dir="ltr">div</code>, while on larger screens <code translate="no" dir="ltr">background-image: url(body.png)</code> is applied to the body and <code translate="no" dir="ltr">background-image: url(large.png)</code> is applied to the content <code translate="no" dir="ltr">div</code>.</p> <pre class="prettyprint lang-css" translate="no" dir="ltr"><code translate="no" dir="ltr">.example { height: 400px; background-image: url(small.png); background-repeat: no-repeat; background-size: contain; background-position-x: center; } @media (min-width: 500px) { body { background-image: url(body.png); } .example { background-image: url(large.png); } } </code></pre> <p><a href="https://googlesamples.github.io/web-fundamentals/fundamentals/design-and-ux/responsive/conditional-mq.html">Try it</a></p> <h3 id="use_image-set_to_provide_high_res_images" data-text="Use image-set to provide high res images" tabindex="-1">Use image-set to provide high res images</h3> <p>The <code translate="no" dir="ltr">image-set()</code> function in CSS enhances the behavior <code translate="no" dir="ltr">background</code> property, making it easy to provide multiple image files for different device characteristics. This allows the browser to choose the best image depending on the characteristics of the device, for example using a 2x image on a 2x display, or a 1x image on a 2x device when on a limited bandwidth network.</p> <pre class="prettyprint lang-css" translate="no" dir="ltr"><code translate="no" dir="ltr">background-image: image-set( url(icon1x.jpg) 1x, url(icon2x.jpg) 2x ); </code></pre> <p>In addition to loading the correct image, the browser also scales it accordingly. In other words, the browser assumes that 2x images are twice as large as 1x images, and so scales the 2x image down by a factor of 2, so that the image appears to be the same size on the page.</p> <p>Support for <code translate="no" dir="ltr">image-set()</code> is still new and is only supported in Chrome and Safari with the <code translate="no" dir="ltr">-webkit</code> vendor prefix. Take care to include a fallback image for when <code translate="no" dir="ltr">image-set()</code> is not supported; for example:</p> <pre class="prettyprint lang-css" translate="no" dir="ltr"><code translate="no" dir="ltr">.sample { width: 128px; height: 128px; background-image: url(icon1x.png); background-image: -webkit-image-set( url(icon1x.png) 1x, url(icon2x.png) 2x ); background-image: image-set( url(icon1x.png) 1x, url(icon2x.png) 2x ); } </code></pre> <p><a href="https://googlesamples.github.io/web-fundamentals/fundamentals/design-and-ux/responsive/image-set.html">Try it</a></p> <p>The above loads the appropriate asset in browsers that support image-set; otherwise it falls back to the 1x asset. The obvious caveat is that while <code translate="no" dir="ltr">image-set()</code> browser support is low, most browsers get the 1x asset.</p> <h3 id="use_media_queries_to_provide_high_res_images_or_art_direction" data-text="Use media queries to provide high res images or art direction" tabindex="-1">Use media queries to provide high res images or art direction</h3> <p>Media queries can create rules based on the <a href="http://www.html5rocks.com/en/mobile/high-dpi/#toc-bg">device pixel ratio</a>, making it possible to specify different images for 2x versus 1x displays.</p> <pre class="prettyprint lang-css" translate="no" dir="ltr"><code translate="no" dir="ltr">@media (min-resolution: 2dppx), (-webkit-min-device-pixel-ratio: 2) { /* High dpi styles & resources here */ } </code></pre> <p>Chrome, Firefox, and Opera all support the standard <code translate="no" dir="ltr">(min-resolution: 2dppx)</code>, while the Safari and Android browsers both require the older vendor prefixed syntax without the <code translate="no" dir="ltr">dppx</code> unit. Remember, these styles are only loaded if the device matches the media query, and you must specify styles for the base case. This also provides the benefit of ensuring something is rendered if the browser doesn't support resolution-specific media queries.</p> <pre class="prettyprint lang-css" translate="no" dir="ltr"><code translate="no" dir="ltr">.sample { width: 128px; height: 128px; background-image: url(icon1x.png); } @media (min-resolution: 2dppx), /* Standard syntax */ (-webkit-min-device-pixel-ratio: 2) /* Safari & Android Browser */ { .sample { background-size: contain; background-image: url(icon2x.png); } } </code></pre> <p><a href="https://googlesamples.github.io/web-fundamentals/fundamentals/design-and-ux/responsive/media-query-dppx.html">Try it</a></p> <p>You can also use the min-width syntax to display alternative images depending on the viewport size. This technique has the advantage that the image is not downloaded if the media query doesn't match. For example, <code translate="no" dir="ltr">bg.png</code> is only downloaded and applied to the <code translate="no" dir="ltr">body</code> if the browser width is 500px or greater:</p> <pre class="prettyprint lang-css" translate="no" dir="ltr"><code translate="no" dir="ltr">@media (min-width: 500px) { body { background-image: url(bg.png); } } </code></pre> <h2 id="use_svg_for_icons" data-text="Use SVG for icons" tabindex="-1">Use SVG for icons</h2> <p>When adding icons to your page, use SVG icons where possible or in some cases, unicode characters.</p> <h3 id="summary_3" data-text="Summary" tabindex="-1">Summary</h3> <ul> <li>Use SVG or unicode for icons instead of raster images.</li> </ul> <h3 id="replace_simple_icons_with_unicode" data-text="Replace simple icons with unicode" tabindex="-1">Replace simple icons with unicode</h3> <p>Many fonts include support for the myriad of unicode glyphs, which can be used instead of images. Unlike images, unicode fonts scale well and look good no matter how small or large they appear on screen.</p> <p>Beyond the normal character set, unicode may include symbols for arrows (←), math operators (√), geometric shapes (★), control pictures (▶), music notation (♬), Greek letters (Ω), even chess pieces (♞).</p> <p>Including a unicode character is done in the same way named entities are: <code translate="no" dir="ltr">&#XXXX</code>, where <code translate="no" dir="ltr">XXXX</code> represents the unicode character number. For example:</p> <pre class="prettyprint lang-html" translate="no" dir="ltr"><code translate="no" dir="ltr">You're a super &#9733; </code></pre> <p>You're a super ★</p> <h3 id="replace_complex_icons_with_svg" data-text="Replace complex icons with SVG" tabindex="-1">Replace complex icons with SVG</h3> <p>For more complex icon requirements, SVG icons are generally lightweight, easy to use, and can be styled with CSS. SVG have a number of advantages over raster images:</p> <ul> <li>They're vector graphics that can be infinitely scaled.</li> <li>CSS effects such as color, shadowing, transparency, and animations are straightforward.</li> <li>SVG images can be inlined right in the document.</li> <li>They are semantic.</li> <li>They provide better accessibility with the appropriate attributes.</li> </ul> <pre class="prettyprint lang-html" translate="no" dir="ltr"><code translate="no" dir="ltr">With SVG icons, you can either add icons using inline SVG, like this checkmark: <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 32 32"> <path d="M27 4l-15 15-7-7-5 5 12 12 20-20z" fill="#000000"></path> </svg> or by using an image tag, like this credit card icon: <img src="credit.svg">. </code></pre> <p><a href="https://googlesamples.github.io/web-fundamentals/fundamentals/design-and-ux/responsive/icon-svg.html">Try it</a></p> <h3 id="use_icon_fonts_with_caution" data-text="Use icon fonts with caution" tabindex="-1">Use icon fonts with caution</h3> <figure> <img src="/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e.png" alt="Example of a page that uses FontAwesome for its font icons." width="320" height="568" srcset="https://web.dev/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e_36.png 36w,https://web.dev/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e_48.png 48w,https://web.dev/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e_72.png 72w,https://web.dev/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e_96.png 96w,https://web.dev/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e_480.png 480w,https://web.dev/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e_720.png 720w,https://web.dev/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e_856.png 856w,https://web.dev/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e_960.png 960w,https://web.dev/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e_1440.png 1440w,https://web.dev/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e_1920.png 1920w,https://web.dev/static/articles/responsive-images/image/example-a-page-uses-fon-dbf8a265a1b2e_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="wd-caption"> <a href="https://googlesamples.github.io/web-fundamentals/fundamentals/design-and-ux/responsive/icon-font.html" target="_blank" class="external"> Example of a page that uses FontAwesome for its font icons. </a> </figcaption> </figure> <p>Icon fonts are popular, and can be easy to use, but have some drawbacks compared to SVG icons:</p> <ul> <li>They're vector graphics that can be infinitely scaled, but may be anti-aliased resulting in icons that aren’t as sharp as expected.</li> <li>Limited styling with CSS.</li> <li>Pixel perfect positioning can be difficult, depending on line-height, letter spacing, etc.</li> <li>They aren't semantic, and can be difficult to use with screen readers or other assistive technology.</li> <li>Unless properly scoped, they can result in a large file size for only using a small subset of the icons available.</li> </ul> <pre class="prettyprint lang-html" translate="no" dir="ltr"><code translate="no" dir="ltr">With Font Awesome, you can either add icons by using a unicode entity, like this HTML5 logo (<span class="awesome">&#xf13b;</span>) or by adding special classes to an &lt;i&gt; element like the CSS3 logo (<i class="fa fa-css3"></i>). </code></pre> <p><a href="https://googlesamples.github.io/web-fundamentals/fundamentals/design-and-ux/responsive/icon-font.html">Try it</a></p> <p>There are hundreds of free and paid icon fonts available including <a href="https://fortawesome.github.io/Font-Awesome/">Font Awesome</a>, <a href="http://pictos.cc/">Pictos</a>, and <a href="https://glyphicons.com/">Glyphicons</a>.</p> <p>Be sure to balance the weight of the additional HTTP request and file size with the need for the icons. For example, if you only need a handful of icons, it may be better to use an image or an image sprite.</p> <h2 id="optimize_images_for_performance" data-text="Optimize images for performance" tabindex="-1">Optimize images for performance</h2> <p>Images often account for most of the downloaded bytes and also often occupy a significant amount of the visual space on the page. As a result, optimizing images can often yield some of the largest byte savings and performance improvements for your website: the fewer bytes the browser has to download, the less competition there is for client's bandwidth and the faster the browser can download and display all the assets.</p> <h3 id="summary_4" data-text="Summary" tabindex="-1">Summary</h3> <ul> <li>Don't just randomly choose an image format—understand the different formats available and use the format best suited.</li> <li>Include image optimization and compression tools into your workflow to reduce file sizes.</li> <li>Reduce the number of http requests by placing frequently used images into image sprites.</li> <li>To improve the initial page load time and reduce the initial page weight, consider loading images only after they’ve scrolled into view.</li> </ul> <h3 id="choose_the_right_format" data-text="Choose the right format" tabindex="-1">Choose the right format</h3> <p>There are two types of images to consider: <a href="https://en.wikipedia.org/wiki/Vector_graphics">vector images</a> and <a href="https://en.wikipedia.org/wiki/Raster_graphics">raster images</a>. For raster images, you also need to choose the right compression format, for example: <code translate="no" dir="ltr">GIF</code>, <code translate="no" dir="ltr">PNG</code>, <code translate="no" dir="ltr">JPG</code>.</p> <p><strong>Raster images</strong>, like photographs and other images, are represented as a grid of individual dots or pixels. Raster images typically come from a camera or scanner, or can be created in the browser with the <code translate="no" dir="ltr">canvas</code> element. As the image size gets larger, so does the file size. When scaled larger than their original size, raster images become blurry because the browser needs to guess how to fill in the missing pixels.</p> <p><strong>Vector images</strong>, such as logos and line art, are defined by a set of curves, lines, shapes, and fill colors. Vector images are created with programs like Adobe Illustrator or Inkscape and saved to a vector format like <a href="https://css-tricks.com/using-svg/"><code translate="no" dir="ltr">SVG</code></a>. Because vector images are built on simple primitives, they can be scaled without any loss in quality or change in file size.</p> <p>When choosing the appropriate format, it is important to consider both the origin of the image (raster or vector), and the content (colors, animation, text, etc). No one format fits all image types, and each has its own strengths and weaknesses.</p> <p>Start with these guidelines when choosing the appropriate format:</p> <ul> <li>Use <code translate="no" dir="ltr">JPG</code> for photographic images.</li> <li>Use <code translate="no" dir="ltr">SVG</code> for vector art and solid color graphics such as logos and line art. If vector art is unavailable, try <code translate="no" dir="ltr">WebP</code> or <code translate="no" dir="ltr">PNG</code>.</li> <li>Use <code translate="no" dir="ltr">PNG</code> rather than <code translate="no" dir="ltr">GIF</code> as it allows for more colors and offers better compression ratios.</li> <li>For longer animations consider using <code translate="no" dir="ltr"><video></code>, which provides better image quality and gives the user control over playback.</li> </ul> <h3 id="reduce_the_file_size" data-text="Reduce the file size" tabindex="-1">Reduce the file size</h3> <p>You can reduce image file size considerably by "post-processing" the images after saving. There are a number of tools for image compression—lossy and lossless, online, GUI, command line. Where possible, it's best to try automating image optimization so that it's a built-in to your workflow.</p> <p>Several tools are available that perform further, lossless compression on <code translate="no" dir="ltr">JPG</code> and <code translate="no" dir="ltr">PNG</code> files with no effect on image quality. For <code translate="no" dir="ltr">JPG</code>, try <a href="http://jpegclub.org/">jpegtran</a> or <a href="http://freshmeat.net/projects/jpegoptim/">jpegoptim</a> (available on Linux only; run with the --strip-all option). For <code translate="no" dir="ltr">PNG</code>, try <a href="http://optipng.sourceforge.net/">OptiPNG</a> or <a href="http://www.advsys.net/ken/util/pngout.htm">PNGOUT</a>.</p> <h3 id="use_image_sprites" data-text="Use image sprites" tabindex="-1">Use image sprites</h3> <figure> <img src="/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5.png" alt="Image sprite sheet used in example" width="190" height="352" srcset="https://web.dev/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5_36.png 36w,https://web.dev/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5_48.png 48w,https://web.dev/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5_72.png 72w,https://web.dev/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5_96.png 96w,https://web.dev/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5_480.png 480w,https://web.dev/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5_720.png 720w,https://web.dev/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5_856.png 856w,https://web.dev/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5_960.png 960w,https://web.dev/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5_1440.png 1440w,https://web.dev/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5_1920.png 1920w,https://web.dev/static/articles/responsive-images/image/image-sprite-sheet-used-5dca0dfa226c5_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> </figure> <p>CSS spriting is a technique whereby a number of images are combined into a single "sprite sheet" image. You can then use individual images by specifying the background image for an element (the sprite sheet) plus an offset to display the correct part.</p> <pre class="prettyprint lang-css" translate="no" dir="ltr"><code translate="no" dir="ltr">.sprite-sheet { background-image: url(sprite-sheet.png); width: 40px; height: 25px; } .google-logo { width: 125px; height: 45px; background-position: -190px -170px; } .gmail { background-position: -150px -210px; } .maps { height: 40px; background-position: -120px -165px; } </code></pre> <p><a href="https://googlesamples.github.io/web-fundamentals/fundamentals/design-and-ux/responsive/image-sprite.html">Try it</a></p> <p>Spriting has the advantage of reducing the number of downloads required to get multiple images, while still enabling caching.</p> <h3 id="consider_lazy_loading" data-text="Consider lazy loading" tabindex="-1">Consider lazy loading</h3> <p>Lazy loading can significantly speed up loading on long pages that include many images below the fold by loading them either as needed or when the primary content has finished loading and rendering. In addition to performance improvements, using lazy loading can create infinite scrolling experiences.</p> <p>Be careful when creating infinite scrolling pages—because content is loaded as it becomes visible, search engines may never see that content. In addition, users who are looking for information they expect to see in the footer, never see the footer because new content is always loaded.</p> <h2 id="avoid_images_completely" data-text="Avoid images completely" tabindex="-1">Avoid images completely</h2> <p>Sometimes the best image isn't actually an image at all. Whenever possible, use the native capabilities of the browser to provide the same or similar functionality. Browsers generate visuals that would have previously required images. This means that browsers no longer need to download separate image files thus preventing awkwardly scaled images. You can use unicode or special icon fonts to render icons.</p> <h3 id="place_text_in_markup_instead_of_embedded_in_images" data-text="Place text in markup instead of embedded in images" tabindex="-1">Place text in markup instead of embedded in images</h3> <p>Wherever possible, text should be text and not embedded into images. For example, using images for headlines or placing contact information—like phone numbers or addresses—directly into images prevents users from copying and pasting the information; it makes the information inaccessible for screen readers, and it isn't responsive. Instead, place the text in your markup and if necessary use webfonts to achieve the style you need.</p> <h3 id="use_css_to_replace_images" data-text="Use CSS to replace images" tabindex="-1">Use CSS to replace images</h3> <p>Modern browsers can use CSS features to create styles that would previously have required images. For example: complex gradients can be created using the <code translate="no" dir="ltr">background</code> property, shadows can be created using <code translate="no" dir="ltr">box-shadow</code>, and rounded corners can be added with the <code translate="no" dir="ltr">border-radius</code> property.</p> <style> p#noImage { margin-top: 2em; padding: 1em; padding-bottom: 2em; color: white; border-radius: 5px; box-shadow: 5px 5px 4px 0 rgba(9,130,154,0.2); background: linear-gradient(rgba(9, 130, 154, 1), rgba(9, 130, 154, 0.5)); } p#noImage code { color: rgb(64, 64, 64); } </style> <p id="noImage"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sit amet augue eu magna scelerisque porta ut ut dolor. Nullam placerat egestas nisl sed sollicitudin. Fusce placerat, ipsum ac vestibulum porta, purus dolor mollis nunc, pharetra vehicula nulla nunc quis elit. Duis ornare fringilla dui non vehicula. In hac habitasse platea dictumst. Donec ipsum lectus, hendrerit malesuada sapien eget, venenatis tempus purus. </p> <pre class="prettyprint lang-css" translate="no" dir="ltr"><code translate="no" dir="ltr"><style> div#noImage { color: white; border-radius: 5px; box-shadow: 5px 5px 4px 0 rgba(9,130,154,0.2); background: linear-gradient(rgba(9, 130, 154, 1), rgba(9, 130, 154, 0.5)); } </style> </code></pre> <p>Keep in mind that using these techniques does require rendering cycles, which can be significant on mobile. If over-used, you'll lose any benefit you may have gained and it may hinder performance.</p> </div> <devsite-thumb-rating position="footer"> </devsite-thumb-rating> <div class="devsite-floating-action-buttons"> </div> </article> <devsite-content-footer class="nocontent"> <p>Except as otherwise noted, the content of this page is licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 License</a>, and code samples are licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>. For details, see the <a href="https://developers.google.com/site-policies">Google Developers Site Policies</a>. Java is a registered trademark of Oracle and/or its affiliates.</p> <p>Last updated 2014-04-29 UTC.</p> </devsite-content-footer> <devsite-notification > </devsite-notification> <div class="devsite-content-data"> <template class="devsite-content-data-template"> [[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2014-04-29 UTC."],[],[]] </template> </div> </devsite-content> </main> <devsite-footer-promos class="devsite-footer"> </devsite-footer-promos> <devsite-footer-linkboxes class="devsite-footer"> <nav class="devsite-footer-linkboxes nocontent" aria-label="Footer links"> <ul class="devsite-footer-linkboxes-list"> <li class="devsite-footer-linkbox wd-footer-promo"> <h3 class="devsite-footer-linkbox-heading no-link">web.dev</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <h3 class="devsite-footer-linkbox-heading no-link"> web.dev </h3> <div class="devsite-footer-linkbox-description">We want to help you build beautiful, accessible, fast, and secure websites that work cross-browser, and for all of your users. This site is our home for content to help you on that journey, written by members of the Chrome team, and external experts.</div> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Contribute</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://issuetracker.google.com/issues/new?component=1400680&template=1857359" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > File a bug </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://issuetracker.google.com/issues?q=status:open%20componentid:1400680&s=created_time:desc" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > See open issues </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Related Content</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://developer.chrome.com/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Chrome for Developers </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://blog.chromium.org/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Chromium updates </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/case-studies" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Case studies </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/shows" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Podcasts & shows </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Follow</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://twitter.com/ChromiumDev" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > @ChromiumDev on X </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://www.youtube.com/user/ChromeDevelopers" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > YouTube </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://www.linkedin.com/showcase/chrome-for-developers" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Chrome for Developers on LinkedIn </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/static/blog/feed.xml" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > RSS </a> </li> </ul> </li> </ul> </nav> </devsite-footer-linkboxes> <devsite-footer-utility class="devsite-footer"> <div class="devsite-footer-utility nocontent"> <nav class="devsite-footer-utility-links" aria-label="Utility links"> <ul class="devsite-footer-utility-list"> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/terms" data-category="Site-Wide Custom Events" data-label="Footer Terms link" > Terms </a> </li> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/privacy" data-category="Site-Wide Custom Events" data-label="Footer Privacy link" > Privacy </a> </li> <li class="devsite-footer-utility-item glue-cookie-notification-bar-control"> <a class="devsite-footer-utility-link gc-analytics-event" href="#" data-category="Site-Wide Custom Events" data-label="Footer Manage cookies link" aria-hidden="true" > Manage cookies </a> </li> </ul> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> </nav> </div> </devsite-footer-utility> <devsite-panel></devsite-panel> </section></section> <devsite-sitemask></devsite-sitemask> <devsite-snackbar></devsite-snackbar> <devsite-tooltip ></devsite-tooltip> <devsite-heading-link></devsite-heading-link> <devsite-analytics> <script type="application/json" analytics>[]</script> <script type="application/json" tag-management>{"at": "True", "ga4": [], "ga4p": [], "gtm": [{"id": "GTM-MZWCJPP", "purpose": 0}], "parameters": {"internalUser": "False", "language": {"machineTranslated": "False", "requested": "en", "served": "en"}, "pageType": "article", "projectName": "Articles", "signedIn": "False", "tenant": "web", "recommendations": {"sourcePage": "", "sourceType": 0, "sourceRank": 0, "sourceIdenticalDescriptions": 0, "sourceTitleWords": 0, "sourceDescriptionWords": 0, "experiment": ""}, "experiment": {"ids": ""}}}</script> </devsite-analytics> <devsite-badger></devsite-badger> <script nonce="bPB/4IyxO3l3x2fesQ9Yr7viqVgvza"> (function(d,e,v,s,i,t,E){d['GoogleDevelopersObject']=i; t=e.createElement(v);t.async=1;t.src=s;E=e.getElementsByTagName(v)[0]; E.parentNode.insertBefore(t,E);})(window, document, 'script', 'https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/js/app_loader.js', '[27,"en",null,"/js/devsite_app_module.js","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web","https://web-dot-devsite-v2-prod-3p.appspot.com",1,null,["/_pwa/web/manifest.json","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/images/video-placeholder.svg","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/favicon.png","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/lockup.svg","https://fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"],1,null,[1,6,8,12,14,17,21,25,50,52,63,70,75,76,80,87,91,92,93,97,98,100,101,102,103,104,105,107,108,109,110,112,113,116,117,118,120,122,124,125,126,127,129,130,131,132,133,134,135,136,138,140,141,147,148,149,151,152,156,157,158,159,161,163,164,168,169,170,179,180,182,183,186,191,193,196],"AIzaSyCNm9YxQumEXwGJgTDjxoxXK6m1F-9720Q","AIzaSyCc76DZePGtoyUjqKrLdsMGk_ry7sljLbY","web.dev","AIzaSyB9bqgQ2t11WJsOX8qNsCQ6U-w91mmqF-I","AIzaSyAdYnStPdzjcJJtQ0mvIaeaMKj7_t6J_Fg",null,null,null,["MiscFeatureFlags__enable_firebase_utm","Profiles__enable_public_developer_profiles","Search__enable_page_map","Search__enable_dynamic_content_confidential_banner","Cloud__enable_cloudx_experiment_ids","Profiles__enable_recognition_badges","Profiles__enable_developer_profiles_callout","MiscFeatureFlags__enable_explain_this_code","Cloud__enable_cloud_dlp_service","Cloud__enable_cloud_shell","Analytics__enable_clearcut_logging","Profiles__enable_page_saving","MiscFeatureFlags__enable_view_transitions","Profiles__enable_completecodelab_endpoint","Search__enable_suggestions_from_borg","CloudShell__cloud_shell_button","Profiles__enable_profile_collections","Search__enable_ai_eligibility_checks","Profiles__enable_dashboard_curated_recommendations","Profiles__enable_complete_playlist_endpoint","Profiles__enable_release_notes_notifications","CloudShell__cloud_code_overflow_menu","OnSwitch__enable","Cloud__enable_cloud_facet_chat","Cloud__enable_cloudx_ping","DevPro__enable_cloud_innovators_plus","TpcFeatures__enable_mirror_tenant_redirects","MiscFeatureFlags__enable_project_variables","Cloud__enable_llm_concierge_chat","EngEduTelemetry__enable_engedu_telemetry","Cloud__enable_cloud_shell_fte_user_flow","Concierge__enable_pushui","Cloud__enable_legacy_calculator_redirect","BookNav__enable_tenant_cache_key","Profiles__require_profile_eligibility_for_signin","Cloud__enable_free_trial_server_call","MiscFeatureFlags__developers_footer_dark_image","MiscFeatureFlags__developers_footer_image","DevPro__enable_developer_subscriptions","TpcFeatures__enable_required_headers","MiscFeatureFlags__enable_variable_operator","Profiles__enable_awarding_url","MiscFeatureFlags__emergency_css","Experiments__reqs_query_experiments"],null,null,"AIzaSyA58TaKli1DculwmAmbpzLVGuWc8eCQgQc","https://developerscontentserving-pa.googleapis.com","AIzaSyDWBU60w0P9hEkr29kkksYs8Z7gvZ8u_wc","https://developerscontentsearch-pa.googleapis.com",2,4,null,"https://developerprofiles-pa.googleapis.com",[27,"web","web.dev","web.dev",null,"web-dot-devsite-v2-prod-3p.appspot.com",null,null,[null,null,null,null,null,null,null,null,null,null,null,[1],null,null,null,null,null,null,[1],null,null,null,null,[1,null,1],[1,1,null,1,1]],null,[38,null,null,null,null,null,"/images/lockup.svg","/images/touchicon-180.png",null,null,null,1,1,null,null,null,null,null,null,null,null,2,null,null,null,"/images/lockup-dark-theme.svg",[]],[],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[],[1,1]],[[null,null,null,null,null,["GTM-MZWCJPP"],null,null,null,null,null,[["GTM-MZWCJPP",1]],1]],null,4]]') </script> <devsite-a11y-announce></devsite-a11y-announce> </body> </html>