CSS Protips
Это современные решения типичных проблем, коллекция советов, которая поможет вам улучшить ваши профессиональные навыки CSS.От переводчика
Приветствую, для вас подготовлен еще один перевод заметок на тему CSS. Мэтт Смит, разработчик из Портленда, поделился CSS-советами и выложил их на GitHub. Мне особенно понравилась его подборка, она структурирована, не особо громоздкая в плане скучных больших текстов и описаний, и в целом будет понятна даже новичку. Я буду рад, если в комментариях мы с вами обсудим каждый пункт и в итоге дадим некоторые заключения. Итак, приступим.Cодержание
- Используем псевдо-класс :not для задания рамки навигации
- Добавляем межстрочный интервал элементу body
- Центрируем по вертикали все что угодно
- Правильно разделяем запятыми элементы списков
- Отрицательный порядковый номер в nth-child
- Используем SVG-логотипы
- Аксиоматический CSS
- Максимальная высота у CSS-слайдера
- Наследуем box-sizing
- Одинаковая ширина ячейки таблицы
- Динамические внешние отступы при помощи flexbox
- Используем селектор атрибутов пустых ссылок
- Стили по умолчанию для обычных ссылок
Используем псевдо-класс :not для задания рамки навигации
Вместо того, чтобы задавать рамку (border) таким образом…
/* добавляем рамку */
.nav li {
border-right: 1px solid #666;
}
… да еще и обнулять border последнему элементу…
/* удаляем рамку */
.nav li:last-child {
border-right: none;
}
… можно было просто использовать псевдо-класс :not(), который поможет нам выбрать только нужные элементы:
.nav li:not(:last-child) {
border-right: 1px solid #666;
}
Конечно, вы могли использовать такую выборку .nav li + li или даже .nav li:first-child ~ li, однако, если мы намеренно используем :not(), нам ясно, что CSS определяет границу всем элементам, кроме последнего, и теперь любому человеку будет понятно, что здесь происходит. Этот способ поддерживается в IE9+ и остальных.
Добавляем межстрочный интервал элементу body
Вам не следует добавлять высоту строки для каждого параграфа или заголовка (<р>, <h*>), соответственно, определяя каждый элемент. Вместо этого, добавьте этот код в тело элемента body:
body {
line-height: 1;
}
Вот таким вот образом, любые текстовые элементы наследуют это свойство от главного родительского элемента body.
Центрируем по вертикали все что угодно
Нет, это не черная магия, вы действительно можете центрировать любой элемент по вертикали:
html, body {
height: 100%;
margin: 0;
}
body {
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-flex;
display: flex;
}
Хотите центрировать как-то еще? Вертикально, горизонтально… как-нибудь, где-нибудь? На CSS-Tricks вы можете ознакомиться со статьей и тогда вы сможете делать все, что угодно. Пример имеет поддержку в IE11+ и остальных.
Примечание: Следите за багами (ошибки) flexbox в IE11 и контролируйте процесс html-верстки.
Правильно разделяем запятыми элементы списков
Мы можем сделать наши элементы li так, чтобы они действительно выглядели как реальный список, записи которого разделены запятыми:
ul > li:not(:last-child)::after {
content: ",";
}
Используя псевдо-класс :not(), мы добавляем после каждого элемента ul-списка запятую, кроме последнего.
Отрицательный порядковый номер в nth-child
Используем отрицательные аргументы в nth-child для выбора элементов с 1 по n.
li {
display: none;
}
/* выбираем элементы с 1 по 3 и отображаем их */
li:nth-child(-n+3) {
display: block;
}
Или, теперь, когда мы знаем все об использовании псевдо-класса :not(), можем попробовать так:
/* скрываем все элемента ul-списка, кроме элементов с 1 по 3 */
li:not(:nth-child(-n+3)) {
display: none;
}
Ну, что, было довольно легко.
Используем SVG-логотипы
Нет, никаких причин не использовать SVG:
.logo {
background: url("logo.svg");
}
SVG хорошо масштабируется под любое разрешение и поддерживается во всех браузерах, IE9+.Теперь мы можем использовать svg, вместо .png, .jpg, or .gif-файлов.
Примечание: Если у вас есть SVG-иконка только для какой-либо кнопки и, в случае, если SVG не был загружен, вы можете использовать доступную текстовую подсказку:
.no-svg .icon-only::after {
content: attr(aria-label);
}
Аксиоматический CSS
Лоботомированная сова (аксиоматический СSS), да, это довольно странное название, однако с помощью универсального селектора (*) и одноуровневого селектора (+) можно получить мощные возможности CSS:
* + * {
margin-top: 1.5em;
}
В этом примере, все элементы в потоке, которые расположены после другого элемента, должны получить верхний отступ равный 1.5em.Более подробную информацию о "лоботомированной сове" можете прочитать в статье Хейдона Пикеринга, или перевод на русском.
Максимальная высота у CSS-слайдера
Реализовать CSS-слайдер можно с помощью «max-height» и «overflow:hidden»:
.slider ul {
max-height: 0;
overflow: hidden;
}
.slider:hover ul {
max-height: 1000px;
transition: .3s ease; /* анимация для max-height */
}
Наследуем box-sizing
Пусть box-sizing наследуется от html:
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
Теперь нам проще контролировать box-sizing в плагинах или компонентах, которые используют свои правила поведения. Поддержка в IE8+ и остальных.
Одинаковая ширина ячейки таблицы
Иногда, таблицы могут причинять боль в работе, поэтому попробуйте использовать table-layout: fixed, чтобы задействовать ячейки одинаковыми по ширине:
.calendar {
table-layout: fixed;
}
Мы избавляемся от боли с помощью table-layout. Поддержка в IE8+ и остальных.
Динамические внешние отступы при помощи flexbox
При работе с колоночным макетом, вы можете избавиться от использования css-селекторов nth-*, first-*, и last-child при помощи flexbox значения space-between:
.list {
display: flex;
justify-content: space-between;
}
.list .person {
flex-basis: 23%; /* базовый размер отдельно взятого блока */
}
Поддержка в IE11+ и остальных.
Используем селектор атрибутов пустых ссылок
Отображаем ссылки, когда a-элемент не имеет текстового значения, но при этом атрибут href содержит ссылку:
a[href^="http"]:empty::before {
content: attr(href);
}
Это довольно удобно. Поддержка в IE9+ и остальных.
Стили по умолчанию для обычных ссылок
Добавляем по умолчанию стиль ссылкам:
a[href]:not([class]) {
color: #008000;
text-decoration: underline;
}
Теперь ссылки, вставленные через визуальный редактор вашей CMS, которые обычно не имеют класса, будут отличаться от остальных ссылок, не затрагивая каскад.
Комментарии (28)
dom1n1k
19.01.2016 04:42+5Вам не следует добавлять высоту строки для каждого параграфа или заголовка
Cледует.
Как минимум половину пунктов я бы из «дельных советов» перенес в категорию «сомнительные трюки». Почти у всех есть побочные эффекты, делающие их, скажем так мягко, неуниверсальными.
В принципе, заметки любопытные и для углубленного понимания технологии полезные. Но в продакшн я бы отсюда мало что потащил.
linoleum
19.01.2016 06:22+4Лоботомированная сова… в продакшне так лучше не делать. Я уже вижу как другой разработчик тратит полчаса на «а откуда тут этот отступ». А когда найдет сову, то сам пойдёт делать лоботомию, угадайте кому.
mayorovp
19.01.2016 09:10+3Причина любого отступа находится инструментами разработчика в хроме за минуту. Нужно всего лишь сначала найти какой элемент имеет этот отступ, а потом заглянуть на вкладку Computed и посмотреть кто именно этот отступ элементу выставил.
Проблема в другом. Найдя сову за минуту, другой разработчик будет вынужден либо костылить отменяющий стиль, либо три дня искать по всему проекту случаи ее использования.
Я бы не рискнул использовать подобные трюки без контекста (.enable-owl * > *)
Dolios
19.01.2016 11:31+1Надо, наверное, тоже начать куски букваря по css перепечатывать. Стану популярным автором :-)
splincodewd все что есть в вашем посте, есть в любом учебнике по css. За исключением, разве что, трюка с «совой», который, впрочем, весьма дурно пахнет, имхо. Только у вас, в отличие от учебника, все разрозненно и бессистемно.
Ваша статья даже вредна, я бы сказал. Вместо того, чтобы, например, прочитать главу про flexbox и разобраться с ним, новичок начитается вот таких статей, в которых ничего не объясняется и предлагается поверить в магию «хаков», и будет потом иметь проблемы.
Желающим разобраться, советую какую-нибудь хорошую книгу почитать. Например, эту:
www.allitebooks.com/css-the-missing-manual-4th-edition
RUQ
19.01.2016 12:02+1А вот я не понимаю. Flexbox, все круто, и пример про «Динамические внешние отступы при помощи flexbox», то есть вроде бы мечта сбылась. Просто говоришь ширину блока, и space-between, а оно уже само там.
Но, что если у меня 6 блоков и на каком-то разрешении помещается в ряд 4. Что будет с оставшимися 2? А я вам скажу, они будут просто по краям. Как так...flexbox ведь?
Я встречал какие-то странные хаки, дескать надо подставить несколько фальшивых (пустых блоков) до недостающего и тогда все будет ок, но это чушь. Другими словами, пока без inline-block никуда)Ganster41
19.01.2016 13:15Media queries и flex-wrap вам в этом случае помогут.
RUQ
19.01.2016 13:33+1В том-то и дело, что я ожидал от flexbox, решения простой задачи равномерного распределения ячеек в зависимости от ширины. А вместо этого мне предлагают завязываться на физические величины (media-queries). Flex-wrap — тут не при чём.
На мой взгляд оптимальным решением было-бы, например специальное свойство для последней строки, наверное.SelenIT2
19.01.2016 14:35+2Нужно что-то типа такого? С инлайн-блоками при justify там тоже без пары-тройки хаков трудно. Флексбоксы для такой задачи, увы, бессильны, потому что они одномерные — строки там никак не влияют друг на друга. Тривиально это будет решаться только в грид-раскладке (уже решается в Хроме за флагом и в ночных Фоксах без него, массового применения ждем к началу-середине весны).
AlexKeller
19.01.2016 18:39Может, я не совсем корректно вас понял насчет последней строки, но простейший флекс позволяет сделать так:
vintage
19.01.2016 20:12Не понял, а что ещё вы ожидали от space-between? Вам точно он нужен, а не какой-нибудь margin-right: calc( 10% + 10px )?
RUQ
20.01.2016 10:07Не от space-between, и даже не от space-around. А ожидал от flexbox решения простой задачи распределения карточек с фиксированной шириной и например фиксироваными отступами по центру контейнера + каждая карточка должна быть одинакова по высоте (по контенту самой большой карточки).
Ваше предложение, её кстати тоже не решает, так как карточки будут выровнены по левому краю контейнера. Посмотрите как это решается например в twitter bootstrap — отрицательные маргины у контейнера.
Возможно как вариант взять от flexbox stretch по поперечной оси, а всё остальное от сетки из inline-block'ов.vintage
20.01.2016 12:29margin: 0 calc( 10% + 10px )?
Нарисуйте картинку лучше.RUQ
20.01.2016 13:21Я же говорю в вашем случае блоки будут по левому краю. Лучшая картинка, хм ну например так:
.container .child .child
.conatainer text-align: center margin: 0 -15px; .child display: inline-block width: 300px margin: 0 15px;
Как-то так, таким образом дочерние элементы всегда будут по центру и равно-удалённы от друг друга, в отличие от вашего предложения когда они выровнены по левому краю .container.
P.S. Чувствую себя занудой.
RUQ
20.01.2016 13:26Короче я дозанудничал, если вы имеете ввиду margin: 0 calc( 10% + 10px ) для блоков внутри flex-контейнера, без всяких там space-between, то таки да, скорее всего это оно.
locky_yotun
19.01.2016 12:42+1Вот так можно выровнять по вертикали что угодно без использования flexbox, абсолютного позиционирования и таблиц: jsfiddle.net/locky/ueen3L3k
Vend3tta
19.01.2016 16:20locky_yotun
19.01.2016 16:38Ну понятно, что метод стар как все знают что. Но это не отменяет того, что в среднем по миру по данным caniuse IE8 и IE9, которые ни в каком виде нативно не поддерживают flexbox, дают пока еще 2%. Это уже значительная доля, которую нужно принимать во внимание, если мы не говорим о разработке одностраничного лендинга. Ну а на отдельных ресурсах их доля может быть и выше.
SelenIT2
19.01.2016 18:13Во-первых, не поддерживают нативно, но с прошлого декабря есть полифилл. Во-вторых, если у 2% пользователей страница будет почти как у взрослых, но без вертикального выравнивания — думаю, ни эти 2%, ни кто-либо еще не умрет. В третьих, неизвестно, сколько из этих 2% — боты:)
jmaks13
19.01.2016 17:22+1Прочитав статью вспомнил студента проходившего у меня практику. Я его как то спросил где нужно использовать класс clearfix, на что он ответил, что на всякий случай ставит его везде.
sashabeep
20.01.2016 00:05-2Dead owl описывали на ALA очень много лет назад
Хочу про списки вспомнить, точнее, про то, что должно отмереть. Лично мое имхо — с тех пор, как появилась возможность делать маркированные списки в html никакие дурацкие разделители не нужны, кроме копирования исконно литературного вида (куда это перекочевало из рукописей), когда в начале элемента списка ставится какое-нибудь тире типа "—", а в конце — ";". Делалось это в рукописях только для того, чтобы понять, где закончился один элемент и начался второй, маркеры и отступ списка для этих целей самодостаточны сами по себе.
- Ну это же видно
- невооруженным взглядом
Равно как и то место, где список закончился.
Psychosynthesis
Последнее не сильно отличается от обычного задания по тегу и в общем случае врядли будет сильно полезно.
a { color: #008000; text-decoration: underline; }
Вообще половина примеров — вполне себе элементарные знания, никаких особых хитростей тут нет. Особенно удивляет что кто-то может не знать 2 и 4.
taliban
Вы похоже не поняли последний стиль, он применится только тем ссылкам, которые не имеют класса, а не все подряд.
Psychosynthesis
Я понял, потому и написал «не сильно отличается». Не вижу этому применения при правильно выстроенной иерархии стилей в интерфейсе.