- PVSM.RU - https://www.pvsm.ru -
Здесь я поделюсь своими наработками для нормализации и сброса стилей.
За несколько лет у меня сформировался небольшой файл, за основу которого, изначально, был взят нормалайз.
Почему нормалайз, а не ресет. Он заточен именно под кросбраузерность, что очень важно. Но в чистом виде он меня вообще не устраивал, различные отступы, бордеры и т. д. только мешали, потому я немного подогнал его под свои потребности, поудаляв то, что мне было не нужно.
Со временем файл разрастался, лишнее из нормалайза удалялось, недостающее добавлялось.
Основной целью его создания было максимально подготовить основу для любого проэкта, что по-моему получилось, даже очень удачно. Файл получился довольно универсальный, но все же перед подготовкой проэкта в него нужно заглядывать и возможно что-то коректировать.
Надеюсь вы подчеркнете для себя что-то полезное, здесь вы можете ознакомиться с ним.
custom-reset.css [1]
*,
*:before,
*:after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
}
Такое определение дает возможность переопределить box-sizing
, в случае необходимости, для определенной области, например, если на проект был добавлен компомент у которого был box-sizing: content-box;
body {
margin: 0;
background-color: #fff;
line-height: 1.15;
text-rendering: optimizeLegibility;
text-decoration-skip: objects;
-webkit-text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
}
text-rendering
— определяет как браузеру оптимизировать рендеринг текста.optimizeLegibility
– качественное отображение важнее скорости, разрешает кернинг и лигатуры.
text-decoration-skip: objects;
text-decoration: underline;
необрывистым (там где это работает).
-webkit-text-size-adjust: 100%;
— запретить корректировку размера шрифта после изменения ориентации в iOS.
-webkit-font-smoothing: antialiased;
— делает текст более тонким в Сафари на Маках (начертание сглаженное и четкое одновременно, приятно читать.).
-webkit-tap-highlight-color: transparent;
— убирает синее подсвечивание при клике на девайсах.
:focus {
outline: none;
}
Состояние фокуса это очень важный момент для взаимодействия с интерективными элементами. (Как и почему здесь [2]). Но outline
зачастую не вписывается в дизайн. И сами дизайнеры редко прорисовывают это состоние, потому частой практикой стало дублирование стилей ховера.
Это ленивый способ.
.no-touch {
&:hover,
&:focus {
...
}
}
Нормальные дизайнеры всегда прорисовывают состояние фокуса.
Три основных состояния должны всегда присутствовать на каждом интерактивном элементе (:hover, :focus, :active
).
→ Codepen [3]
Отступы обнулены, текстовые свойства наследуются.
p,
dd,
dl,
figure,
blockquote {
margin: 0;
}
/* Совутую не забывать о списке определений <dl>. Семантика это хорошо.
Для более удобного использования можно позьзоваться дивом (валидно):
dl>div*3>dd{value}+dt{prop} */
blockquote,
q {
quotes: none;
}
ul,
ol {
padding: 0;
margin: 0;
list-style-type: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
th {
font-weight: inherit;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0;
font-size: inherit;
font-weight: inherit;
}
audio,
video {
display: block;
}
img {
display: block;
border: none;
/*max-width: 100%;*/
}
iframe {
border: none;
}
pre,
code,
kbd,
samp {
font-family: monospace, monospace;
font-size: inherit;
}
Если вам нужны отступы для пользовательского контента (а они нужны), должен быть свой класс обертка и свой стайлгайд.
Пример:
.description {
h1,
h2,
h3,
h4 {
/* style */
}
p {
/* style */
}
/* и т. д. */
}
Текстовый контент тоже нужно уметь правильно верстать выставляя правильные отступы и высоту строки.
Вот статья [4] на эту тему.
О том, каким может быть пользовательский контент:
Полное наследование. Ссылки больше не синие, стронг не болд, ем не италик. Em, strong это семантические элементы, они используются не для оформления. Например для названиях товаров, в карточках. То что они имеют по дефолту стили не значит, что они будут нужны именно в том, месте где используется этот тег.
Цвет и подчеркивание ссылки мешает когда эта ссылка в виде кнопки или в виде большой кнопки с картинкой и текстом.
a {
background-color: transparent;
text-decoration: none;
color: inherit;
}
abbr {
border: none;
text-decoration: none;
}
b,
strong {
font-weight: inherit;
}
i,
em {
font-style: inherit;
}
dfn {
font-style: inherit;
}
mark {
background-color: transparent;
color: inherit;
}
small {
font-size: inherit;
}
sub,
sup {
position: relative;
vertical-align: baseline;
font-size: inherit;
line-height: 0;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
Удаляются полностью стили присвоенные кнопкам и инпутам, что может кому-то показаться спорным.
Бывает, возникают неудобства с кнопками при смене тегов, чаще всего это бывает с ссылки на кнопку и наоборот.
button,
input,
optgroup,
select,
textarea {
padding: 0;
margin: 0;
border: none;
border-radius: 0;
box-shadow: none;
background-color: transparent;
font: inherit; /* По дефолту, шрифтовые свойства, для этих элементов не наследуются */
color: inherit;
letter-spacing: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-align: left;
text-transform: none;
}
button,
[type='button'],
[type='reset'],
[type='submit'] {
cursor: pointer;
-webkit-appearance: none;
}
textarea {
resize: none;
overflow-y: auto;
overflow-x: hidden;
}
button::-moz-focus-inner,
[type='button']::-moz-focus-inner,
[type='reset']::-moz-focus-inner,
[type='submit']::-moz-focus-inner {
border: none;
padding: 0;
}
button:-moz-focusring,
[type='button']:-moz-focusring,
[type='reset']:-moz-focusring,
[type='submit']:-moz-focusring {
outline: none;
}
[type='number']::-webkit-inner-spin-button,
[type='number']::-webkit-outer-spin-button {
height: auto;
}
[type='search']::-webkit-search-decoration {
-webkit-appearance: none;
}
[type='search'] {
outline: none;
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
(Тег button
нельзя использовать как флекс контейнер. На IOSах сломается.)
fieldset {
padding: 0;
margin: 0;
border: none;
}
legend {
display: block;
padding: 0;
white-space: normal;
}
Часто встречал, что эти семантические элементы форм использовались в декоратиыных целях.
Для такого:
Никогда так не делайте, это пример худшей практики. Вот пару примров с нормальной реализацией:
(Тег fieldset
нельзя использовать как флекс контейнер. Не работает просто.)
Отменяем стандартное отображение select'а
select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
select::-ms-expand {
display: none;
}
→ Оформляем select сами: codepen [7]
::-webkit-input-placeholder {
color: inherit;
opacity: 1;
transition: opacity .3s;
}
::-moz-placeholder {
color: inherit;
opacity: 1;
transition: opacity .3s;
}
:-moz-placeholder {
color: inherit;
opacity: 1;
transition: opacity .3s;
}
:-ms-input-placeholder {
color: inherit;
opacity: 1;
transition: opacity .3s;
}
:focus::-webkit-input-placeholder {
opacity: 0;
}
:focus::-moz-placeholder {
opacity: 0;
}
:focus:-moz-placeholder {
opacity: 0;
}
:focus:-ms-input-placeholder {
opacity: 0;
}
Плейсхолдер наслудует цвет. Исчезает при фокусе.
Тег svg
хоть и полноценный тег, который поддерживает любые свойства, я всегда использую для него обертку, которой и задаю размеры и цвет. Такой подход очень удобный для работы с спрайтами 2-х типов.
Расскажу, как мы работаем с иконками:
Иконочный шрифт мы не используем.
У нас есть 2 типа иконок:
— одноцветные
— цветные (иконки и мелкие изображения).
Все они в формате svg.
Для одноцветных используется svg спрайт, котрых хранится отдельно, и кешируется. Выглядит это так:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="search" viewBox="0 0 24 24">
<path></path>
</symbol>
</svg>
И инклюдится на страницу он так:
<svg class="alert__ico">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../img/sprites/sprite.svg#search"></use>
</svg>
И стили для него: (этот код добавляется в файл)
svg {
display: block;
width: 100%;
height: 100%;
fill: currentColor;
}
Для цветных используется css спрайт:
.icon-ico-color:after {
background-image: url("data:image/svg+xml,%3Csvg%20width%3D...;
}
И стили для него:
[class*='icon-']:after {
content: '';
display: block;
width: 100%;
height: 100%;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
Загружается css спрайт асинхронно
<script>
$(document).ready(function() {
$("head").append("<link rel='stylesheet' type='text/css' href='../css/icons.min.css' />");
})
</script>
Генерируется это, понятное дело, галпом.
Что дает такой подход
Для иконки делается контейнер нужного размера и не зависимо от того, будет иконка цветной или нет, она в него отлично впишется.
<div class="elem__ico">
<svg class="alert__ico">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../img/sprites/sprite.svg#search"></use>
</svg>
</div>
<div class="elem__ico icon-ico-color"></div>
[hidden] {
display: none; // IE10
}
Атрибут, который скрывает элемент. Пригодится.
:disabled,
.disabled {
cursor: not-allowed;
}
Правильный курсор. Так как задизейбленной кнопкой может быть ссылка, то псевдокласс уже не сработает, так как ссылка не элемент формы. Для этого добавляйте класс.
Псевдоэлемент в инпуте IE для очистки текста.
::-ms-clear {
display: none;
}
Убираем его.
:-webkit-autofill {
box-shadow: 0 0 100px #fff inset;
-webkit-text-fill-color: currentColor;
}
С помощью внутренней тени закрашиваем этот псевдоэлемент под нужный цвет. И наследует заданный цвет.
::selection {
color: #fff;
background-color: #004fe4;
}
.clearfix:after {
content: '';
display: block;
clear: both;
}
Хоть сейчас во всю используются флексы, не стоит забывать про флоаты, и тем более не стоит забывать про чистку потока для флоатов.
.visually-hidden {
position: absolute;
z-index: -1;
width: 0;
height: 0;
padding: 0;
margin: 0;
border: none;
overflow: hidden;
}
Для семантики: Когда надо спрятать заголовок, который должен быть, но его нет в дизайне. Скрытие этим способом не игнорируется скринридером.
Для кастомизация цекбоксов/радиобаттонов:
Скрывать с помощью display: none;
или атрибута hidden
плохая идея, так как инпут теряет способность получать фокус, а фокус (как мы знаем) это важно.
А если скрывать с помощью класса .visually-hidden
то инпут не теряет способность получать фокус.
В работе с изображениями, а именно с тегом
<img>
есть некоторые сложности:
Метод «padding-bottom» отлично подходит для решения этих проблем. Контроль размеров изображения происходит за счет обертки.
<div class="img-wrap"> <img src="" alt=""> </div>
Но нельзя просто задать высоту обертке или изображению, потому что при ресайте страницы потеряются нужные пропорции.
И чтоб этого не происходило, высота задается за счет padding в % для псевдоэлемента обертки (:before). Как известно padding в % берет значение ширины родителя, не зависимо заданы вертикальные или горизонтальные значения.
(padding в % некоректно отображается в мозиле, если он задан флекс итему).
.img-wrap {
position: relative;
width: 30%;
}
.img-wrap:before {
content: '';
display: block;
padding-bottom: 60%;
}
Само изображение нужно спозиционировать абсолютно относительно обертки. Когда необходимо, чтоб изображение занимало все пространство (на подобии background-size: cover;). Используется класс .cover-pic
.cover-pic,
.contain-pic {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.cover-pic {
object-fit: cover;
}
.contain-pic {
object-fit: contain;
}
Когда необходимо, чтоб изображение занимало не все пространство (на подобии background-size: contain;). Используется класс .contain-pic
В итоге получается:
Из недостатков: Поддержка object-fit
IE. Потому приходится использовать полифил [8].
→ Пример [9]
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.footer-page {
margin-top: auto;
}
Фикс при прижатии футера для IE. В блоке с min-height (которым в данном случае служит body) flex некоректно работает.
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
html {
display: flex;
flex-direction: column;
}
}
Выше показан один из самых оптимальных способов. Прижатие с помощью таблиц [10] и гридов [11] тоже не требует знать высоту футера, но табличный способ как-то не принято (и немного неудобно) использовать, а гриды не очень кросбраузерно.
100vh на IOS будет немного больше экрана и будет скролл, при наличии адресной строки.
→ Codepen [12]
Спасибо, что прочитали мою статью, надеюсь она будет вам полезна. Вопросы и предложения, идеи и замечания приветствуются.
P. S. Советую ознакомиться с публикацией Организация отступов в верстке (margin/padding) [13]. И советую использовать css линтеры. И кому интересно, может решить css задачку [14].
Автор: yurch-html
Источник [15]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/html/289764
Ссылки в тексте:
[1] custom-reset.css: https://yurch-html.github.io/dist/custom-reset.html
[2] здесь: https://habrahabr.ru/company/htmlacademy/blog/339852/
[3] Codepen: https://codepen.io/yurch-html/pen/qyaOZz
[4] статья: http://alistapart.com/article/settingtypeontheweb
[5] Пример 1: https://codepen.io/yurch-html/pen/QBaMyz
[6] пример 2: https://codepen.io/yurch-html/pen/prOMpR
[7] codepen: https://codepen.io/yurch-html/pen/djdMZq
[8] полифил: https://codepen.io/yurch-html/pen/jwoMWE?sort_col=item_updated_at
[9] Пример: https://codepen.io/yurch-html/pen/bxbNYN?editors=1100
[10] таблиц: https://codepen.io/yurch-html/pen/wxVePR
[11] гридов: https://codepen.io/lucyhackwrench/pen/qjpZmr
[12] Codepen: https://codepen.io/yurch-html/pen/LBQbMg
[13] Организация отступов в верстке (margin/padding): https://habr.com/post/340420/
[14] css задачку: https://codepen.io/yurch-html/pen/ZLmyMa
[15] Источник: https://habr.com/post/420539/?utm_campaign=420539
Нажмите здесь для печати.