Отзывчивый дизайн

В процессе перевода.

На заре веб-дизайна страницы создавались для экрана определенного размера. Если у пользователя был экран большего или меньшего размера чем ожидал дизайнер, то результат мог быть от нежелательных полос прокрутки, до слишком длинной строки и плохого использования пространства. Поскольку становились доступны много различных размеров экранов, появилась концепция отзывчивого (адаптивого) веб-дизайна (responsive web design (RWD)) — набор методов, которые позволяют веб-страницам менять свой макет и внешний вид в соответствии с разной шириной экрана, разрешением и т.д. Это та самая, идея которая изменила подход к дизайну веба для множества устройств, и в этой статье мы поможем вам понять основные методы, которые вам необходимо знать, чтобы освоить его.

Необходимые знания:

Основы HTML (изучите Введение в HTML), идея о том как работает CSS (изучите Введение в CSS и Устройство CSS.)

Задача:

Понять базовые концепции и историю отзывчивого дизайна.

Исторические макеты сайтов

В какой-то момент истории при разработке веб-сайта у вас было два варианта:

  • Вы могли создать жидкий сайт, который будет растягиваться чтобы заполнить окно браузера
  • или сайт с фиксированной шириной, который будет иметь фиксированный размер в пикселях.

Эти два подхода, как правило, приводили к тому, что веб-сайт лучше всего выглядел на экране человека, создавшего сайт! Жидкий сайт приводил к раздавленному дизайну на маленьких экранах (как видно ниже) и не читаемо длинным строкам на больших.

A layout with two columns squashed into a mobile size viewport.

Примечание: Посмотрите этот простой жидкий макет: пример, исходный код. При просмотре примера, растягивайте и сжимайте окно браузера чтобы увидеть, как это выглядит при разных размерах.

Сайт с фиксированной шириной рисковал иметь горизонтальную полосу прокрутки на экранах меньших чем ширина сайта (как видно ниже) и много белого пространства на краях дизайна на больших экранах.

A layout with a horizontal scrollbar in a mobile viewport.

Примечание: Посмотрите этот простой макет с фиксированной шириной: пример, исходный код. Снова изучите результат по мере изменения размера окна браузера.

Примечание: Скриншоты выше сделаны используя Responsive Design Mode в Firefox DevTools.

Когда мобильный веб стал становиться реальностью с первыми функциональными телефонами, компании желающие охватить мобильники начали создавать в основном специальные мобильные версии своих сайтов, с различными URL (часто что-то наподобие m.example.com или example.mobi). Это означало, что необходимо было разрабатывать и поддерживать в актуальном состоянии две отдельные версии сайта.

Кроме того, эти мобильные сайты часто предлагали очень урезанный вариант. Поскольку мобильные гаджеты стали мощнее и способными отображать целые веб-сайты, пользователей мобильных устройств раздражало, что они обнаруживали себя запертыми в мобильной версии сайта, неспособные получить доступ к информации, которая, как они знали, есть в полнофункциональной версии сайта.

Гибкий макет до отзывчивого дизайна

Было разработано несколько подходов чтобы попытаться разрешить недостатки построения веб-сайтов жидким методом или методом с фиксированной шириной. В 2004 году Камерон Адамс написал пост Resolution dependent layout, описывающий метод создания дизайна который мог бы адаптироваться к разным разрешениям экрана. Этот подход требовал, чтобы JavaScript узнавал разрешение экрана и загружал корректный CSS.

Зои Миккели Гилленвотер сыграла важную роль в свой работе описав и формализовав различные способы посредствам которых могут быть созданы гибкие сайты, пытаясь найти золотую середину между заполнением экрана или полностью фиксированным размером.

Отзывчивый дизайн

Термин адаптивный дизайн был Придуман Итаном Маркоттом в 2010 году и описывал использование трех методов в сочетании.

  1. Первой была идея жидких сеток, нечто что уже исследовала Гилленвотер, что можно прочитать в статье Маркотта - Fluid Grids (опубликовано в 2009 в A List Apart).
  2. Вторым методом была идея жидких изображений. Используя очень простой метод настройки свойства max-width на 100%, изображения будут становиться меньше если содержащий столбец становится уже чем изначальный размер изображения, но никогда не становится больше. Это позволяет изображению уменьшаться чтобы соответствовать столбцу гибких размеров, а не перекрываться с ним, но не расти и становиться пиксельным если столбец становится шире изображения.
  3. Третьим ключевым компонентом был media query. Media Query позволяют переключать тип макета применяя только CSS то, что Камерон Адамс исследовал, используя JavaScript. Вместо того чтобы иметь один макет для всех размеров экранов, макет мог изменяться. Боковые панели можно перемещать для маленьких экранов, либо отображать альтернативную навигацию.

Очень важно понять, что адаптивный веб-дизайн это не отдельная технология, это термин используемый, чтобы описать подход к веб-дизайну или набор лучших практик, используемых для создания макета, который может реагировать на используемое устройство для просмотра контента. В первоначальном исследовании Маркотта это означало гибкие сетки (с использованием floats) и media query, однако почти за 10 лет, прошедших с момента написания этой статьи, адаптивная работа стала стандартом по умолчанию. Современные методы макета CSS отзывчивы по своей сути, и у нас есть новые штучки, встроенные в веб-платформу для того, чтобы делать дизайн отзывчивых сайтов проще.

Остальная часть этой статьи укажет вам на различные функции веб-платформы, которые вы, возможно, захотите использовать при создании адаптивного сайта.

Media Queries (Медиа-запросы)

Отзывчивый дизайн был способен появится только благодаря media query. Спецификация Media Queries Level 3 стала Рекомендованным Кандидатом в 2009 году, что означает, что она была признана готовой к реализации в браузерах. Медиа запросы позволяют нам проводить серию тестов (например, является ли экран пользователя больше, чем определенная ширина или разрешение) и выборочно применять CSS к стилю страницы соответственно с нуждами пользователя.

For example, the following media query tests to see if the current web page is being displayed as screen media (therefore not a printed document) and the viewport is at least 800 pixels wide. The CSS for the .container selector will only be applied if these two things are true.

@media screen and (min-width: 800px) { 
  .container { 
    margin: 1em 2em; 
  } 
} 

You can add multiple media queries within a stylesheet, tweaking your whole layout or parts of it to best suit the various screen sizes. The points at which a media query is introduced, and the layout changed, are known as breakpoints.

A common approach when using Media Queries is to create a simple single-column layout for narrow-screen devices (e.g mobile phones), then check for larger screens and implement a multiple-column layout when you know that you have enough screen width to handle it. This is often described as mobile first design.

Find out more in the MDN documentation for Media Queries.

Flexible grids

Responsive sites don't just change their layout between breakpoints, they are built on flexible grids. A flexible grid means that you don't need to target every possible device size that there is, and build a pixel perfect layout for it. That approach would be impossible given the vast number of differently-sized devices that exist, and the fact that on desktop at least, people do not always have their browser window maximized.

By using a flexible grid, you only need to add in a breakpoint and change the design at the point where the content starts to look bad. For example, if the line lengths become unreadably long as the screen size increases, or a box becomes squashed with two words on each line as it narrows.

In the early days of responsive design, our only option for performing layout was to use floats. Flexible floated layouts were achieved by giving each element a percentage width, and ensuring that across the layout the totals were not more than 100%. In his original piece on fluid grids, Marcotte detailed a formula for taking a layout designed using pixels and converting it into percentages.

target / context = result 

For example, if our target column size is 60 pixels, and the context (or container) it is in is 960 pixels, we divide 60 by 960 to get a value we can use in our CSS, after moving the decimal point two places to the right.

.col { 
  width: 6.25%; /* 60 / 960 = 0.0625 */ 
} 

This approach will be found in many places across the web today, and it is documented here in the layout section of our Legacy layout methods article. It is likely that you will come across websites using this approach in your work, so it is worth understanding it, even though you would not build a modern site using a float-based flexible grid.

The following example demonstrates a simple responsive design using Media Queries and a flexible grid. On narrow screens the layout displays the boxes stacked on top of one another:

A mobile view of the layout with boxes stacked on top of each other vertically.

On wider screens they move to two columns:

A desktop view of a layout with two columns.

Note: You can find the live example and source code for this example on GitHub.

Modern layout technologies

Modern layout methods such as Multiple-column layout, Flexbox, and Grid are responsive by default. They all assume that you are trying to create a flexible grid and give you easier ways to do so.

Multicol

The oldest of these layout methods is multicol — when you specify a column-count, this indicates how many columns you want your content to be split into. The browser then works out the size of these, a size that will change according to the screen size.

.container { 
  column-count: 3; 
} 

If you instead specify a column-width, you are specifying a minimum width. The browser will create as many columns of that width as will comfortably fit into the container, then share out the remaining space between all the columns. Therefore the number of columns will change according to how much space there is.

.container { 
  column-width: 10em; 
} 

Flexbox

In Flexbox, flex items will shrink and distribute space between the items according to the space in their container, as their initial behavior. By changing the values for flex-grow and flex-shrink you can indicate how you want the items to behave when they encounter more or less space around them.

In the example below the flex items will each take an equal amount of space in the flex container, using the shorthand of flex: 1 as described in the layout topic Flexbox: Flexible sizing of flex items.

.container { 
  display: flex; 
} 

.item { 
  flex: 1; 
} 

Note: As an example, we have rebuilt the simple responsive layout above, this time using flexbox. You can see how we no longer need to use strange percentage values to calculate the size of the columns: example, source code.

CSS grid

In CSS Grid Layout the fr unit allows the distribution of available space across grid tracks. The next example creates a grid container with three tracks sized at 1fr. This will create three column tracks, each taking one part of the available space in the container. You can find out more about this approach to create a grid in the Learn Layout Grids topic, under Flexible grids with the fr unit.

.container { 
  display: grid; 
  grid-template-columns: 1fr 1fr 1fr; 
} 

Note: The grid layout version is even simpler as we can define the columns on the .wrapper: example, source code.

Responsive images

The simplest approach to responsive images was as described in Marcotte's early articles on responsive design. Basically, you would take an image that was at the largest size that might be needed, and scale it down. This is still an approach used today, and in most stylesheets, you will find the following CSS somewhere:

img {
  max-width: 100%;
} 

There are obvious downsides to this approach. The image might be displayed a lot smaller than its intrinsic size, which is a waste of bandwidth — a mobile user may be downloading an image several times the size of what they actually see in the browser window. In addition, you may not want the same image aspect ratio on mobile as on desktop. For example, it might be nice to have a square image for mobile, but show the same scene as a landscape image on desktop. Or, acknowledging the smaller size of an image on mobile you might want to show a different image altogether, one which is more easily understood at a small screen size. These things can't be achieved by simply scaling down an image.

Responsive Images, using the <picture> element and the <img> srcset and sizes attributes solve both of these problems. You can provide multiple sizes along with "hints" (meta data that describes the screen size and resolution the image is best suited for), and the browser will choose the most appropriate image for each device, ensuring that a user will download an image size appropriate for the device they are using.

You can also art direct images used at different sizes, thus providing a different crop or completely different image to different screen sizes.

You can find a detailed guide to Responsive Images in the Learn HTML section here on MDN.

Responsive typography

An element of responsive design not covered in earlier work was the idea of responsive typography. Essentially, this describes changing font sizes within media queries to reflect lesser or greater amounts of screen real estate.

In this example, we want to set our level 1 heading to be 4rem, meaning it will be four times our base font size. That's a really large heading! We only want this jumbo heading on larger screen sizes, therefore we first create a smaller heading then use media queries to overwrite it with the larger size if we know that the user has a screen size of at least 1200px.

html { 
  font-size: 1em; 
} 

h1 { 
  font-size: 2rem; 
} 

@media (min-width: 1200px) { 
  h1 {
    font-size: 4rem; 
  }
} 

We have edited our responsive grid example above to also include responsive type using the method outlined. You can see how the heading switches sizes as the layout goes to the two column version.

On mobile the heading is smaller:

A stacked layout with a small heading size.

On desktop, however, we see the larger heading size:

A two column layout with a large heading.

Note: See this example in action: example, source code.

As this approach to typography shows, you do not need to restrict media queries to only changing the layout of the page. They can be used to tweak any element to make it more usable or attractive at alternate screen sizes.

Using viewport units for responsive typography

An interesting approach is to use the viewport unit vw to enable responsive typography. 1vw is equal to one percent of the viewport width, meaning that if you set your font size using vw, it will always relate to the size of the viewport.

h1 {
  font-size: 6vw;
}

The problem with doing the above is that the user loses the ability to zoom any text set using the vw unit, as that text is always related to the size of the viewport. Therefore you should never set text using viewport units alone.

There is a solution, and it involves using calc(). If you add the vw unit to a value set using a fixed size such as ems or rems then the text will still be zoomable. Essentially, the vw unit adds on top of that zoomed value:

h1 {
  font-size: calc(1.5rem + 3vw);
}

This means that we only need to specify the font size for the heading once, rather than set it up for mobile and redefine it in the media queries. The font then gradually increases as you increase the size of the viewport.

See an example of this in action: example, source code.

The viewport meta tag

If you look at the HTML source of a responsive page, you will usually see the following <meta> tag in the <head> of the document.

<meta name="viewport" content="width=device-width,initial-scale=1">

This meta tag tells mobile browsers that they should set the width of the viewport to the device width, and scale the document to 100% of its intended size, which shows the document at the mobile-optimized size that you intended.

Why is this needed? Because mobile browsers tend to lie about their viewport width.

This meta tag exists because when the original iPhone launched and people started to view websites on a small phone screen, most sites were not mobile optimized. The mobile browser would, therefore, set the viewport width to 960 pixels, render the page at that width, and show the result as a zoomed-out version of the desktop layout. Other mobile browsers (e.g. on Google Android) did the same thing. Users could zoom in and pan around the website to view the bits they were interested in, but it looked bad. You will still see this today if you have the misfortune to come across a site that does not have a responsive design.

The trouble is that your responsive design with breakpoints and media queries won't work as intended on mobile browsers. If you've got a narrow screen layout that kicks in at 480px viewport width or less, and the viewport is set at 960px, you'll never see your narrow screen layout on mobile. By setting width=device-width you are overriding Apple's default width=960px with the actual width of the device, so your media queries will work as intended.

So you should always include the above line of HTML in the head of your documents.

There are other settings you can use with the viewport meta tag, however in general the above line is what you will want to use.

  • initial-scale: Sets the initial zoom of the page, which we set to 1.
  • height: Sets a specific height for the viewport.
  • minimum-scale: Sets the minimum zoom level.
  • maximum-scale: Sets the maximum zoom level.
  • user-scalable: Prevents zooming if set to no.

You should avoid using minimum-scale, maximum-scale, and in particular setting user-scalable to no. Users should be allowed to zoom as much or as little as they need to; preventing this causes accessibility problems.

Note: There is a CSS @ rule designed to replace the viewport meta tag — @viewport — however, it has poor browser support. When both are used the meta tag overrides @viewport.

Summary

Responsive design refers to a site or application design that responds to the environment in which it is viewed. It encompasses a number of CSS and HTML features and techniques and is now essentially just how we build websites by default. Consider the sites that you visit on your phone — it is probably fairly unusual to come across a site that is the desktop version scaled down, or where you need to scroll sideways to find things. This is because the web has moved to this approach of designing responsively.

It has also become much easier to achieve responsive designs with the help of the layout methods you have learned in these lessons. If you are new to web development today you have many more tools at your disposal than in the early days of responsive design. It is therefore worth checking the age of any materials you are referencing. While the historical articles are still useful, modern use of CSS and HTML makes it far easier to create elegant and useful designs, no matter what device your visitor views the site with.

In this module