3061
Шлёпаем формы и красим кнопки... Блог про фронтенд — просто, понятно и с юмором. Всех обнял, приподнял, пошел пилить для вас годноту) Связь: @advertos
"Липкая" шапка таблицы с position: sticky v2
Давайте сегодня еще добавим пару фич в нашу таблицу из этого поста. Разберем, как сделать выделение строк, которые находятся под курсором и как добавить эффект зебра-стайл)
Итак, чтобы сделать полосатые строки таблицы, можно с помощью псевдокласса :nth-child выбрать четные строки и поменять им цвет:
tr:nth-child(even) {
background-color: #e0e0e0;
}:hover:tr:hover {
background-color: #f1f9ff;
}
"Липкая" шапка таблицы с position: sticky
Бывает таблица длинная, ты ее скроллишь, читаешь, а потом опа.. и забыл, что вообще находится в столбце №4 и приходится скроллить обратно наверх, запоминать и снова возвращаться вниз. Немного напрягает)
Чтобы пофиксить этот момент, в таблице можно сделать шапку, которая всегда будет на виду во время скролла.
Делается это с помощью всем нам знакомого свойства position: sticky.position: sticky — это своего рода гибрид между relative и fixed. Элемент ведет себя как position: relative, пока не достигнет определенного порога при скролле, а затем превращается в position: fixed.
Чтобы все было ок, достаточно этого:
th {
position: sticky;
top: 0;
background-color: #fff; /* Чтобы не просвечивало содержимое */
}
Давайте разберём еще одну фичу CSS — currentColor, это ключевое слово в CSS, которое ссылается на текущий цвет текста элемента.
Т.е. это динамическая переменная, которая автоматически подхватывает значение color и позволяет использовать его в других свойствах, таких как background, border, fill, stroke и т.д.
Для примера, создадим кнопку:
<button class="btn">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.46447 3.46447C2 ... 8.46967Z"></path>
</svg>
currentColor
</button>
.btn {
color: #ff5722;
border: 3px solid currentColor;
}
.btn:hover {
color: #4caf50;
}
.btn svg {
fill: currentColor;
}color: #ff5722 задаёт оранжевый цвет для текста кнопки.border: 3px solid currentColor и fill: currentColor автоматически подхватывают этот же цвет.:hover меняется только color: #4caf50, а граница и иконка моментально подстраиваются.
Карточка с вертикальным заголовком
Недавно на одном сайте увидел прикольно сделанные карточки, решил повторить и сверстать примерно то же самое. Заодно вам показать и сохранить на будущее, мало ли пригодится еще)
Весь прикол вертикального заголовка здесь в writing-mode: sideways-lr, но это свойство пока слабовато поддерживается браузерами, я расскажу, чем его заменить.
Разметка:
<div class="card">
<div class="vertical-title">Заголовок</div>
<div class="content">
Текст карточки...
</div>
</div>
.vertical-title {
writing-mode: sideways-lr;
display: flex;
align-items: center;
justify-content: center;
}.content пишем текст карточки.writing-mode: sideways-lr; можно заменить на это:writing-mode: vertical-lr;
transform: rotate(180deg);
Эффект stroke из фотошопа в CSS
Кто пробовал фотошопить знает, что там есть эффект обводки (stroke), так вот такой же эффект к тексту можно применять и в CSS.
Это свойство text-stroke, задаем толщину обводки и цвет:
.text {
color: #ffffff; /* Цвет текста */
-webkit-text-stroke: 3px #000000; /* Обводка для WebKit-браузеров */
text-stroke: 3px #000000; /* Стандартная обводка */
}-webkit-.
Наглядно про свойство background-repeat
Свойство background-repeat в CSS определяет, как фоновое изображение будет повторяться.
У него есть несколько основных значений, разберем каждое и закроем вопрос)
background-repeat: no-repeat;
background-repeat: repeat;
background-repeat: space;
background-repeat: round;
repeat-x (повторение только по горизонтали) и repeat-y (повторение только по вертикали).
Читать полностью…
Центрирование в CSS: flexbox и margin: auto
Посвящается тем, кто устал постоянно гуглить, как выровнять блок по центру)
Забирайте, пожалуй, самый простой способ выровнять блок по центру родительского блока:
<div class="container">
<div class="block"></div>
</div>
.container {
display: flex;
}
.block {
margin: auto;
}
display: flex превращает блок в flex-контейнер, активируя flex-контекст для его дочерних элементов.margin: auto на дочернем элементе заставляет браузер автоматически распределить доступное пространство поровну со всех сторон блока.
Нативные поповеры в HTML
Помните, как мы годами писали кастомные решения для поповеров? Кучу JS, позиционирование, обработку кликов вне элемента... А потом ещё фиксили баги на мобилках.
Можно выдохнуть) Браузеры наконец-то добавили нативную поддержку поповеров.
Для открытия используем атрибут popovertarget, который ссылается на id поповера. А сам контейнер помечаем атрибутом popover.
<button popovertarget="mypopover">Покажи попап</button>
<div id="mypopover" popover>Контент поповера</div>
#mypopover {
border-radius: 12px;
box-shadow: 0 8px 20px rgba(0,0,0,0.15);
padding: 16px;
border: none;
animation: fadeIn 0.2s ease-out;
}
#mypopover::backdrop {
background: rgba(0,0,0,0.4);
backdrop-filter: blur(2px);
}
Подсказки с :focus-within
Помните, здесь мы обсуждали форму с плавающими лейблами? Давайте добавим в нее новую фичу с :focus-within, которая будет показывать подсказки при фокусе.
Добавим атрибут data-hint с текстом подсказки.
<div class="input-group" data-hint="Введите ваше полное имя">
<input type="text" class="input-field" id="name" placeholder=" ">
<label for="name" class="input-label">Имя</label>
</div>
:focus-within срабатывает, когда фокус попадает на элемент или его потомков. Мы используем это, чтобы показать подсказку.::after, который берёт текст из data-hint. .input-group получает :focus-within, мы меняем стили: opacity становится 1, и подсказка плавно "всплывает" на место с помощью transform..input-group::after {
content: attr(data-hint);
position: absolute;
}
.input-group:focus-within::after {
opacity: 1;
transform: translateY(0);
}
Группировка элементов одной строкой CSS
Сегодня поговорим о маленьком, но полезном CSS-трюке для группировки элементов.
Стандартная запись:
header a,
main a,
footer a,
nav a,
.sidebar a {
color: red;
}
:where(header, main, footer, nav, .sidebar) a {
color: red;
}:where() — это псевдокласс, который позволяет группировать селекторы без увеличения специфичности. Т.е. мы говорим браузеру: "найди все ссылки a, которые находятся внутри header, main, footer, nav и .sidebar, и сделай их красными!".:where() в своих проектах?
Читать полностью…
Резиновые шрифты с clamp()
Для тех, устал от медиа-запросов для каждого чиха. Держите лайфхак с clamp().
Помните, как было раньше? Сначала пишешь размер шрифта для мобилок, потом для планшетов, потом для десктопов. А между ними — пара-тройка брейкпоинтов:
h1 {
font-size: 1.5rem; /* для телефонов */
}
@media (min-width: 768px) {
h1 {
font-size: 2rem; /* для планшетов */
}
}
@media (min-width: 1200px) {
h1 {
font-size: 3rem; /* для десктопов */
}
}clamp() решает эту проблему одной строкой:h1 {
font-size: clamp(1.5rem, 5vw, 3rem);
}1.5rem (минимум)3rem (максимум)clamp() экономит наше время и нервы)
Читать полностью…
Плавающие лейблы для форм
Давайте сегодня разберем, как сделать плавающие лейблы для форм (floating labels).
Это модный эффект, когда метка изначально находятся внутри поля формы, а при фокусе на поле — метка всплывает над ним. Благодаря такой приколюхе, юзер понимает, что нужно вводить в поле, если вдруг забыл)
HTML-структура:
<div class="input-group">
<input type="text" class="input-field" id="name" placeholder=" ">
<label for="name" class="input-label">Имя</label>
</div>
.input-group {
position: relative;
}.input-label {
position: absolute;
left: 15px;
top: 15px;
}.input-field:focus + .input-label,
.input-field:not(:placeholder-shown) + .input-label {
top: -10px;
left: 10px;
}
Эффект матового стекла на CSS
Сегодня поговорим о том, как делать крутой эффект матового стекла (glassmorphism), чтоб было прям, как на маке)
Всё волшебство делает свойство backdrop-filter, которое добавляет фильтры к фону элемента.
Пример:
background: rgba(255, 255, 255, 0.2);
border-radius: 16px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
border: 1px solid rgba(255, 255, 255, 0.3);
Нестандартное подчёркивание текста на CSS
По умолчанию подчеркивание "разрывается" под определенными буквами (например, "g", "p", "y"). Но иногда по макету нужно сверстать так, чтобы этого разрыва не было.
Так вот, чтобы пофиксить разрыв, достаточно использовать свойство text-decoration-skip-ink: none;
Ну и вдобавок другие свойства для стилизации подчеркивания:
h1 {
text-decoration: underline; /* Добавляем подчеркивание */
text-decoration-color: #fac133; /* Задаем цвет линии */
text-decoration-thickness: 10px; /* Устанавливаем толщину */
text-decoration-skip-ink: none; /* Отключаем разрывы под буквами */
}
Как использовать min() для адаптивности
Хотите писать меньше медиа-запросов? CSS функция min() к вашим услугам)
Она берёт меньшее значение из списка, что идеально для гибких размеров. Примеры использования:
1️⃣ Адаптивная ширина блока:
width: min(100%, 500px);
padding: min(10vw, 50px);
font-size: min(8vw, 48px);
Круглые аватарки с object-fit: cover
Разбираем, как сделать аватарки, которые выглядят, как из модного приложения, а не как из профиля на форуме 2000 года)
Возьмём одну и ту же фотку и применим два подхода: ленивый (border-radius: 50%) и правильный (object-fit: cover).
Ленивый подход с border-radius: 50%
Берём фотку и просто делаем её круглой:
<img class="lazy-avatar" src="image.jpg" alt="Аватар">
.lazy-avatar {
width: 300px;
height: 300px;
border-radius: 50%;
}object-fit: cover:<div class="avatar">
<img src="image.jpg" alt="Аватар">
</div>
.avatar {
width: 100px;
height: 100px;
border-radius: 50%;
overflow: hidden;
}
.avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
Второй способ прижать подвал сайта к низу экрана
Первый способ с флексами мы уже рассматривали здесь. Теперь давайте разберем еще один способ — с помощью CSS Grid.
Превратим всю страницу в грид-контейнер и распределим на зоны: хедер, контент и футер:
<body>
<header>Шапка сайта</header>
<main>Основной контент</main>
<footer>Подвал сайта</footer>
</body>
body {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}grid-template-rows: auto 1fr autoheader) занимает столько места, сколько нужно (auto)main) растягивается на всё свободное пространство (1fr)footer) также занимает только необходимое место (auto)min-height: 100vh - заставляет body занимать как минимум всю высоту экрана.
Стилизуем форму с :optional
Многие знают про псевдокласс :required, но его противоположность :optional — незаслуженно обходят стороной. А ведь этот псевдокласс позволяет стилизовать все поля формы, у которых нет атрибута required.
Например, зададим фон необязательным полям:
input:optional {
background: #f0f7ff;
}input:required {
background: #fff;
}required и без будут закрашены в разные цвета.
Гамбургер-меню без JS с помощью Popover
В этом посте, мы рассматривали Popover, давайте теперь с его помощью сделаем простейшее гамбургер-меню?
HTML-структура:
<button class="menu-btn" popovertarget="menu">☰</button>
<div popover id="menu">
<button class="close-btn" popovertarget="menu" popovertargetaction="hide">✖️</button>
<nav>
<ul>
<li><a href="#">Главная</a></li>
<li><a href="#">О нас</a></li>
<li><a href="#">Контакты</a></li>
</ul>
</nav>
</div>
#menu {
width: 250px;
height: 100vh;
inset: 0 0 0 auto;
margin: 0;
border: none;
transition: transform 0.3s;
transform: translateX(100%);
}
#menu:popover-open {
transform: translateX(0);
}popovertarget связывает кнопку с менюpopover создает всплывающее окноpopovertargetaction="hide" закрывает меню
Расширяющиеся блоки: простой, но эффектный прием CSS
Давайте сегодня опять поработаем с флексами и разберем классный эффект, который можно применять для галерей и карточек — плавное увеличение блока при наведении курсора.
Поехали, создадим разметку:
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
flex: 1;.box {
flex: 1;
transition: flex-grow 0.3s ease;
width: 100%;
height: 10rem;
background: #FF9933;
border-radius: 1rem;
}.box:hover {
flex-grow: 2;
}flex: 1flex-grow: 2, плюс накинули анимацию, чтобы это было плавно.
:not(:hover) для затемнения соседних элементов
Иногда по ТЗ бывает необходимость добавить интерактивности, например, есть контейнер с блоками и при наведении на 1 блок, нужно его подсвечивать, затемняя соседние.
Давайте разберем самый простой способ решения такой задачи.
Сделаем разметку:
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
.container:hover > :not(:hover) {
opacity: 0.5;
}.container>)hover (:not(:hover))opacity: 0.5
Когда джун получил первый апрув на свой пул-реквест)
Читать полностью…
Aspect-ratio в CSS: сохраняем пропорции без лишнего кода
Хотите, чтобы квадрат был квадратом даже при масштабировании?
Свойство aspect-ratio в CSS помогает элементам сохранять заданное соотношение ширины и высоты. Это идеально для адаптивных дизайнов, где нужно, чтобы блоки, изображения или видео не теряли пропорции при изменении размеров.
Давайте сравним два блока:
— Первый — с фиксированной высотой (height: 200px), которая не меняется.
— Второй — использует aspect-ratio: 1 / 1, чтобы оставаться квадратом.
При уменьшении ширины экрана первый блок "сжимается" только по ширине, теряя форму, а второй сохраняет квадратные пропорции.
<div class="card fixed">1</div>
<div class="card aspect-ratio">2</div>
.fixed {
height: 200px;
}
.aspect-ratio {
aspect-ratio: 1;
}
:has() для интерактивных карточек с чекбоксами
Хочу показать вам еще одну интересную идею применения селектора :has().
Сделаем интерактивные карточки, которые меняют внешний вид, когда юзер отмечает чекбокс внутри них. Такое раньше делали только с помощью JS, а теперь — парой строчек в CSS.
.card:has(input:checked) {
background-color: #e3f2fd;
border-color: #2196f3;
box-shadow: 0 0 15px rgba(33, 150, 243, 0.3);
transform: translateY(-5px);
}:has() ищет родительский элемент (карточку), содержащий определенный дочерний элементinput:checked — это условие: отмеченный чекбокс#e3f2fd#2196f3box-shadowtransform: translateY(-5px)transition: all 0.3s ease
Открываешь ссылку в инкогнито, Гугл такой — "он открыл ее в инкогнито, значит это самое интересное, так и запишем..."
Читать полностью…
Стилизация радио-кнопок в виде иконок
Хотите сделать радио-кнопки стильными, модными, молодежными?) Давайте сегодня разберем, как превратить их красивые иконки.
HTML:
<label class="icon-radio">
<input type="radio" name="delivery" checked>
<div class="icon-radio-content">
🚚<span class="icon-radio-label">Курьер</span>
</div>
</label>
.icon-radio input {
position: absolute;
opacity: 0;
}.icon-radio-content {
border: 2px solid #e0e0e0;
border-radius: 12px;
transition: all 0.3s;
}input:checked + .icon-radio-content {
border-color: #4a6bff;
background: #f5f7ff;
}.icon-radio:hover .icon-radio-content {
border-color: #b3c1ff;
}
Видео-шпаргалка: адаптивная верстка на CSS Grid
Нашел наглядный видос по созданию адаптивных блоков на CSS Grid, без медиа-запросов.
Код из видео:
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
</div>
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
width: 100%;
}
Список с точками-разделителями на чистом CSS
Если вам нужно сверстать список с разделителями в виде точек, как в старых добрых меню или прайс-листах, то вот вам интересный способ на Flexbox.
Разметка может быть такой:
<ul class="dotted-list">
<li>
<span class="number">101</span>
<span class="dots"></span>
<span class="text">Пожарная (МЧС)</span>
</li>
</ul>
.dotted-list .dots {
flex-grow: 1;
border-bottom: 2px dotted #333;
height: 1em;
margin: 0 4px;
transform: translateY(-1px);
}display: flex позволяет легко расположить элементы в строку.flex-grow: 1 для элемента с точками заставляет его растягиваться на всё доступное пространство.border-bottom: dotted создаёт видимость точек-разделителей.transform: translateY тонко настраивает выравнивание точек.
Красная строка в CSS
Недавно потребовалось запилить красную строку (первую строку абзаца с отступом), пришлось гуглить, потому что забыл. Поэтому, чтоб не забывать, решил здесь пост запилить об этом.
Выделил два основных способа реализации — классика, с помощью свойства text-indent и с помощью псевдоэлемента ::first-letter.
Вариант 1:
p {
text-indent: 2em;
}p::first-letter {
margin-left: 2em;
color: red; /* Сделаем еще первую букву красной */
}