Junior web-разработчик
26,4
рейтинг
19 января в 01:59

Разработка → Несколько дельных советов по CSS

CSS*

CSS Protips

Это современные решения типичных проблем, коллекция советов, которая поможет вам улучшить ваши профессиональные навыки CSS.

От переводчика

Приветствую, для вас подготовлен еще один перевод заметок на тему CSS. Мэтт Смит, разработчик из Портленда, поделился CSS-советами и выложил их на GitHub. Мне особенно понравилась его подборка, она структурирована, не особо громоздкая в плане скучных больших текстов и описаний, и в целом будет понятна даже новичку. Я буду рад, если в комментариях мы с вами обсудим каждый пункт и в итоге дадим некоторые заключения. Итак, приступим.



Cодержание


  1. Используем псевдо-класс :not для задания рамки навигации
  2. Добавляем межстрочный интервал элементу body
  3. Центрируем по вертикали все что угодно
  4. Правильно разделяем запятыми элементы списков
  5. Отрицательный порядковый номер в nth-child
  6. Используем SVG-логотипы
  7. Аксиоматический CSS
  8. Максимальная высота у CSS-слайдера
  9. Наследуем box-sizing
  10. Одинаковая ширина ячейки таблицы
  11. Динамические внешние отступы при помощи flexbox
  12. Используем селектор атрибутов пустых ссылок
  13. Стили по умолчанию для обычных ссылок


Используем псевдо-класс :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, которые обычно не имеют класса, будут отличаться от остальных ссылок, не затрагивая каскад.
Максим @splincodewd
карма
45,0
рейтинг 26,4
Junior web-разработчик
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

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

  • +4
    Последнее не сильно отличается от обычного задания по тегу и в общем случае врядли будет сильно полезно.

    a { color: #008000; text-decoration: underline; }

    Вообще половина примеров — вполне себе элементарные знания, никаких особых хитростей тут нет. Особенно удивляет что кто-то может не знать 2 и 4.
    • +1
      Вы похоже не поняли последний стиль, он применится только тем ссылкам, которые не имеют класса, а не все подряд.
      • +1
        Я понял, потому и написал «не сильно отличается». Не вижу этому применения при правильно выстроенной иерархии стилей в интерфейсе.
  • +9
    Это все понятно, так что насчет дельных советов?
  • +5
    Вам не следует добавлять высоту строки для каждого параграфа или заголовка
    Cледует.

    Как минимум половину пунктов я бы из «дельных советов» перенес в категорию «сомнительные трюки». Почти у всех есть побочные эффекты, делающие их, скажем так мягко, неуниверсальными.
    В принципе, заметки любопытные и для углубленного понимания технологии полезные. Но в продакшн я бы отсюда мало что потащил.
  • +4
    Лоботомированная сова… в продакшне так лучше не делать. Я уже вижу как другой разработчик тратит полчаса на «а откуда тут этот отступ». А когда найдет сову, то сам пойдёт делать лоботомию, угадайте кому.
    • +3
      Причина любого отступа находится инструментами разработчика в хроме за минуту. Нужно всего лишь сначала найти какой элемент имеет этот отступ, а потом заглянуть на вкладку Computed и посмотреть кто именно этот отступ элементу выставил.

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

      Я бы не рискнул использовать подобные трюки без контекста (.enable-owl * > *)
  • +1
    Надо, наверное, тоже начать куски букваря по css перепечатывать. Стану популярным автором :-)
    splincodewd все что есть в вашем посте, есть в любом учебнике по css. За исключением, разве что, трюка с «совой», который, впрочем, весьма дурно пахнет, имхо. Только у вас, в отличие от учебника, все разрозненно и бессистемно.

    Ваша статья даже вредна, я бы сказал. Вместо того, чтобы, например, прочитать главу про flexbox и разобраться с ним, новичок начитается вот таких статей, в которых ничего не объясняется и предлагается поверить в магию «хаков», и будет потом иметь проблемы.

    Желающим разобраться, советую какую-нибудь хорошую книгу почитать. Например, эту:
    www.allitebooks.com/css-the-missing-manual-4th-edition
  • +1
    А вот я не понимаю. Flexbox, все круто, и пример про «Динамические внешние отступы при помощи flexbox», то есть вроде бы мечта сбылась. Просто говоришь ширину блока, и space-between, а оно уже само там.

    Но, что если у меня 6 блоков и на каком-то разрешении помещается в ряд 4. Что будет с оставшимися 2? А я вам скажу, они будут просто по краям. Как так...flexbox ведь?

    Я встречал какие-то странные хаки, дескать надо подставить несколько фальшивых (пустых блоков) до недостающего и тогда все будет ок, но это чушь. Другими словами, пока без inline-block никуда)
    • 0
      Media queries и flex-wrap вам в этом случае помогут.
      • +1
        В том-то и дело, что я ожидал от flexbox, решения простой задачи равномерного распределения ячеек в зависимости от ширины. А вместо этого мне предлагают завязываться на физические величины (media-queries). Flex-wrap — тут не при чём.

        На мой взгляд оптимальным решением было-бы, например специальное свойство для последней строки, наверное.
        • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          Может, я не совсем корректно вас понял насчет последней строки, но простейший флекс позволяет сделать так:

          image
    • 0
      Не понял, а что ещё вы ожидали от space-between? Вам точно он нужен, а не какой-нибудь margin-right: calc( 10% + 10px )?
      • 0
        Не от space-between, и даже не от space-around. А ожидал от flexbox решения простой задачи распределения карточек с фиксированной шириной и например фиксироваными отступами по центру контейнера + каждая карточка должна быть одинакова по высоте (по контенту самой большой карточки).

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

        Возможно как вариант взять от flexbox stretch по поперечной оси, а всё остальное от сетки из inline-block'ов.
        • 0
          margin: 0 calc( 10% + 10px )?

          Нарисуйте картинку лучше.
          • 0
            Я же говорю в вашем случае блоки будут по левому краю. Лучшая картинка, хм ну например так:

            .container
                .child
                .child
            
            


            .conatainer
                text-align: center
                margin: 0 -15px;
            
            .child
                display: inline-block
                width: 300px
                margin: 0 15px;
            
            


            Как-то так, таким образом дочерние элементы всегда будут по центру и равно-удалённы от друг друга, в отличие от вашего предложения когда они выровнены по левому краю .container.

            P.S. Чувствую себя занудой.
          • 0
            Короче я дозанудничал, если вы имеете ввиду margin: 0 calc( 10% + 10px ) для блоков внутри flex-контейнера, без всяких там space-between, то таки да, скорее всего это оно.
  • +1
    Вот так можно выровнять по вертикали что угодно без использования flexbox, абсолютного позиционирования и таблиц: jsfiddle.net/locky/ueen3L3k
    • 0
      • 0
        Ну понятно, что метод стар как все знают что. Но это не отменяет того, что в среднем по миру по данным caniuse IE8 и IE9, которые ни в каком виде нативно не поддерживают flexbox, дают пока еще 2%. Это уже значительная доля, которую нужно принимать во внимание, если мы не говорим о разработке одностраничного лендинга. Ну а на отдельных ресурсах их доля может быть и выше.
        • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    По поводу слайдера — не совсем понятно, что имеется ввиду.
    • +1
      Что-то вроде details в HTML5
    • НЛО прилетело и опубликовало эту надпись здесь
  • +1
    Прочитав статью вспомнил студента проходившего у меня практику. Я его как то спросил где нужно использовать класс clearfix, на что он ответил, что на всякий случай ставит его везде.

  • –2
    Dead owl описывали на ALA очень много лет назад

    Хочу про списки вспомнить, точнее, про то, что должно отмереть. Лично мое имхо — с тех пор, как появилась возможность делать маркированные списки в html никакие дурацкие разделители не нужны, кроме копирования исконно литературного вида (куда это перекочевало из рукописей), когда в начале элемента списка ставится какое-нибудь тире типа "—", а в конце — ";". Делалось это в рукописях только для того, чтобы понять, где закончился один элемент и начался второй, маркеры и отступ списка для этих целей самодостаточны сами по себе.

    • Ну это же видно
    • невооруженным взглядом

    Равно как и то место, где список закончился.
    • НЛО прилетело и опубликовало эту надпись здесь

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.