Распространенные проблемы с CSS для интерфейсных проектов

Опубликовано: 2022-03-10
Краткое резюме ↬ В последние годы рендеринг и взаимодействие в разных браузерах стали более согласованными. Однако он по-прежнему не идеально однороден, и многие мелкие проблемы могут сбить вас с толку. Добавьте к этим проблемам различные размеры экрана, языковые предпочтения и человеческую ошибку, и мы обнаружим множество мелочей, которые сбивают с толку разработчика.

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

Давай начнем.

1. Сбросить фон button и элементы input

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

(Большой превью)

Сброс фона решит эту проблему:

 button { appearance: none; background: transparent; /* Other styles */ } 

См. «Кнопку пера» и «Ввод» Ахмада Шадида (@shadeed) на CodePen.

См. «Кнопку пера» и «Ввод» Ахмада Шадида (@shadeed) на CodePen.
Еще после прыжка! Продолжить чтение ниже ↓

2. Переполнение: scroll против auto

Чтобы ограничить высоту элемента и позволить пользователю прокручивать его, добавьте overflow: scroll-y . Это будет хорошо выглядеть в Chrome на macOS. Однако в Chrome Windows полоса прокрутки всегда присутствует (даже если содержимое короткое). Это связано с тем, что scroll-y будет отображать полосу прокрутки независимо от содержимого, тогда как overflow: auto будет отображать полосу прокрутки только при необходимости.

Слева: Chrome на macOS. Справа: Chrome в Windows. (Большой превью)
 .element { height: 300px; overflow-y: auto; } 

См. Pen overflow-y Ахмада Шадида (@shadeed) на CodePen.

См. Pen overflow-y Ахмада Шадида (@shadeed) на CodePen.

3. Добавьте flex-wrap

Заставьте элемент вести себя как гибкий контейнер, просто добавив display: flex . Однако, когда размер экрана уменьшается, браузер будет отображать горизонтальную полосу прокрутки на случай, если flex-wrap не добавлен.

 <div class="wrapper"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div>
 .wrapper { display: flex; } .item { flex: 0 0 120px; height: 100px; }

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

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

Решение довольно простое. Обертка должна знать, что когда места не хватает, она должна обернуть элементы.

 .wrapper { display: flex; flex-wrap: wrap; } 

См. flex-wrap Pen от Ahmad Shadeed (@shadeed) на CodePen.

См. flex-wrap Pen от Ahmad Shadeed (@shadeed) на CodePen.

4. Не используйте justify-content: space-between когда количество элементов Flex является динамическим

Когда justify-content: space-between применяется к flex-контейнеру, он распределяет элементы и оставляет между ними равное пространство. В нашем примере восемь элементов карточек, и они выглядят хорошо. Что, если по какой-то причине количество элементов равно семи? Второй ряд элементов будет выглядеть иначе, чем первый.

Обертка с восемью элементами. (Большой превью)
Обертка с семью элементами. (Большой превью)

См. Pen justify-content Ахмада Шадида (@shadeed) на CodePen.

См. Pen justify-content Ахмада Шадида (@shadeed) на CodePen.

В этом случае лучше использовать сетку CSS.

5. Длинные слова и ссылки

Когда статья просматривается на экране мобильного устройства, длинное слово или встроенная ссылка могут вызвать появление горизонтальной полосы прокрутки. Использование word-break в CSS предотвратит это.

Большой превью
 .article-content p { word-break: break-all; } 
(Большой превью)

Проверьте CSS-Tricks для деталей.

6. Прозрачные градиенты

При добавлении градиента с прозрачными начальной и конечной точками он будет выглядеть черным в Safari. Это потому, что Safari не распознает ключевое слово « transparent ». Заменив его на rgba(0, 0, 0, 0) , он будет работать, как и ожидалось. Обратите внимание на скриншот ниже:

Вверху: Chrome 70. Внизу: Safari 12. (Большой предварительный просмотр)
 .section-hero { background: linear-gradient(transparent, #d7e0ef), #527ee0; /*Other styles*/ }

Вместо этого должно быть:

 .section-hero { background: linear-gradient(rgba(0, 0, 0,0), #d7e0ef), #527ee0; /*Other styles*/ }

7. Заблуждение о разнице между auto-fit и auto-fill в CSS Grid

В сетке CSS функция repeat может создать адаптивный макет столбца, не требуя использования медиа-запросов. Для этого используйте auto-fill или auto-fit .

 .wrapper { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); } 
(Большой превью)

Короче говоря, auto-fill упорядочивает столбцы, не увеличивая их ширину, тогда как auto-fit сворачивает их до нулевой ширины, но только если у вас есть пустые столбцы. Сара Суэйдан написала отличную статью на эту тему.

8. Фиксация элементов в верхней части экрана, когда окно просмотра недостаточно высокое

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

 @media (min-height: 500px) { .site-header { position: sticky; top: 0; /*other styles*/ } }

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

Также важно: когда вы используете position: sticky , это не будет работать, если вы не укажете свойство top .

Большой превью

См. Медиа-запросы Pen Vertical: фиксированный заголовок от Ahmad Shadeed (@shadeed) на CodePen.

См. Медиа-запросы Pen Vertical: фиксированный заголовок от Ahmad Shadeed (@shadeed) на CodePen.

9. Установка max-width для изображений

При добавлении изображения определите max-width: 100% , чтобы размер изображения изменялся при маленьком экране. В противном случае браузер отобразит горизонтальную полосу прокрутки.

 img { max-width: 100%; }

10. Использование сетки CSS для определения main и aside элементов

Сетку CSS можно использовать для определения main и aside частей макета, что идеально подходит для использования сетки. В результате высота aside секции будет равна высоте main элемента, даже если она пуста.

Чтобы исправить это, выровняйте элемент aside по началу его родителя, чтобы его высота не увеличивалась.

 .wrapper { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-gap: 20px; } // align-self will tell the aside element to align itself with the start of its parent. aside { grid-column: 1 / 4; grid-row: 1; align-self: start; } main { grid-column: 4 / 13; } 
(Большой превью)

См. Pen main и side от Ahmad Shadeed (@shadeed) на CodePen.

См. Pen main и side от Ahmad Shadeed (@shadeed) на CodePen.

11. Добавление fill в SVG

Иногда при работе с SVG fill не работает должным образом, если атрибут fill был добавлен в SVG. Чтобы решить эту проблему, либо удалите атрибут fill из самого SVG, либо переопределите fill: color .

Возьмите этот пример:

 .some-icon { fill: #137cbf; }

Это не сработает, если SVG имеет встроенную заливку. Вместо этого должно быть так:

 .some-icon path { fill: #137cbf; }

12. Работа с псевдоэлементами

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

При работе с ними автор может забыть сделать одно из следующего:

  • добавить свойство content: "" ,
  • установите width и height , не определяя для них свойство display .

В приведенном ниже примере у нас есть заголовок со значком в качестве псевдоэлемента. Необходимо добавить свойство content: "" . Кроме того, у элемента должен быть установлен display: inline-block , чтобы width и height работали должным образом.

Большой превью

13. Странное пространство при использовании display: inline-block

Установка двух или более элементов для display: inline-block или display: inline создаст крошечное пространство между каждым из них. Пробел добавляется, потому что браузер интерпретирует элементы как слова, поэтому между каждым из них добавляется пробел.

В приведенном ниже примере каждый элемент имеет пространство 8 8px с правой стороны, но крошечное пространство, вызванное использованием display: inline-block , делает его равным 12 12px , что не является желаемым результатом.

 li:not(:last-child) { margin-right: 8px; } 
(Большой превью)

Простое исправление для этого — установить font-size: 0 для родительского элемента.

 ul { font-size: 0; } li { font-size: 16px; /*The font size should be reassigned here because it will inherit `font-size: 0` from its parent.*/ } 
(Большой превью)

См. Интервал между блоками Pen Inline от Ahmad Shadeed (@shadeed) на CodePen.

См. Интервал между блоками Pen Inline от Ahmad Shadeed (@shadeed) на CodePen.

14. Добавьте for="ID" при назначении элемента метки входу

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

 <label for="emailAddress">Email address:</label> <input type="email"> 
Большой превью

15. Шрифты не работают с интерактивными элементами HTML

При назначении шрифтов всему документу они не будут применяться к таким элементам, как input , button , select и textarea . По умолчанию они не наследуются, потому что браузер применяет к ним системный шрифт по умолчанию.

Чтобы исправить это, назначьте свойство шрифта вручную:

 input, button, select, textarea { font-family: your-awesome-font-name; }

16. Горизонтальная полоса прокрутки

Некоторые элементы вызывают появление горизонтальной полосы прокрутки из-за ширины этих элементов.

Самый простой способ найти причину этой проблемы — использовать структуру CSS. Эдди Османи поделилась очень удобным скриптом, который можно добавить в консоль браузера, чтобы выделить каждый элемент на странице.

 [].forEach.call($$("*"), function(a) { a.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16); }); 
(Большой превью)

17. Сжатые или растянутые изображения

Когда вы изменяете размер изображения в CSS, оно может быть сжато или растянуто, если соотношение сторон не соответствует ширине и высоте изображения.

Решение простое: используйте object-fit CSS. Его функциональность аналогична функции background-size: cover для фоновых изображений.

 img { object-fit: cover; } 
(Большой превью)

Использование object-fit не будет идеальным решением во всех случаях. Некоторые изображения должны отображаться без обрезки или изменения размера, а некоторые платформы заставляют пользователя загружать или обрезать изображение определенного размера. Например, Dribbble принимает загрузку миниатюр размером 800 на 600 пикселей.

18. Добавьте правильный type для input .

Используйте правильный type для поля input . Это улучшит взаимодействие с пользователем в мобильных браузерах и сделает его более доступным для пользователей.

Вот немного HTML:

 <form action=""> <p> <label for="name">Full name</label> <input type="text" id="name"> </p> <p> <label for="email">Email</label> <input type="email" id="email"> </p> <p> <label for="phone">Phone</label> <input type="tel" id="phone"> </p> </form>

Вот как каждый вход будет выглядеть после того, как он будет сфокусирован:

(Большой превью)

19. Телефонные номера в макетах RTL

При добавлении номера телефона, такого как + 972-123555777 , в макете справа налево, символ плюса будет расположен в конце номера. Чтобы это исправить, переназначьте направление номера телефона.

 p { direction: ltr; } 
(Большой превью)

Заключение

Все проблемы, упомянутые здесь, являются одними из наиболее распространенных, с которыми я сталкивался в своей работе по разработке интерфейса. Моя цель — вести список для регулярной проверки во время работы над веб-проектом.

У вас есть проблема, с которой вы всегда сталкиваетесь в CSS? Дайте нам знать об этом в комментариях!