[Перевод] Советы по CSS, которые вы вряд ли найдете в самоучителях
Существуют определенные правила CSS, которые можно найти в любом учебнике. Но есть также правила CSS, которые вы не найдете в пособиях, но столкнетесь с ними, как только начнете писать код. Я уверен, вы уже разобрались в том, как выровнять элемент по вертикали или создать сложный макет. Мы не будем об этом говорить.
Наконец, есть правила CSS, которые вы вряд ли видели в руководствах, и о которых можно просто не знать. На протяжении некоторого времени я собирал эти советы и сейчас решил написать статью в надежде, что они будут полезны.
Ниже изложено то, чему руководства по CSS меня не научили.
Свойство padding-top относительно ширины родительского элемента
Как часто вы использовали относительные единицы в CSS? Я их большой поклонник, потому что они позволяют создать адаптивный веб-сайт, не слишком углубляясь в медиазапросы. Если вы хотите установить высоту элемента в половину от высоты родителя, то достаточно просто написать height: 50%
.
Вы можете использовать относительные единицы где угодно. Если хотите добавить расстояние между двумя вертикальными элементами, то можете написать margin-top: 15%
и появится внешний отступ. Расстояние будет составлять 15% от исходной высоты. Я думаю, вы все это знаете, и не буду тратить ваше время. Но, возможно, вы не знаете, что все не так просто.
В некоторых ситуациях лучше использовать padding вместо margin. Но когда вы устанавливаете padding-top: 15%
… Что за?…
Свойство не работает так, как мы ожидаем. Оно не устанавливает параметры относительно высоты родителя. Что происходит?
Объяснение
Оно устанавливает параметры относительно родительской высоты. Вам нужна демонстрация? Вот:
Просто поиграйте с изменением родительской ширины и посмотрите, как это повлияет на внутренний отступ дочернего элемента. На первый взгляд это покажется странным, но на самом деле есть веская причина, почему так происходит. Вы найдете ее, прочитав CSS спецификацию…
Нет, я шучу — нет никаких объяснений, почему так происходит. По крайней мере, я нигде не смог найти объяснений. Просто так происходит, имейте это в виду.
Хотя мы и не понимаем, почему разработчики сделали так, но можем использовать эту особенность в наших интересах. Для нашего элемента мы устанавливаем следующее:
.parent {
height: auto;
width: 100px;
}
.child {
padding-top: 100%;
}
Тогда высота элемента будет такой же, как высота дочернего элемента, хотя мы задали height: auto
. С другой стороны, высота дочернего элемента будет такой же, как и ширина родительского элемента, поскольку мы устанавливаем padding-top: 100%
. В результате получается квадрат, и элемент будет поддерживать это соотношение при любых размерах.
Вот рабочий пример:
Если измените padding-top: 100%
на любой другой процент, то получится прямоугольник. Если меняете ширину, то соотношение все равно сохраняется.
Трансформация может накапливать правила
Если вы изучали информатику, то наверняка помните эту ужасную черепаху и ее двигающуюся ручку. Эта образовательная концепция более известна как черепашья графика, цель которой состоит в том, чтобы провести черепаху по пути при помощи простых инструкций — »20 шагов вперед», «поворот на 90 градусов» и тому подобное.
Что, если бы используя CSS, вы могли задать команду перемещение на »20 пикселей вправо» относительно текущего положения элемента, а не его стартовой позиции? А если я скажу, что вы можете это сделать, используя свойство transform
?
Многие разработчики не знают, что свойство transform
может накапливать правила и правило n+1 будет относиться к позиции, достигнутой в n-м правиле, а не к исходной позиции.
Вы растеряны? Возможно, этот пример поможет вам прийти в себя:
Обратите внимание, что мы не использовали никаких переменных JavaScript для сохранения текущей позиции или текущего вращения. Эта информация нигде не хранится! Решение простое, если напишете:
transform: translateX(20px);
А затем добавите следующее правило:
transform: translateX(20px) translateX(40px)
Второе правило не будет заменять первое — они будут применяться последовательно. Тот факт, что они применяются последовательно имеет важное значение. Когда вы поворачиваете элемент, вы изменяете систему отсчета, и дальнейшие правила будут относиться к новой системе отсчета. Таким образом, эта запись:
transform: rotateZ(20deg) translateX(30px)
будет отличаться от такой:
transform: translateX(30px) rotateZ(20deg)
Вы также можете комбинировать разные единицы измерения. Например, вы можете отцентрировать элемент размером в 600 следующим образом:
transform: translateX(50vw) translateX(-300px)
Но если вы не собираетесь его анимировать, то, возможно, calc ()
— лучшая альтернатива.
Если вы волнуетесь по поводу черепахи, то я создал другой фрагмент, который воссоздает динамику:
К сожалению, она пока не рисует. Но, если захотите, всегда можете реализовать функцию рисования.
Внешние и внутренние отступы отсчитываются по часовой стрелке
Это легко и многие подумают, что я пишу банальные вещи, но я видел так много людей, борющихся с четверками, что перестал считать это само собой разумеющимся.
Многие разработчики не знают, что почти каждое свойство CSS имеет сокращенную альтернативу. Другие разработчики знают это, но продолжают использовать полные версии, потому что никогда не помнят порядок.
Позвольте дать вам подсказку:
Отступы и границы следуют по часовой стрелке
Объясню проще. Вы с уверенностью можете использовать:
padding-top: 3px;
padding-left: 6px;
padding-right: 6px;
padding-bottom: 3px;
Но точно так же вы можете использовать более короткую альтернативу:
padding: 3px 6px 3px 6px;
Порядок запомнить легко — просто посмотрите на эти часы:
Начинайте с 12:00 и продолжайте движение по часовой стрелке. Вы получите правильный порядок.
Если вместо этого вы используете только два значения:
padding: 2px 4px;
Браузер расширит его, повторив параметры:
padding: 2px 4px 2px 4px;
Если вы используете три значения:
padding: 2px 4px 6px;
Браузер будет использовать среднее значение как для левого, так и для правого края, как если бы вы написали:
padding: 2px 4px 6px 4px;
Фон поддерживает несколько изображений
Это одно из наименее известных свойств, хотя оно широко поддерживается.
Вы знаете, что можно указать URL-адрес изображения внутри свойства background
, но, если необходимо, можете вставить столько изображений, сколько хотите. Все, что вам нужно сделать, это разделить их запятой:
background: url('first-image.jpeg') top left,
url('second-image.jpeg') bottom right;
Почему это может быть полезно? Что вы думаете о Линусе Торвальдсе на фоне сгенерированного при помощи CSS восхода солнца?
Вы также можете сделать квадратным прямоугольное изображение, добавляя те затененные границы, которые так популярны в Instagram. Для этого я повторил одно и то же изображение дважды, увеличив фоновое изображение в 5 раз:
Обнаружение сенсорных устройств
Благодаря медиа-запросам мы можем сделать сайты гибкими, а макеты адаптировать к экранам различных размеров. Но этого недостаточно!
Смартфоны, планшеты и классические персональные компьютеры отличаются по своей природе. Дело не в размере экрана.
На устройстве с сенсорным экраном вы используете экранные жесты, а такие инструменты, как HammerJS помогают в этом. С помощью мыши вы только кликаете, но с большей точностью. Если вы адаптировали свой сайт к экранам разных размеров, возможно, вы задумываетесь над его гибкостью в других направлениях и поддержкой различных типов ввода!
Вам не нужен сложный JavaScript-код для определения user-agent. Все необходимое есть в CSS:
@media (any-pointer: fine) {
/*
These rules will be applied to not-touchscreen devices
*/
}
@media (any-pointer: coarse) {
/*
These rules will be applied to touchscreen devices only
*/
}
Вот пример:
Подсказка: Для проверки вам не нужен смартфон, можете имитировать сенсорное устройство с помощью инструментов Google Chrome, просто щелкнув этот значок:
Он очень полезен, и я не знаю, почему он не распространен, хотя и прилично поддерживается. Например, я использовал его в карусели, чтобы скрыть иконки-шевроны на устройствах с сенсорным экраном для более естественного вида.
В конце концов, вы можете предусмотреть файл touchscreen.css
и при необходимости его импортировать:
@import url('touchscreen.css') screen and (any-pointer: coarse);
Примечание: в настоящее время не поддерживается Firefox, как вы можете видеть на caniuse.com.
Отступы схлопываются
«И следите за лестницами. Они любят меняться» (Перси Уизли Гарри Поттеру)
Мне нравится CSS — это чистый, точный и элегантный язык, в нем есть все, что нужно разработчикам.
Вы применяете правило, и оно работает. Но когда я думал, что знаю все о CSS, произошло вот это:
Что, черт возьми, происходит? Вероятно, вы ждете, что текст будет внутри поля заголовка, но заголовок оказался внизу. Я не хотел подобного расклада. Позже я обнаружил, что с отступами происходит путаница.
Что это значит? Предположим, мы хотим создать такой макет:
Мы создали разметку для трех элементов и установили разную высоту верхней границы для каждого из них. Вроде бы все должно работать? Нет.
Если вы так сделаете, браузер заметит три смежных поля и захочет объединить их в один большой блок.
Результат будет выглядеть так:
Что случилось? Я не знаю. Это историческая особенность CSS. Я думаю, что когда CSS стандартизировался, поля вообще не являлись проблемой, а макеты не были такими сложными, как сейчас. Поэтому разработчики решили, что это полезная функция. Но сейчас она не имеет смысла.
Если вы работали с CSS много лет и никогда не встречались с этой проблемой, то это потому, что отступы объединяются только когда:
- поля вертикальны (с горизонтальными подобного не происходит);
- внешние элементы не содержат текст или другой контент;
- не установлены внутренние отступы или границы;
- свойство display определено как «block»;
- свойство overflow отличается от «initial»;
- отступы не являются отрицательными.
И список можно продолжить. Если вы столкнулись с этой проблемой, то можете просто исключить одно из этих условий (кроме первого), и отступы придут в норму. Вы также можете избегать использования margin-top
, а вместо этого использовать top
и padding-top
.
Обратите внимание, что это может случиться и для элементов одного уровня. Если у вас есть два родственных элемента один над другим и вы устанавливаете margin-bottom: 30px
для первого и margin-top: 60px
для второго, то с наименьшим будут проблемы. Отступы в результате не будут равны 30 + 60 = 90 пикселей, а будут равны наибольшему значению (30, 60) = 60 пикселей.
Финальные размышления
На этом все! Надеюсь, я не зря тратил время на статью и она оказалась полезной для вас.
Заглядывайте на VPS.today — сайт для поиска виртуальных серверов. 1500 тарифов от 130 хостеров, удобный интерфейс и большое число критериев для поиска самого лучшего виртуального сервера.