Привет, Хабр! Представляю вашему вниманию перевод статьи «The 6 most common mistakes developers when writing HTML and CSS» автора Stas Melnikov.

Использование атрибута placeholder вместо элемента label


Часто разработчики используют атрибут placeholder вместо элемента label. Но в этом случае пользователи скринридера (программы чтения с экрана) не могут заполнять поля, потому что скринридер не может прочитать текст из атрибута placeholder.

<input type="email" placeholder="Enter your email">

Поэтому я рекомендую использовать элемент label для поля имени и атрибут placeholder для примера данных, которые пользователь должен заполнить.

<label>
  <span>Enter your email</span>
  <input type="email" placeholder="e.g. example@gmail.com">
</label>

Использование элемента img для разметки декоративной графики


Я часто вижу, как разработчики путают декоративную графику с изображениями контента. Например, они размечают социальные иконки с помощью элемента img.

<a href="https://twitter.com" class="social">
  <img class="social__icon" src="twitter.svg" alt>
  <span class="social__name">Twitter</span>
</a>

Но иконка социальной сети — это декоративная иконка, которая помогает пользователям быстрее понять смысл элемента, не читая текст. Если мы удаляем значок, мы не теряем значение элемента, поэтому мы можем использовать для него свойство background-image.

<a href="https://twitter.com" class="social">
  <span class="social__name">Twitter</span>
</a>

.social::before {
  background-image: url("twitter.svg");
}

Использование свойства resize


При отключении изменения размера текстовой области с помощью свойства resize доступность ухудшается. Таким образом, пользователь не может ввести данные удобным для себя способом.

textarea {
  width: 100%;
  height: 200px;
  resize: none;
}

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

textarea {
  min-width: 100%;
  max-width: 100%;
  min-height: 200px;
  max-height: 400px;
}

Использование display: block и position: absolute (fixed) вместе.


Я часто вижу, как разработчики используют свойства display и position следующим образом:

.button::before {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  left: 0;
}

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

.button::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
}

Нет значения для свойства структуры


Я не могу работать с веб-сайтом, используя клавиатуру. Я не могу перейти по ссылке. Я не могу зарегистрироваться. Это происходит потому, что разработчики отключают фокус на элементах, когда они добавляют значение none для свойства outline.

.button:focus {
  outline: none;
}

/* or */

.button:focus {
  outline: 0;
}

Если вам нужно отключить фокусировку по умолчанию, не забудьте сделать состояние альтернативной фокусировки.

.button:focus {
  outline: none;
  box-shadow: 0 0 3px 0 blue;
}

Пустые элементы


Часто разработчики используют пустые элементы HTML для оформления элементов. Например, разметка меню-гамбургера с использованием пустых элементов div или span:

<button class="hamburger">
  <span></span>
  <span></span>
  <span></span>
</button>

.hamburger {
  width: 60px;
  height: 45px;
  position: relative;
}

.hamburger span {
  width: 100%;
  height: 9px;

  background-color: #d3531a;
  border-radius: 9px;

  position: absolute;
  left: 0;
}

.hamburger span:nth-child(1) {
  top: 0;
}

.hamburger span:nth-child(2) {
  top: 18px;
}

.hamburger span:nth-child(3) {
  top: 36px;
}

Но вы можете использовать псевдо-элементы :: before и :: after и достичь аналогичных результатов.

<button class="hamburger">
  <span class="hamburger__text">
    <span class="visually-hidden">Open menu</span>
  </span>
</button>

.hamburger {
  width: 60px;
  height: 45px;
  position: relative;
}

.hamburger::before,
.hamburger::after,
.hamburger__text::before {
  content: "";
  width: 100%;
  height: 9px;

  background-color: #d3531a;
  border-radius: 9px;

  position: absolute;
  left: 0;
}

.hamburger::before {
  top: 0;
}

.hamburger::after {
  top: 18px;
}

.hamburger__text::before {
  top: 36px;
}

.visually-hidden {
  position: absolute !important;
  clip: rect(1px, 1px, 1px, 1px);
  width: 1px !important; 
  height: 1px !important; 
  overflow: hidden;
}

Комментарии (13)


  1. DarkPreacher
    11.12.2019 17:39

    Для textarea можно использовать resize: vertical, сохраняется возможность изменить размер и не ломает макет.
    А вообще советы, как будто, из далёкого прошлого.


  1. PaulZi
    11.12.2019 19:20
    +1

    Последний вообще странный, вместо 3ёх пустых span будем использовать два вложенных span с текстом.


    1. Kozack
      11.12.2019 22:03

      Тут больше про доступность. В предложенном варианте кнопка имеет синтаксический текст который будет обработан разными читалками.


  1. dady_KK
    11.12.2019 20:02

    Про картинки годно, действительно часто начинающие так делает, да и сам когда-то так делал, но остальное — очень странно.


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


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


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


    Аутлайн — согласен, лучше так и делать, НО кроме разработчиков вообще мало кто использует клавиатуру для навигации, а разработчики — это зачастую не целевая аудитория. Ну а пример с гамбургером даже смысла комментировать нет — это вкусовщина, да непонятно, но если просто три спана заменить одним с классом и использовать псевдоэлементы — это более грамотное решение, чем ещё один вложенный спан, подпись также просто делается псевдоэлементом.


    1. stardust_kid
      11.12.2019 23:50

      В b2b еще как используют. Если у человека работа весь день формы забивать.


  1. andreymal
    11.12.2019 20:45
    +2

    они размечают социальные иконки
    Но браузер устанавливает значение блока по умолчанию.
    Нет значения для свойства структуры
    Если вам нужно отключить фокусировку по умолчанию, не забудьте сделать состояние альтернативной фокусировки.
    После гуглопереводчика текст нужно обязательно вычитывать.


  1. sinneren
    12.12.2019 10:05

    Использование атрибута placeholder вместо элемента label

    А ничего, что это обуславливается дизайном, а не хотелаками верстака? Как бы наличие лейбла это прерогатива дизигна


  1. ua30
    12.12.2019 11:27

    Использование элемента img для разметки декоративной графики
    Весьма спорная реализация. Я бы сделал через спрайт. Или base64 на крайний случай. А то получается недопример.


  1. Hooter
    12.12.2019 14:33

    Если вопрос про доступность, то странные немного советы.
    Если говорить про label то у него есть атрибут for. А в случае если его не нужно отображать, то добавляют дополнительный стиль sr-only, который выводит елеммент далеко за пределы экрана. И placeholder этому не помеха.
    Картинки можно рамещать в верстке, если они не влияют, достаточно указать alt с пустым значением.
    Фокус на все ссылки и контролы должен быть, это факт. При этом не важны есть стили или нет. Просто доступность по кнопке tab и shift+tab.


    1. sved
      12.12.2019 17:26

      Если речь идёт про доступность, то никакие модификации со стилями не должны менять содержимое сайта, ибо пользователи могут подключать свои stylesheet.
      Хороший способ протестировать доступность — это открыть в текстовом браузере


      1. Hooter
        13.12.2019 10:46

        Я вас возможно расстрою, но любые модификации возможны, и кнопки из div делать можно и из ссылок, и любые капризы за ваши деньги.
        Открываем WAI-ARIA Authoring Practices 1.1 или ARIA Landmarks Example

        Да семантическая верстка рулит, но если у вас что-то не так, это не значит, что нельзя это исправить. И скорее даже не исправить, а доделать все что бы обеспечить доступность, дописать и заполнить атрибуты для ридеров, добавить компоненты и меню доступные только с клавиатуры и тд и тп.


        1. sved
          13.12.2019 15:27

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

          Не совсем понятно, зачем вы прислали ссылку на Landmarks.
          А aria — это в некотором смысле костыль. Даже если пройдёте по вашей ссылке, то увидите например

          Unlike HTML input elements, ARIA roles do not cause browsers to provide keyboard behaviors or styling.


          Я довольно долго занимался accessibility чтобы утверждать, что требования доступности предъявляют наивысшие требования к качеству и логичности/стандартности вёрстки.
          И если у вас что-то не так, то есть шанс, что вы «попали», и придётся всё переделывать.
          К примеру, у вас локализовано 5% текста. Теперь для обеспечения доступности вам надо локализовать всё ибо lang атрибут прикреплён ко всей странице целиком.

          Более того кроме WCAG рекомендаций, есть ещё дополнительные, основанные на здравом смысле. Пользователи могут подключать свои стили и они имеют высший приоритет в браузерах. Найдите кастомные стили для слабозрячих, подключите. И если ваш сайт нормально отображается то да значит всё хорошо


  1. kash
    12.12.2019 19:29

    С картинками в background — лучше так не делайте. Точнее какой-то философский смысл в этом есть, но, на практике, часто пригодиться прописывать для иконки hover и/или focus, а это плюс одна картинка, которую надо отрабатывать. И не дай боже делать это на гос.сайте или сайте крупной конторы. Потому что там будет "«версия для слабовидящих» — это ещё 3-5 иконок для каждой цветовой схемы…

    Так что, в этом случае, все иконки лучше через svg, инлайно или через svg-спрайт вставлять. Либо вообще не верстать тк, иногда, проще вставить блок «поделиться», например, от Яндекса