- Фоны и рамки;
- Фигуры;
- Визуальные эффекты.
Фоны и рамки
В первой теме «Фоны и рамки» я расскажу, что такое currentColor в CSS3, как cделать прозрачные рамки, несколько рамок, что такое гибкое позиционирование фона. Во второй теме «Фигуры» приведу методы создания различных видов прямоугольников с помощью css. В визуальных эффектах рассмотрю примеры наложения различных цветовых тонов. А в теме «Взаимодействие с пользователем» покажу, как сделать интерактивное сравнение изображений.
Как вы думаете, какого цвета будет border у блока с текстом «Hello world»?
Такого же синего? Да, правильно. А почему?
Цвет будет такой же, #38A потому что в CSS есть такая прекрасная переменная, как currentCollor, которая берет свое значение цвета из свойства color. И если мы не передадим цвет в border, outline, text-shadow, box-shadow, то по умолчанию получим такой же цвет, что и в свойстве color.
На рисунке ниже можно увидеть, что currentColor можно передавать, как явным образом, так и не передавать вовсе.
Переменная currentColor предоставляет нам очень удобный код и соответствует принципам DRY (don’t repeat yourself — не повторяйся). И как показано на следующем рисунке, изменяя только свойство color, для блока с кодом, который был представлен выше, мы получаем разное отображение элемента.
Полупрозрачные рамки
Если бы меня кто-нибудь спросил раньше, как сделать полупрозрачные рамки, то я бы ответил: «Легко! Я бы сделал два блока дива: родительский и дочерний. И уже в родительском задал бы некоторый padding: 10px и background-color: rgba(255, 255, 255, 0.5) (полупрозрачный), который был бы цветом моей прозрачной границы». Но это можно сделать гораздо проще.
Что если мы просто передадим полупрозрачный border для нашей рамки? Мы ничего хорошего не получим. Почему? В CSS есть такое свойство, как background-clip, и многие забывают о его существовании. Background-clip отвечает за распространения фона и имеет три значения: border-box (по умолчанию), content-box и padding-box.
По умолчанию оно у нас border-box, что значит, что наш фон будет заходить под нашу рамку, и мы не увидим ту самую прозрачность, которую передали в border, так как у нас наш фон будет под нашей границей. Также в background-clip можно передавать content-box, что будет значить, что наш фон распространяется под нашим контентом. Но тут передаем padding-box и получаем вот такую прозрачную рамку.
Несколько рамок
Несколько рамок мы можем создать двумя способами, один используя border и outline. Border и Outline хороши, но с помощью их мы можем сделать только две рамки.
А что если нам потребуется куда больше рамок, к примеру 3, 4 или более, то тут нам на помощь приходят тени.
Все из нас сталкивались со свойством box-shadow. Многие знают, что если передать нулевое вертикальное смещение (v-offset), нулевое горизонтальное смещение (h-offset), нулевое размытие (blur) и четвертый параметр, называемый радиусом распространения (spread radius), который делает тень больше, то получится что-то похожее на рамку. И так можно создать сколько угодно рамок, разделяя их запятой.
Гибкое позиционирование фона
Следующая тема – это гибкое позиционирование фона. Многие из нас сталкивались с такой проблемой, как расположить картинку на нашем фоне. Расположить ее можно с помощью background-position. Хочу отметить, что такие ключевые слова, как right, top, bottom, left в CSS были обновлены. Теперь, когда мы пишем right 10 px и bottom 20 px для нашей картинки, то это будет значить, что сделай нам отступ справа 10 px, а снизу 20 px.
Точно также, если написать background-position: right 10 px top 20 px, то получим отступ справа 10 px, сверху 20 px.
С помощью гибкого позиционирования можно располагать несколько картинок в нашем фоне. Мы им всем говорим no-repeat и с помощью ключевых слов раскидываем по разным углам. Вот так круто получается. отлично все поддерживается, пользуйтесь.
Фон в полоску
Поговорим о создании фона. Обычно для создания какого-либо неоднотонного фона мы прибегаем к использованию различных картинок, которые сделаны с помощью визуальных редакторов. Или нам дизайнер нарисовал картинку, мы ее вставили, и у нас все красиво отображается.
Но простой фон в полоску можно сделать с помощью одного лишь CSS.
Все мы знаем, как выглядит стандартный градиент.
А что если мы этому градиенту зададим границы распространения?
То по краям мы увидим сплошной цвет.
А что если мы сведем градиент к одной точке?
Мы увидим просто две полоски. Вот эти две полосы будут основой нашего фона в полоску. Далее задаем background-size: 30px. Одна полоса будет 15 px и вторая тоже 15 px, так как градиент разделен 50/50. И получаем вот такой вот фон в полоску.
Для того чтобы сделать одну полосу больше, другую меньше, мы для желтого цвета задаем 30%, а для синего — 0. Что значит вот этот ноль? 30% у нас, понятное дело, будет занимать желтый цвет. А вот что значит вот этот 0, кто-нибудь может сказать? По сути, это просто оставшееся расстояние нашего background-size. То есть 30% из 30px – это примерно 9px у нас заполнится желтым, а вся остальная часть синим.
Для того чтобы нарисовать несколько цветов в нашем фоне, мы сталкиваемся с такой ситуацией, как промежуточное повторение цветов. То есть я говорю нашему желтому цвету: заполни мне 33% нашего фона желтым цветом, а ставшуюся часть заполни синим. Потом синему цвету говорю: нет, до 66% заполни, и все остальное заполни желто-зеленым, и получаем 3 цвета в нашем фоне.
Для того чтобы сделать вертикальные полосы — все то же самое, только у нас меняется background-size и в linear-gradient появляется ключевое слов to right. Также вместо ключевого слова мы можем вставить 90° и все отобразится, как надо.
Если мы совместим горизонтальные и вертикальные полосы вместе, то получим вот такой вот фон в решетку.
У нас есть квадратный background-size, мы передаем через запятую в background-image наши градиенты и получаем фон в решетку.
С фоном в диагональную полосу немного посложнее. Здесь мы уже не пользуемся обычным linear-gradient-ом, мы здесь пользуемся repeating-linear-gradient. Обратите внимание, что наш фон распространяется до 30 px, и background-size у нас квадратный 42px на 42px. Почему же все-таки 42?
А что, если мы передадим что-нибудь другое? К примеру 30px вместо 42px.
Почему же все-таки 42px. На помощь приходит обычная школьная математика.
Мы знаем, что наш фон – квадрат, а квадрат состоит из двух равнобедренных треугольников. Дальше мы делаем некоторые математические преобразования, но при этом помним, что наш фон распространяется до 30px.
Подставляем в нашу формулу 30 и получаем примерно 42. Округляем в меньшую степень. Получаем вот такой фон, диагональные полосы.
lea.verou.me/css3patterns
У автора книги «CSS секреты» Леа Веру, сотрудника всемирного веб-консорциума w3с, есть целая подборка фонов, которые она реализует с помощью градиентов.
Примеры, которые реализует Леа Веру.
Примеры, реализованные Беннеттом Фили.
Фигуры
И начну я эту тему с параллелограммов.
Все из нас знают, как выглядят параллелограммы. Параллелограмм – это, прежде всего, нестандартный прямоугольник, у которого углы должны быть не всегда прямые. Для того чтобы сделать скошенные углы, можно обойтись псевдоклассом before. Задаем относительное позиционирование (position: relative) классу button, а абсолютно позиционируем псевдокласс before. Задаем псевдоклассу background, делаем трансформацию с помощью skewX и получаем вот такие скошенные углы.
Для того чтобы сделать трапецию — все то же самое, аналогично. Только здесь мы передаем перспективу и rotateX. И получаем вот такую трапецию.
Изображение в форме ромба можно сделать различными способами. Один из них также с помощью трансформации. То есть у нас есть родительский div, и в него вложено изображение.
Поворачиваем родительский div на 45 градусов, и уже получаем ромб, но изображение у нас наклонилось тоже. Мы хотим его вернуть к нормальному виду и разворачиваем наше изображение обратно на -45 градусов. В итоге получается шестиугольник. Почему? А потому что у нас здесь два прямоугольника, и они срезают углы. Для того чтобы у нас получился именно ромб, мы просто задаем scale(1.42), увеличиваем наше изображение и получаем вот такой ромб.
Изображение в форме ромба можно сделать также с помощью clip-path. Туда мы можем передавать различные имена такие, как circle, polygon и другие. Здесь я пользуюсь полигоном. Я передаю в polygon середину каждой стороны квадрата, а при hover-e возвращаю точки к углам квадрата и получаю вот такую вот анимацию. Это очень хорошее свойство.
<source lang="css"><img src="tiger.jpg" alt=" " />
<img src="tiger2.jpg" alt=" "/>
img {
max-width: 250px;
margin: 20px;
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
transition: all 1s;
}
img:hover {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
Оно поддерживает анимацию, но к сожалению, очень плохо поддерживается браузерами. Его поддерживают только Chrome и Firefox.
Как сделать срезанные углы? Вспомним тему про фон в полоску. Здесь точно также с градиентами. Мы, по сути, разделяем наш фон на 4 части. У нас есть 4 градиента, которые мы раскидываем с помощью гибкого позиционирования по разным углам и закрашиваем их от прозрачного цвета до синего. И получаем срезанные углы.
Для того чтобы сделать срезанные углы во внутрь, здесь используется radial-gradient. Единственное, что у нас появляется, это такие ключевые слова, как circle at top left, чтобы расположить кружочки в различных углах. Опять же 4 части расставляем, с помощью ключевых слов, по местам и получаем такие углы.
Как сделать простые секторные диаграммы с помощью одно лишь CSS. Обычно, чтобы создать секторные диаграммы, мы пользуемся каким-либо фреймворком, например, d3.js. Но простую секторную диаграмму можно сделать на CSS.
У нас есть блок, мы из него делаем круг.
Половину круга закрашиваем коричневым цветом.
Дальше делаем псевдокласс, который закрашиваем в тот же зеленый цвет, который уже есть в блоке.
По сути, просто двигая этот псевдокласс, уже получается некоторый вид секторной диаграммы, но только до половины, так как другая часть у нас зеленая.
Опишу такой интересный подход, если передавать в наш блок отрицательный animation-delay и при этом animation-play-state оставить в состоянии paused, то можно заметить, что изменяется состояние нашего элемента. И если у нас анимация проигрывается до 4s (4 секунд), и мы напишем в стилях -2s, то получим на половину проигравшее состояние, и наш круг будет на половину закрашен.
Визуальные эффекты
Наложения цвета можно сделать различными способами, я приведу два примера: первый из них наложения цвета с помощью фильтров. С помощью фильтров мы можем наложить множество оттенков, но добиться какого-либо конкретного будет проблемой для многих. И тут на помощь приходит такое свойство, как background-blend-mode.
И перейдем к гораздо более адаптивному способу: это background-blend-mode.
Более адаптивный он, потому что он может не просто накладывать желаемые цвета, но и смешивать, и это свойство прекрасно анимируется. Плюс, с помощью его мы можем сделать различные цветовые эффекты.
.tinted-image {
...
backgroung-color: hsl(335, 100%, 50%);
background-blend-mode: luminosity;
transition: .5s background-color;
}
.tinted-image {
...
backgroung-color:yellow;
background-blend-mode: difference;
transition: .5s background-color;
}
.tinted-image:hover {
background-color: transparent;
}
Но, к сожалению, у это свойства не всё хорошо с поддержкой. И пользоваться им или нет, решать вам.
Следующий пример — плавная анимация состояния. Почему он так называется, давайте посмотрим.
У нас есть панорама, и мы хотим добавить немного анимации.
Помещаем изображение на фоне и после анимируем background-position, и получаем анимацию.
.panoramic {
width: 300px, height: 300px;
background: url('b.jpg');
background-size: auto 100%;
border-radius: 50%;
animation: panoramic 10s linear infinite alternate;
animation-play-state: paused;
}
.panoramic:hover, .panoramic:focus {
animation-play-state:running;
}
@keyframes panoramic {
to {background-position: 100% 0;}
}
Обратите внимание именно на верстку, на HTML. У нас есть контейнер, image-slider, и у него есть одно изображение, которое вложено в div, а другое не вложено. Для родительского контейнера мы задаем position: relative, а для вложенного в div изображения, с ним и будем работать, мы задаем position: absolute и ширину 50%. Самое главное — мы ему делаем resize: horizontal.
С помощью этого resize у нас будет интерактивное сравнение. Так как у меня очень хорошее разрешение, мы не видим такого бага, который возникает из-за resize: horizontal. У нас появляется ползунок, который подобен resize-ползунку HTML-элемента textarea. Для того чтобы его убрать, мы просто закрашиваем его псевдоклассом и завязываем на нем cursor: ew-resize.
Хочу отметить, что в основу статьи вошла книга Css Secrets. Better Solutions to Everyday Web Design Problems. Хоть она уже и давно вышла, я настоятельно рекомендую прочитать эту книгу. Из этой книги вы узнаете гораздо больше, чем я здесь представил и по-настоящему попробую многие секреты CSS вживую.
Ссылка на репозиторий с примерами и презентацией
Комментарии (23)
extempl
17.01.2018 19:24+1Шерить код картинками да ещё и разными размерами — так себе решение. Особенно для туториала, где возможность скопировать код — маст хев.
А так — довольно полезно для тех, кто не следит за Lea Verou.
Хотя не знал про относительное позиционирование (right 10px) и про применения background-clip для решения прозрачных рамок, хотя решение конечно лежит на поверхности.SelenIT3
17.01.2018 20:30+1У background-clip вообще немало полезных применений. Причем вполне документированных!:)
kartvladek
18.01.2018 14:45кстати да — для себя именно это и отметил. всё остальное известно именно от Lea Verou
Amareis
17.01.2018 20:35Маленький трюк. Небольшую треугольную стрелочку можно нарисовать с помощью div'а нулевых размеров, у которого установлен border: %n%px solid transparent; (где %n% — размер стрелки) и затем красим только одну границу в нужный цвет: border-left-color: green; получится зелёная стрелка, которая показывает вправо (!). Хорошо работает в комбинации с :after и :before псеводэлементами.
https://jsfiddle.net/zvwpv3eb/2 тут можно потыкать и понять почему и как это.
tehnolog
17.01.2018 20:50Параллелограмм – это, прежде всего, нестандартный прямоугольник, у которого углы должны быть не всегда прямые.
Это мощное утверждение, опровергать я его, конечно, не буду. ))bb0ff
19.01.2018 06:36Там ещё из пересечения двух квадратов шестиугольник получается, тоже миленько ;)
Но главное тут — ссылка на книжку, за это спасибо.
daemonhk
18.01.2018 07:54Анимация зелено-коричневого круга глючит в Хроме — в самый последний момент анимации моргает, возвращается градусов эдак на 10 назад и повторяет анимацию.
А так узнал много нового, спасибо большое) Вот только встает вопрос о поддержке браузерами некоторых «грязных» трюков, вроде currentColor, да и вообще, насколько это «правильно» с позиции стандартов CSS и разработки?extempl
18.01.2018 08:40"грязный" трюк вроде currentColor поддерживается всеми браузерами практически с момента их выпуска в мир и является очень базовым механизмом никак не относящимся ни к трюкам, ни, тем более, к грязным из них.
Ну ладно, IE8 и ниже его не поддерживают, но это укладывается в "практически всеми".
rrrrex
18.01.2018 10:09Есть еще сайт, на котором выкладывают анимации с ограниченным размером кода. Конечно функций там не так много используется, но разнообразие полученного результата поражает.
www.dwitter.net
mdss
18.01.2018 11:00все примеры из книги есть на сайте play.csssecrets.io
А в статье надергали несколько глав из самой книги.
jamepock
18.01.2018 12:32Параллелограмм – это, прежде всего, нестандартный прямоугольник, у которого углы должны быть не всегда прямые.
Параллелограмм — четырёхугольник, у которого противоположные стороны параллельны, частным случаем которого является прямоугольник. Вроде как и понятно что имелось ввиду, но если честно такие определения вызывают дикое жжение и портят впечатления от статьи.
justboris
18.01.2018 12:33Недокументированные приемы CSS
Очень даже документированные. Все происходит как и описано в спецификации.
Малоизвестные — да, но никак не «недокументированные»
batmandarkside
18.01.2018 20:59Хорошо зашло! Спасибо
В комментах пуканы горят, как будто личное оскорбление в названии статьи
YuryKa
CSS мощная штука. И статья интересная.
Kwisatz
Если бы еще все это еще не превращалось в ад когда нужно добицо кроссброузерности, цены бы ему не было.
Ну и действительно важные вещи не развиваются десятилетиями. 2018 год а для печати из броузеров до сих пор применяются костыли. Просто пример: попробуйте в хроме поставить разрыв страницы между строками таблицы 8)