От автора: Причины, по которым HTML и CSS могут заставить вас сказать «черт возьми!» Рекомендованный к прочтению список недоумений, промахов и дилемм, связанных с HTML и CSS, которые многих раздражают.
Объявляйте doctype
Всегда включайте doctype. Я рекомендую простой HTML5 doctype:
1 |
<!DOCTYPE html> |
Пропуск doctype может вызвать проблемы, такие как плохо сформированные таблицы и поля ввода и многое другое, т.к. страница будет отображаться в режиме совместимости.
Математика блочной модели
Элементы, которым задана ширина, становятся шире, если им задать padding или/и границы (border-width). Чтобы избежать этих проблем, используйте уже распространенное свойство сброса box-sizing: border-box; reset.
Единицы rem и мобильная версия браузера Safari
В то время как мобильный Safari поддерживает использование rem в значениях всех свойств, он пасует как rem используются в размерных медиа запросах и текст страницы постоянно меняет размеры. Пока что используйте em вместо rem.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
html { font-size: 16px; } /* Вызывает мигающий баг в Safari */ @media (min-width: 40rem) { html { font-size: 20px; } } /* Отлично работает в мобильной версии Safari */ @media (min-width: 40em) { html { font-size: 20px; } } |
Плавающие элементы первыми
Плавающие элементы должны идти первыми в порядке документа. Плавающие элементы необходимо заворачивать, иначе они прыгнут вверх, вместо того чтобы идти после контента.
1 2 3 4 5 6 |
<div class="parent"> <div class="float">Плавающий элемент </div> <div class="content"> <!-- ... --> </div> </div> |
Плавающие элементы и использование свойства clear
Если вы задаете float, то возможно вам необходимо использовать clear. Любой контент, который следует за плавающим элементом, будет обтекать его, если не задано свойство clear. Во избежание обтекания используйте одну из следующих техник. Используйте технику микро clearfix с отдельным классом.
1 2 3 4 5 6 7 8 |
.clearfix:before, .clearfix:after { display: table; content: ""; } .clearfix:after { clear: both; } |
Или свойство overflow, задавая значения auto либо hidden родительским элементам.
1 2 3 4 5 6 |
.parent { overflow: auto; /* clearfix */ } .other-parent { overflow: hidden; /* clearfix */ } |
Учтите, что overflow может вызвать непреднамеренные побочные эффекты вокруг позиционированных элементов в пределах родительского.
Подсказка! Избавьте себя и коллег от проблем в будущем, включая комментарии вида /* clearfix */ когда предотвращаете обтекание плавающих элементов, т.к. это свойство может быть использовано и в других целях.
Плавающие элементы и автоматическая высота
Родительский элемент, внутри которого находятся только плавающие, будет иметь высоту равную 0. Добавляйте .clearfix к родительскому элементу, чтобы заставить браузеры подсчитать высоту.
Плавающие элементы всегда блочные
Элементы, которым задано свойство float автоматически приобретают display: block; . Задавать его отдельно нет необходимости т.к. float все равно получит больший приоритет, и значение свойства display не будет играть роли.
1 2 3 4 |
.element { float: left; display: block; /* Не обязательно */ } |
Забавный факт: Несколько лет назад, нам нужно было задавать display: inline; большинству плавающих элементов, для корректной работы в IE6, чтобы избежать бага, связанного с двойными внешними отступами. Но те времена давно прошли.
Смежные вертикальные отступы свертываются
Верхние и нижние отступы прилегающих элементов (следующих один за другим) могут и будут налегать друг на друга во многих ситуациях, но только не для плавающих и абсолютно позиционированных элементов. Прочитайте эту статью от Mozilla либо описание свертывания внешних отступов в спецификации CSS2, чтобы узнать больше. Отступы, прилегающие горизонтально никогда не будут свертываться.
Стилизация строк таблицы
Строки таблицы, tr, не имеют границ border, если вы не зададите border-collapse: collapse; родительской таблице table. Более того, если тэг tr и дочерние тэги td или th имеют одинаковую ширину границ (border-width), то стили, примененные непосредственно к строке не будут видны. Пройдите по этой ссылке, чтобы увидеть пример.
Firefox и кнопки input
По неизвестным причинам Firefox применяет свойство line-height к отправке и другим кнопкам input, это свойство нельзя переопределить своим CSS. У вас есть два выхода из этой ситуации:
Использовать элементы button
Не использовать line-height в своих кнопках
Если вы следуете по первому пути (и я его все равно рекомендую, потому что элементы button -отличное решение), вот что вам стоит знать:
1 2 3 4 5 6 7 |
<!—Не так хорошо --> <input type="submit" value="Save changes"> <input type="button" value="Cancel"> <!—Отлично работает везде --> <button type="submit">Save changes</button> <button type="button">Cancel</button> |
Если вы следуете по второму пути, просто не используйте line-height и используйте только padding для вертикального расположения текста. Посмотрите на этот пример в Firefox’e, чтобы увидеть первоначальную проблему и ее решение.
Хорошие новости! Кажется, это поведение будет исправлено в 30 версии Firefox. Это хорошие новости для нас в будущем, но имейте ввиду, что исправление не повлияет на более ранние версии.
Внешние границы кнопок в Firefox
Firefox добавляет внешние границы кнопкам (элементам input и button) при фокусе (:focus). Очевидно, это сделано в целях доступности, но выглядит оно довольно странно. Используйте следующий код CSS, чтобы переопределить его:
1 2 3 4 5 |
input::-moz-focus-inner, button::-moz-focus-inner { padding: 0; border: 0; } |
Вы можете видеть это исправление в действии на этом примере, упомянутом в предыдущем разделе.
Подсказка! Обязательно включайте особое состояние при фокусе для кнопок, ссылок, полей ввода. Подобные меры доступности архи-важны как для профессиональных пользователей, использующих клавишу Tab для быстрой навигации по контенту, так и для тех, кто имеет проблемы со зрением.
Всегда задавайте тип элементам button
Значение по умолчанию submit, что означает любая кнопка формы, может ее отправить. Используйте type=”button” для всего, что не должно отправлять форму и type=”submit” для тех элементов, что должны.
1 2 |
<button type="submit">Save changes</button> <button type="button">Cancel</button> |
Для действий, которые требуют тэга button, но находятся за пределами формы, используйте type=”button”.
1 |
<button class="dismiss" type="button">x</button> |
Забавный факт: Очевидно IE7 не имеет должной поддержки для атрибута value у элемента button. Вместо того, чтобы брать значение из атрибута, он берет его из внутреннего HTML (контента, расположенного между открывающим и закрывающим тэгами button). Однако, я не вижу в этом большой проблемы по двум причинам: использование IE7 значительно сократилось, и задание и value и внутреннего HTML не применяется повсеместно.
Ограничение на количество селекторов в Internet Explorer
Internet Explorer 9 и ниже имеет максимальное значение для количества селекторов в файле стилей равное 4,096. Также есть лимит в 31 как для внешних файлов стилей так и для тэгов style на страницу. Все, что превышает этот лимит будет проигнорировано браузером. Либо разделите ваш CSS код, либо проведите рефакторинг. Я бы предложил последнее. В качестве полезной заметки, вот как браузеры подсчитывают селекторы:
1 2 3 4 5 6 7 8 9 10 11 |
/* Один селектор */ .element { } /* Два селектора */ .element, .other-element { } /* Еще три селектора */ input[type="text"], .form-control, .form-group > input { } |
Как работает position
Элементы, которым задано свойство position: fixed; располагаются относительно окна просмотра браузера. Элементы с position: absolute; располагаются относительно ближайшего родительского элемента, которому задано свойство position, отличное от static (например, relative, absolute или fixed).
Позиция и ширина
Не задавайте width: 100%; элементу, который имеет абсолютную либо фиксированную позицию, левую или правую. Использование width: 100%; — это то же самое что задать одновременно left: 0; и right: 0;. Используйте либо одно либо другое, но не все сразу.
Фиксированная позиция и трансформации
Браузеры нарушают position: fixed; кода родительскому элементу задан набор трансформаций (transform). Использование трансформаций создает новый контейнерный блок, который принудительно задаст родительскому элементу position: relative; и фиксированный элемент будет вести себя так, если б он имел position: absolute;
Посмотрите демо или прочитайте пост Эрика Майера на эту тему.
Источник: //wtfhtmlcss.com/
Редакция: Команда webformyself.