HimeraSearchDB
Carding_EbayThief
triada
CrackerTuch
d-shop
HimeraSearchDB

НОВОСТИ [Перевод] Интересные CSS-находки в дизайне Twitter

Bonnie
Оффлайн
Регистрация
12.04.17
Сообщения
19.095
Реакции
107
Репутация
0
Хочу, в очередной раз, рассказать о результатах исследования дизайна сайта, который привлёк моё внимание. я писал о CSS-механизмах, лежащих в основе нового дизайна Facebook. А теперь мне стало любопытно исследовать CSS-код Twitter. Новый дизайн Twitter появился почти год назад. В CSS-коде Twitter я нашёл много интересного: кое-что кажется мне просто замечательным, а кое-что — странным.



Соотношение сторон аватаров пользователей


Я обратил внимание на интересную реализацию аватара пользователя на странице профиля. В этой реализации используется CSS-техника сохранения соотношения сторон элемента.

21971bd388f5616da30e8cffb32d31bc.jpg


Аватар пользователя на странице профиля

Ниже показан HTML- и CSS-код, иллюстрирующие реализацию аватара.



.avatar {
position: relative;
width: 25%;
display: block;
}

.avatar-aspect-ratio {
width: 100%;
padding-bottom: 100%;
}

.avatar img {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
}


Техника сохранения соотношения сторон элемента работает благодаря тому, что, когда у элемента есть вертикальный внутренний отступ (свойство padding-bottom или padding-top), отступ зависит от ширины элемента. Взгляните на следующий пример:


.element {
width: 250px;
padding-bottom: 100%;
}


Вычисленное значение padding-bottom равняется 250px. Это означает, что у нас имеется идеальный квадрат. Команда Twitter использовала такую же технику, но в применении к элементу , который, по отношению к родительскому элементу, позиционирован абсолютно. Почему? Вот причина.

ceec3462deba4f49a04af72183d2d22c.png


С аватаром что-то не так

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

Теперь, когда мы разобрались с идеей, лежащей в основе этого решения, вернёмся к тому, как эта идея реализована в Twitter.

Свойство width: 25% основано на ширине элемента-обёртки. На моём экране это — 600px. Я задался вопросом о том, почему была выбрана именно такая методика. После того, как я лучше изучил CSS-код, я обратил внимание на то, что тот же самый компонент используется в модальном окне Edit Profile. Правда, элемент тут имеет меньший размер из-за использования следующего стиля:


.avatar {
max-width: 8rem; /* 112px вместо 150px (25%) */
}


Мне очень нравится идея управления изображениями путём воздействия только на свойство width. видео, иллюстрирующее эту идею.

6ba685977e090bfa41de3c32afdfa34a.png


Управление шириной изображения

можно найти демонстрационный проект к этому разделу.

Верхний внешний отступ, заданный в процентах


Для того чтобы аватар пользователя перекрывал бы фото, находящееся в верхней части страницы профиля, используется отрицательный внешний отступ, заданный в процентах:


.avatar {
margin-top: -18%;
}


Правда, в модальном окне Edit Profile для настройки верхнего внешнего отступа используется уже конструкция margin-top: -3rem. Обратите внимание на то, что отступ в модальном окне задаётся с использованием единиц измерения rem. Те же единицы измерения применяются и для настройки свойства max-width.

Странное использование CSS-функции calc()


Я обратил внимание на то, что для стилизации некоторых кнопок используется следующий CSS-код:


.button {
min-width: calc(45.08px)
}


Зачем передавать функции calc() единственное значение? Не вижу в этом смысла. Может, число 45.08 хотели округлить? Но оно при таком подходе не округляется до 45. Ширина кнопки очень мала. Кнопка, при переводе приложения на RTL-язык, вроде арабского, окажется слишком маленькой.

3643fac4f7f5b281c4c4daee828cc92f.jpg


Слишком маленькая кнопка

Функция calc() появляется во встроенном CSS-коде. Поэтому я полагаю, что это — результат динамической стилизации кнопки средствами React.

Смешивание CSS-фонов и HTML-изображений


Во многих местах сайта я обнаружил смешивание фоновых изображений, задаваемых средствами CSS, и HTML-изображений. Взгляните на следующий пример:



me.jpg



Я видел такое в профиле пользователя, и в компоненте, используемом при формировании сеточного макета. Интересно то, что свойство opacity элемента установлено в 0. Источником активного изображения является свойство background-image. Кроме того, тут используется и свойство background-size: cover, которое позволяет избежать искажения изображения.

Я попытался сделать всё наоборот, то есть — отобразить элемент и скрыть CSS-фон, и сравнил сеточные макеты. Ниже показаны результаты этого сравнения.
e740d6add70aa7fc0059162198770f9f.jpg


Слева — вариант, в котором используется фоновое изображение, а справа — вариант, в котором применяется HTML-изображение

Очевидно то, что изображение справа искажено! Не знаю, почему команда разработчиков не воспользовалась CSS-свойством object-fit: cover для предотвращения искажений. И мне хотелось бы узнать о том, почему тут используются два изображения.

Сброс стилей


Я заметил один паттерн, который заключается в постоянном использовании CSS-класса, который добавляется к элементам
. Вот соответствующий CSS-код:


.css-1dbjc4n {
align-items: stretch;
border: 0 solid black;
box-sizing: border-box;
display: flex;
flex-basis: auto;
flex-direction: column;
flex-shrink: 0;
margin-bottom: 0px;
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
min-height: 0px;
min-width: 0px;
padding-bottom: 0px;
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
position: relative;
z-index: 0;
}


Этот стиль применяется буквально к каждому элементу
, находящемуся на странице. Почему? Разве тут недостаточно сброса CSS-стилей?

Некоторые из вышеописанных стилей мне вполне понятны, вроде min-width: 0, так как тут прослеживается некоторая связь с Flexbox. Но как насчёт внутренних отступов, внешних отступов, границ? Почему у некоего элемента
надо сбрасывать стили, учитывая то, что у этого элемента нет соответствующих свойств?

Flexbox и min-width: 0


Значением по умолчанию свойства min-width является auto, которое оказывается равным нулю. Когда нечто выводится как flex-элемент, значение его свойства min-width равно размеру его содержимого. Позволение подобного поведения может нарушить макет в том случае, если содержимое элемента больше, чем он сам.

Для того чтобы избежать возникновения этой проблемы, нужно сбрасывать свойство min-width для потомков flex-элементов.

fffa8b96cd6ecce00b4fb3b2b1c77c67.png


Flex-элемент и Flexbox-обёртка

Макет, приведённый выше, показывает, что может произойти в том случае, если содержимое flex-элемента окажется слишком длинным. Обратите внимание на то, что текст выходит за пределы элемента-обёртки. А вот что получается при использовании свойства min-width: 0.

ff064b158f74c463ec2969c69e531c61.png


Содержимое не выходит за пределы flex-элемента

Использование свойства position: sticky


Я заметил использование свойства position: sticky в правой боковой панели Twitter (там, где выводятся медиа-тренды и рекомендации, касающиеся пользователей, на которых можно подписаться). Мне показалось интересным то, как организована работа со значениями свойств bottom и top при скроллинге. Значения, установленные по умолчанию, выглядят так:


.sidebar {
position: sticky;
width: 350px;
bottom: -470.5px;
}


Когда страницу прокручивают вниз, свойство bottom заменяется на свойство top: -480.5px. Я думаю, что дизайнеры поступили так для того чтобы позволить пользователю сначала дойти до конца боковой панели. Свойство top добавляется уже после этого.

Элементы-разделители


Так же, как и в проанализированном мной ранее дизайне Facebook, в дизайне Twitter, во многих местах, используются элементы-разделители. Всё это — flex-элементы, ширина которых установлена с использованием свойства flex-basis.

f910341c9584521ee7f014e1b33d41e9.jpg


Элементы-разделители

В первом элементе, приведённом на предыдущем изображении, при настройке элемента-разделителя используется свойство flex-grow: 1. Во втором используется фиксированная ширина, заданная в пикселях.

Оформление содержимого твитов


bcf21b6152c348b5563701d93ef3943f.png


Твит

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

97d6bfb1864c12be9cb43d4986c9825a.jpg


Оформление текста твита

Смайлик — это , в котором есть элемент
, в
содержатся два изображения. Одно — это CSS-фон, второе — HTML-изображение.

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

43701606760195d7d21ec7329d225bcb.png


Второе предложение

Использование вычисляемых значений для разделения элементов


63b5b5261dd990e2c358397744cdbab9.jpg


Кнопка Назад

При выполнении поиска в Twitter, или при открытии страницы профиля, можно видеть кнопку Назад. К этой кнопке применён стиль margin-left: -4px, задающий отрицательный внешний левый отступ. Меня заинтересовала процедура вычисления этого значения.


.back-button {
margin-left: calc(5px + (-1 * (39px - 1.5em)) / 2);
}


Вышеприведённые вычисления приводят к получению значения -4px. Почему бы не задать просто -4px? Не лучше ли это в данном случае, чем применение функции calc()?

Ширина навигационных ссылок


e0fab951b42a250ab60c645cea9e175f.jpg


Навигационные ссылки

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

Здесь моё внимание привлекло использование свойства flex-direction: column для каждого элемента навигационной панели. Почему? Нужно ли это в ситуации, когда тут используется лишь один дочерний элемент?

Внешний отступ, добавляемый «на всякий случай»


Отступ, о котором идёт речь, присутствует в дизайне для предотвращения нежелательного поведения макета страницы. Я обратил внимание на два примера использования внешних отступов, добавляемых к элементам, так сказать, «на всякий случай». Посмотрим на них.

43cb086726d8961372167e0a34c644e2.jpg


Отступы, добавляемые к элементам «на всякий случай». Слева — обычное содержимое элемента. Справа — содержимое, которое заметно длиннее обычного

Обратите внимание на то, что происходит в том случае, когда содержимое элемента заметно длиннее, чем его обычное содержимое. А именно, тут происходит следующее:

  1. Текст обрезается.
  2. Между элементами присутствует внешний отступ.

Внешний отступ играет роль местозаполнителя, который не даёт элементу занять всё пространство. Если вовремя это учесть, можно избежать неожиданных проблем, которые могут возникнуть в процессе работы проекта. Рекомендуется всегда тестировать макеты страниц с использованием содержимого, длина которого превышает некую «обычную» длину.

Модальные окна в областях просмотра маленькой высоты


Я исследовал модальное окно редактирования профиля. Оказалось, что при определённой высоте области просмотра кнопка Save такого окна недоступна. Вот как это выглядит.

7f84622114a4c72b7b66b8eb8a4875ee.png


Недоступная кнопка Save

Так как модальное окно не поддерживает прокрутку, до кнопки Save мне добраться не удалось. А вот окно, используемое для управления внешним видом элементов, поддерживает динамическое изменение высоты и скроллинг.

e6ed62a59ff12a6e89abcd7b5b38194b.png


Окно, поддерживающее динамическое изменение высоты

Почему одно окно поддерживает скроллинг, а другое — нет? Интересно знать, какое из них, по мнению дизайнеров Twitter, важнее? Как по мне — так это именно то окно, которое используется для редактирования профиля.

А вы планируете ли вы взять на вооружение какие-нибудь идеи из дизайна Twitter?

 
Сверху Снизу