3061
Шлёпаем формы и красим кнопки... Блог про фронтенд — просто, понятно и с юмором. Всех обнял, приподнял, пошел пилить для вас годноту) Связь: @advertos
Тень хедера при скролле
На днях пытался запилить тень, которая появляется под хедером, при прокрутке страницы. Самое интересное из того, что перепробовал — это использование animation-timeline: scroll().
Всё получается очень классно, но есть одно "НО": пока что не работает эта история в Firefox.animation-timeline: scroll() — эта фича позволяет привязать CSS-анимацию к прокрутке страницы.
header {
position: sticky;
top: 0;
background: white;
/* Изначально без тени */
box-shadow: 0 0 0 rgba(0, 0, 0, 0);
/* Привязываем анимацию к скроллу */
animation: shadow-fade both linear;
animation-timeline: scroll(root);
animation-range: 0px 50px;
}
@keyframes shadow-fade {
to {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
}animation-timeline: scroll(root) — анимация управляется прокруткой страницы.animation-range: 0px 50px — анимация происходит в первые 50px скролла.both — анимация работает в обе стороны (при скролле вверх тень исчезает).linear — равномерная скорость изменения.
Простой параллакс на чистом CSS
Разберем, как сделать простейший параллакс эффект, который есть практически на всех модных лендингах)
Основа эффекта:
.parallax-bg {
background-attachment: fixed;
background-size: cover;
background-position: center;
}background-attachment: fixed — ключевой момент. Он "фиксирует" фон относительно окна, а контент прокручивается — создаётся эффект объёма.<section class="section-text">Текст</section>
<section class="parallax-bg bg-1"></section>
<section class="section-text">Еще текст</section>
Эффект инвертирования цветов в CSS
Если нужно, как то заметно выделить элемент или даже блок на странице, к примеру при ховере, то можно попробовать использовать filter: invert(100%).
Делается быстро, эффект заметный)
Просто вешаем на нужный элемент ховер с фильтром:
.card:hover {
filter: invert(100%);
transition: filter 0.4s; /* для плавности */
}
Стилизуем разрывы текста в CSS
Если у вас есть текст с оформлением, который переносится на несколько строк. То с помощью box-decoration-break можно контролировать, как оформление будет отображаться при переносе.
Разберем на примере:
<div class="container">
<h1><span class="clone">Привет, мир!</span></h1>
<h1><span>Привет, мир!</span></h1>
</div>
max-width: 200px).span {
background: linear-gradient(to right, #4f46e5, #ec4899);
color: white;
padding: 12px;
}
.clone {
box-decoration-break: clone;
-webkit-box-decoration-break: clone;
}box-decoration-break: clone и посмотрим разницу:box-decoration-break: slice — оформление ведёт себя как единое целое, паддинги только по бокам всего блока, фон/градиент продолжается между строками.box-decoration-break: clone — каждая строка становится независимым блоком, паддинги со всех сторон у каждой строки, фон/градиент применяется к каждой строке отдельно.
Адаптивная таблица без JS
Таблицы на мобильных — это боль. Помните те времена, когда приходилось скроллить влево-вправо, чтобы увидеть все колонки? Или когда текст был настолько мелким, что нужна была лупа? Сегодня разберем, как можно решить эту проблему)
Наша таблица:
<table>
<thead>
<tr>
<th>Имя</th>
<th>Email</th>
<th>Город</th>
<th>Профессия</th>
</tr>
</thead>
<tbody>
<tr>
<td>Иван Петров</td>
<td>ivan@example.com</td>
<td>Москва</td>
<td>Frontend-разработчик</td>
</tr>
</tbody>
</table>
@media (max-width: 640px) {
/* Делаем все элементы таблицы блочными */
table, thead, tbody, th, td, tr {
display: block;
}
/* Прячем заголовки */
thead {
display: none;
}
/* Каждая строка становится карточкой */
tr {
border: 1px solid #ddd;
margin-bottom: 1rem;
padding: 1rem;
}
/* Ячейки превращаются в пары ключ-значение */
td {
display: flex;
justify-content: space-between;
}
/* Добавляем подписи из data-атрибутов */
td::before {
content: attr(data-label) ":";
font-weight: 600;
}
}
display: block превращает все элементы таблицы в обычные блокиattr(data-label) берет текст из HTML-атрибута и вставляет как подпись
Псевдобрейкпоинты для шрифта без @media
Все мы знаем про fluid typography с clamp() — шрифт плавно меняется в зависимости от ширины окна.
Но если вас напрягает эта плавность и хочется, чтобы размер шрифта не плавал, а менялся чёткими скачками, как при брейкпоинтах, то оказывается, способ есть)
Для этого даже не нужны @media — достаточно одной строчки в CSS и round().
Реализация:
html {
font-size: clamp(
1em,
round(0.8em + 1.5vw, 0.5em),
2.5em
);
}clamp(min, preferred, max) 1em2.5emround().0.8em + 1.5vw0.8em — стартовый размер1.5vw — прибавка, зависящая от ширины окнаround(..., 0.5em)0.5em.
Футер выезжающий из-под контента
Сегодня разберём один из тех визуальных приёмов, который вы 100% видели на модных лендингах — "Sticky Footer Reveal", или по-русски — футер, который выезжает из-под контента при прокрутке)
HTML-разметка:
<div class="container">
<!-- контент -->
</div>
<footer>
<!-- футер -->
</footer>
.container {
position: relative;
z-index: 1;
background: #fff;
}z-index: 1 и position: relative — это делает контейнер "выше" по слоям, чем футер. Поэтому он будет перекрывать футер при прокрутке.footer {
position: sticky;
bottom: 0;
background: #0b0b0b;
z-index: 0;
}position: sticky и bottom: 0, чтобы закрепить на нижней границе страницы, а z-index: 0 — делает его "ниже" контента.
Оживляем форму с помощью :focus-within
Сегодня разберем, как сделать формы немного умнее и приятнее для пользователя)
Поможет нам в этом псевдокласс :focus-within
Допустим, у нас есть поле ввода с префиксом или суффиксом:
<div class="input-group">
<span>https://</span>
<input type="text" placeholder="domain.tld" />
</div>
input, мы хотим, чтобы всё поле реагировало — включая span.:focus-within, который применяется к родителю, если любой из его потомков находится в фокусе:.input-group:focus-within {
border-color: #275efe;
}
.input-group:focus-within span {
background: #678efe;
color: white;
}input — весь контейнер "понимает", что внутри что-то активно, и реагирует)
Или когда решил повайбкодить и нейросеть нагенерила код)
Читать полностью…
Многострочный текст с вертикальным затуханием
Не давно в этом посте, мы разбирали, как делать CSS-эффект затухания для обрезки однострочного текста, давайте теперь посмотрим, как сделать то же самое, но с многострочным текстом.
Разметка:
<div class="text-container">
<div class="multiline">Многострочный текст...</div>
</div>
.multiline {
height: 4lh;
overflow: hidden;
mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
}
CSS-стрелки через border и transform
Нашел интересный видос, как делать стрелки с помощью border и transform, зацените, может быть, кому-нибудь пригодится)
Вот код из видео:
.arrow-right {
display: inline-block;
border: solid #FCA101;
border-width: 0 5px 5px 0;
padding: 5px;
transform: rotate(-45deg);
}
.arrow-up {
display: inline-block;
border: solid #FCA101;
border-width: 0 5px 5px 0;
padding: 5px;
transform: rotate(-135deg);
}
.arrow-left {
display: inline-block;
border: solid #FCA101;
border-width: 0 5px 5px 0;
padding: 5px;
transform: rotate(135deg);
}
.arrow-down {
display: inline-block;
border: solid #FCA101;
border-width: 0 5px 5px 0;
padding: 5px;
transform: rotate(45deg);
}<div class="arrow-right"></div> <!-- стрелка вправо -->
div и задаём ему границы только справа и снизу (border-width: 0 5px 5px 0). transform: rotate() в нужную сторону.
Анимируем градиентный фон
Сегодня разберём простой, но эффектный способ создать блок с анимированным градиентным фоном. Такое обычно используют на лендингах, для привлечения внимания к первому экрану.
HTML-разметка:
<div class="hero">
<h1>формошлёп</h1>
</div>
.hero с заголовком. .hero:.hero {
height: 100vh;
font-family: sans-serif;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(to right, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 800% 800%;
animation: gradientMove 15s ease-in-out infinite;
}@keyframes gradientMove {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
Звездный рейтинг на CSS
Разберём простой способ создания рейтинга без JS.
HTML-структура:
<input type="radio" name="rating" value="5" id="star5">
<label for="star5" title="5 звёзд"></label>
for с id.row-reverse переворачивает порядок отображения:.rating {
display: flex;
flex-direction: row-reverse;
}.rating input { display: none; }label на звёзды:.rating label::before {
content: "★"; /* создаём визуальные звёзды */
}~ находит все последующие label после выбранного input:.rating input:checked ~ label {
color: #ffc107; /* подсветка выбранных звёзд */
}row-reverse и селектору ~, при выборе звезды — подсвечиваются все предшествующие ей в визуальном порядке.
Основные способы центрирования колонки
Допустим, у нас есть колонка с максимальной шириной 1024px, и нам нужно ее отцентровать. Разберем самые основные способы.
Классический способ
.container {
max-width: 1024px;
margin: 0 auto;
}.wrapper {
display: grid;
place-items: center;
}
.container {
width: 100%;
max-width: 1024px;
}place-items: center центрирует содержимое как по горизонтали, так и по вертикали. Родитель активно управляет позиционированием дочерних элементов..wrapper {
display: flex;
justify-content: center;
}
.container {
width: 100%;
max-width: 1024px;
}justify-content: center выравнивает содержимое по центру главной оси.
"Липкий" хедер с эффектом размытия
Сегодня разберём, как сделать стильный фиксированный хедер с полупрозрачным фоном и размытием — прям, как у Apple)
Сделаем обычную разметку:
<header class="header"></header>
<main class="main">
<section class="section">
<h2></h2>
<p></p>
</section>
</main>
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: rgba(255, 255, 255, 0.6);
backdrop-filter: saturate(180%) blur(20px);
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
z-index: 100;
}z-index: 100.backdrop-filter получаем эффект размытия фона под элементом.backdrop-filter и background, чтобы получилось еще интереснее)
Бургер-меню без JS
Давайте разберем, как сделать адаптивное меню для сайта, используя только HTML и CSS.
Нам нужно:
■ Скрытый checkbox для хранения состояния.
■ Label, как переключатель (кнопка бургера).
■ Меню изначально скрыто через opacity: 0.
■ При клике на label — чекбокс переключается и показывает меню.
HTML:
<input type="checkbox" id="menu-toggle">
<div class="menu">
<nav>
<a href="#">Главная</a>
<a href="#">О нас</a>
</nav>
</div>
<label for="menu-toggle" class="menu-btn">
<span></span>
<span></span>
<span></span>
</label>
#menu-toggle {
display: none;
}
.menu {
opacity: 0;
visibility: hidden;
}
#menu-toggle:checked ~ .menu {
opacity: 1;
visibility: visible;
}Checkbox скрыт — display: none, но состояние сохраняется.Label связан с input через for="menu-toggle".label = клик на checkbox — браузер автоматически переключает состояние.~ — находит элементы .menu после чекбокса.:checked — псевдокласс активен только при отмеченном checkbox.
Эффект "появления текста при наведении"
Давайте разберём интересный CSS-эффект, когда часть текста плавно появляется при наведении курсора.
HTML:
<h1>Наведи<span class="hide">, чтобы увидеть весь текст</span>!</h1>
.hide изначально скрыт, он будет "появляться" при наведении. .hide {
display: inline-block;
max-width: 0%;
vertical-align: bottom;
overflow: hidden;
white-space: nowrap;
transition: max-width 1s ease-in-out;
}display: inline-block — превращаем span в inline-block, для управления его шириной.max-width: 0 — ограничиваем максимальную ширину до 0.overflow: hidden — обрезаем всё, что выходит за пределы блока.transition: max-width 1s ease-in-out — анимация изменения ширины.h1:hover .hide {
max-width: 100%;
}<h1> мы увеличиваем max-width до 100%, и текст плавно "раскрывается" слева направо.
Градиентная обводка текста
Сегодня давайте разберем один из эффектных трюков — текст с градиентной обводкой на чистом CSS.
HTML:
<h1>Формошлёп</h1>
:root {
--color-background: #000119;
--stroke-width: 12px;
--font-size: 150px;
--font-weight: 700;
}h1 {
background-clip: text;
background-image: linear-gradient(
to right,
#09f1b8,
#00a2ff,
#ff00d2,
#fed90f
);
color: var(--color-background);
font-size: var(--font-size);
font-weight: var(--font-weight);
-webkit-text-stroke-color: transparent;
-webkit-text-stroke-width: var(--stroke-width);
}background-clip: text — обрезаем фон по форме текста. -webkit-text-stroke-width задаёт толщину обводки (12px).-webkit-text-stroke-color: transparent делает внутреннюю часть обводки прозрачной.
Toggle Switch на CSS
Разберем, как сделать модный переключатель, вместо обычного чекбокса.
HTML структура:
<label class="toggle-switch">
<input type="checkbox">
<span class="slider"></span>
</label>
<label> лежит скрытый <input type="checkbox"> и стилизованный <span class="slider">, который и выглядит как переключатель..toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}.slider {
background: #ccc;
border-radius: 34px;
transition: 0.4s;
}:before):.slider:before {
content: "";
background: white;
border-radius: 50%;
transition: 0.4s;
}input:checked + .slider {
background: #2196F3;
}
input:checked + .slider:before {
transform: translateX(26px);
}
Sticky заголовки
Иногда при прокрутке длинного контента нужно, чтобы заголовок текущего блока не убегал вверх, а оставался на экране, пока мы не дойдём до следующей секции.
Разберем, как это сделать с помощью position: sticky.
Html-структура:
<div class="content-block">
<h2>Шаг 1</h2>
<p>Контент...</p>
<h2>Шаг 2</h2>
<p>Контент...</p>
<h2>Шаг 3</h2>
<p>Контент...</p>
</div>
h2 {
position: sticky;
top: 0;
background: #6200ee;
color: white;
padding: 12px 20px;
margin: 0;
z-index: 1;
}position: sticky + top: 0 — заголовок прилипает к верхней границе контейнераbackground нужен, чтобы перекрывать контент снизуz-index: 1 — поднимаем заголовок над остальным контентом
Раскрывающаяся панель поиска
Сегодня разберем классную штуку — раскрывающуюся панель поиска. Такую часто можно встретить в хедерах сайтов.
Создадим контейнер с инпутом и кнопкой:
<div class="search-bar">
<input type="search" class="search-input" placeholder="Искать...">
<button class="search-btn">
<i class="fa-solid fa-magnifying-glass"></i>
</button>
</div>
.search-bar {
display: flex;
justify-content: flex-end;
background: white;
border-radius: 50px;
width: 70px;
transition: width 0.4s ease;
overflow: hidden;
}:focus-within расширяемся при фокусе на любом дочернем элементе:.search-bar:focus-within {
width: 500px;
}.search-input {
opacity: 0;
transition: opacity 0.4s ease;
}
.search-bar:focus-within .search-input {
opacity: 1;
}
Акцент в меню с помощью :has()
Сегодня разберём мини-лайфхак: меню с эффектом "акцента" на активном пункте.
Ну, т.е. когда наводишь на один пункт — остальные слегка затемняются.
Создадим обычное меню:
<nav>
<ul class="nav-list">
<li><a href="#">Главная</a></li>
<li><a href="#">Статьи</a></li>
<li><a href="#">Видео</a></li>
<li><a href="#">Контакты</a></li>
</ul>
</nav>
nav a:hover {
color: #ff7a18;
}:has:nav ul:has(a:hover) a:not(:hover) {
opacity: 0.3;
}nav ul:has(a:hover) — если внутри списка есть ссылка в состоянии hovera:not(:hover) — то все ссылки, которые НЕ в состоянии hoveropacity: 0.3 — сделать полупрозрачными
Анимация выделения текста при наведении
Случайно наткнулся на интересный прием — эффектное выделение важных частей текста при наведении.
Он отлично подходит для подсветки ключевых фраз в статьях, акцента на важных моментах и т.п.
HTML-разметка:
<p class="animate">
Фронтенд-разработка — это создание внешнего интерфейса.
<span>Для фронтенд-разработчика важно, чтобы пользователи с лёгкостью могли найти на сайте всё, что им нужно.</span>
К примеру, прочитать подробности о товаре...
</p>
animate, а внутри него <span> оборачивает текст, который нужно выделить.p.animate span {
background: linear-gradient(to right, #ffef7e, #b7f9e9);
background-size: 0% 100%;
background-repeat: no-repeat;
transition: background 750ms ease-in-out;
box-decoration-break: clone;
}
.animate:hover span {
background-size: 100% 100%;
}linear-gradient создаёт градиентное подчёркиваниеbackground-size: 0% 100% - изначально фон невидим (0% по ширине)transition обеспечивает плавную анимациюbox-decoration-break: clone - для многострочных выделений, чтобы фон применялся к каждой строке отдельно:hover - триггер анимации, при наведении на весь абзац — фон растягивается на 100%.
Glitch-эффект для текста на CSS
Как-то верстал лендинг в стиле киберпанка, там был текстовый логотип, к которому нужно было применить глитч-эффект, чтобы тени елозили туда-сюда, создавая искажение.
Пробовал довольно разные способы и подобрал вроде неплохой, который всех устроил)
Разберем его здесь, вдруг кому пригодится.
Разметка:
<div class="glitch">ФОРМОШЛЁП</div>
.glitch {
font-size: 4rem;
font-weight: bold;
color: white;
animation: glitch 0.9s infinite;
}
@keyframes glitch {
0%,
100% {
text-shadow: -2px -2px 0 #1f640a, 2px 2px 0 red;
}
25% {
text-shadow: 2px 2px 0 #1f640a, -2px -2px 0 red;
}
50% {
text-shadow: 2px -2px 0 #1f640a, -2px 2px 0 red;
}
75% {
text-shadow: -2px 2px 0 #1f640a, 2px -2px 0 red;
}
}
Контроль изображения с Object-Fit
Как разместить картинку в контейнере, если их пропорции не совпадают? object-fit решает эту задачу довольно просто.
Свойство определяет, как изображение будет помещаться в контейнер. Аналог background-size, но для img)
Fill
Изображение растягивается или сжимается, чтобы полностью заполнить контейнер. Пропорции могут быть нарушены.
object-fit: fill;
object-fit: cover;
object-fit: contain;
none или contain, выбирая вариант, который дает меньший размер изображения.object-fit: scale-down;
object-fit: none;
aspect-ratio)
CSS-эффект затухания для обрезки текста
Если не хочется ставить многоточие для обрезки длинного текста, то можно использовать эффект плавного затухания.
Причем организовать это можно без псевдоэлементов, а с помощью mask-image.
Разметка:
<div class="single-line">
Формошлёп: блог про фронтенд — шлёпаем формы и красим кнопки
</div>
.single-line {
white-space: nowrap;
overflow: hidden;
/* Маска для затухания */
mask-image: linear-gradient(to right, black 70%, transparent 100%);
}mask-image:mask-image задаёт прозрачность по шаблону.black = непрозрачно (текст виден полностью)transparent = полная прозрачность (текст исчезает)
Overlay с помощью border-image
В этом посте, мы уже с вами разбирали, как сделать оверлей, с помощью добавления градиента непосредственно на фоновое изображение. Но есть еще один интересный и не совсем очевидный способ — с помощью свойства border-image.
Свойство border-image, позволяет заменять стандартные границы элемента на произвольное изображение или CSS-градиент. Но можно использовать его не совсем стандартно)
HTML-разметка:
<div class="container overlay">
<h1>С затемнением</h1>
</div>
.container {
height: 250px;
margin: 10px auto;
background: url(image.jpg) center/cover;
display: grid;
place-items: center;
color: #fff;
}
.overlay {
border-image: fill 0 linear-gradient(#0003, #000);
}border-image мы:fill — растягиваем градиент на всю область элемента.linear-gradient(#0003, #000) — создаем полупрозрачный чёрный градиент.