Шлёпаем формы и красим кнопки... Блог про фронтенд — просто, понятно и с юмором. Всех обнял, приподнял, пошел пилить для вас годноту) Связь: @advertos
Нативные поповеры в 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);
Отображение результатов формы через <output>
Предлагаю сегодня разобрать еще один интересный тег <output>
.
Это удобный способ показать результаты формы в реальном времени.
Реализация простого калькулятора суммы:
<form oninput="result.value = parseInt(a.value) + parseInt(b.value)">
<input type="number" name="a"> +
<input type="number" name="b"> =
<output name="result"></output>
</form>
oninput
— это событие, которое срабатывает каждый раз, когда юзер что-то вводит или меняет в любом поле внутри формы. В нашем случае — при изменении значений в <input>
.parseInt(a.value)
— преобразуем значения в числаresult.value
- суммируем числа<output name="result">
— выводим результатЕдиница ch для работы с текстом
Разберем еще одну интересную единицу измерения в CSS.
Это единица ch
, она основана на ширине символа "0" в текущем шрифте. Позволяет эффективно управлять шириной текстовых блоков.
Реализация:
<p>Этот текст ограничен по ширине с помощью ch. Единица ch равна ширине символа "0", и 60ch — это примерно 60 символов в строке.</p>
p {
max-width: 60ch;
line-height: 1.5;
font-family: Arial, sans-serif;
margin: 0 auto;
padding: 16px;
background: #f0f0f0;
border-radius: 8px;
}
ch
можно использовать не только для max-width
, но и для других свойств, например:width: 20ch
— для фиксированной ширины поля ввода.text-indent: 2ch
— для отступа первой строки.font-family: "Courier New"
), ch
будет ещё точнее соответствовать количеству символов.Видео-шпаргалка: CSS-позиционирование
Нашел видео по позиционированию в CSS, все очень красиво и наглядно показано, решил с вами поделиться, наслаждайтесь)
Код из видео:
.parent-element {
position: relative; /* относительное позиционирование */
}
.child-element {
position: absolut; /* абсолютное позиционирование */
bottom: 0;
right: 0;
}
.child-element {
position: fixed; /* фиксированное позиционирование */
top: 0;
right: 0;
}
.child-element {
position: sticky; /* «липкое» позиционирование */
top: 0;
right: 0;
}
Стилизация формы с помощью :user-invalid и :valid
Недавно мы рассматривали, как подсвечивать поля формы с некорректными данными. Вот в этом посте.
Сейчас предлагаю дополнить предыдущий код, теперь давайте будем не только подсвечивать проблемные поля, но и дополнительно будем выводить сообщения об ошибках. Плюс подсвечивать зеленым те поля, где все введено корректно.
Для этого добавим:
.error-message {
display: none;
position: absolute;
bottom: -20px;
left: 0;
font-size: 12px;
color: #f44336;
}
input:valid {
border-color: #4caf50;
}
input:user-invalid + .error-message {
display: block;
}
Откопал в заметках кое-что интересное и решил поделиться с вами — https://webmasters.teamdev.com/. Подробный гайд по вёрстке и фронтенду: от азов HTML/CSS до архитектуры, доступности и даже программирования.
Полезная информация для всех — от новичков до ребят на опыте)
Что внутри?
— Основа основ: семантика, препроцессоры, SVG, мобильность.
— Путь верстальщика: как расти от "ученика" до "мастера".
— Полезности: работа с формами, шрифтами, фреймворками + софт-скиллы.
Но есть нюанс: материал давно не обновляли, так что некоторые темы (например, jQuery или старые подходы к фреймворкам) могут показаться ретро. Но база — вечна, а стиль подачи с юмором и гифками — огонь!
Сохраняйте в закладки, вдохновляйтесь и качайте скиллы)
Стилизация формы с помощью :user-invalid
Раньше, для стилизации полей формы, которые подходят условиям валидации, использовали псевдокласс :invalid
. Но это это было очень ущербно, потому что он активировался сразу при загрузке страницы.
Теперь есть псевдокласс :user-invalid
— он применяется к полям, с которыми юзер взаимодействовал, а также активируется после попытки отправить форму.
И это очень круто!
Вот небольшой пример:
input:user-invalid {
border-color: #f44336;
box-shadow: 0 0 5px rgba(244, 67, 54, 0.5);
}
required
, type="email"
, minlength
).Простой CSS-хак для разделителей между элементами
Допустим, у нас есть горизонтальный список, и нужно добавить тонкие линии между пунктами, чтобы визуально отделить их друг от друга.
Всё, что нам нужно, это:
— border-right
для создания линий.
— Псевдокласс :not(:last-child)
для исключения последнего элемента.
Реализация:
<ul class="list">
<li>Главная</li>
<li>О нас</li>
<li>Услуги</li>
<li>Контакты</li>
</ul>
.list {
display: flex;
gap: 20px; /* Расстояние между элементами */
list-style: none; /* Убираем маркеры списка */
padding: 0; /* Сбрасываем отступы */
font-family: sans-serif;
}
.list li:not(:last-child) {
border-right: 1px solid #ccc; /* Вертикальная линия */
padding-right: 20px; /* Отступ справа */
}
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
#2196f3
box-shadow
transform: 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; /* Сделаем еще первую букву красной */
}
Умный перенос слов в CSS
Давайте сегодня рассмотрим еще одно интересное CSS свойство — hyphens
.
Оно определяет, как будут переноситься слова через дефис, если строка не помещается в родительский контейнер.
В отличие от свойств overflow-wrap
и word-break
, свойство hyphens
переносит слова именно по слогам и ставит дефис.
Но нужно помнить, что для правильного переноса слов нужно, чтобы язык страницы был определен <html lang="ru">
.
Реализация:
.text {
hyphens: auto;
}
hyphens
и без можно глянуть здесь.
Читать полностью…
Тени в png изображениях
Новички часто путаются когда нужно наложить тень на изображение в формате png. Пытаются для этого использовать свойство box-shadow
, но вместо красивой тени в изображении с прозрачным фоном — получают просто тень на границе изображения.
Чтобы получать красивую тень, именно внутри png изображения, нужно использовать свойство filter
с функцией drop-shadow()
;
Это можно сделать так:
<img src="image.png">
img {
filter: drop-shadow(0.25rem 0.25rem 0.5rem #000000);
}
box-shadow
и filter: drop-shadow();
можно посмотреть здесь.
Читать полностью…
Олдскул: атрибут label для <optgroup>
В HTML есть вещи, которые знают все, но используют их редко. Одна из таких штук — это атрибут label
для элемента <optgroup>
.
Выпадающий список с кучей опций:
<select>
<option disabled selected>--Выберите блюдо--</option>
<option>Цезарь</option>
<option>Весенние роллы</option>
<option>Брускетта</option>
<option>Гриль лосось</option>
<option>Стейк из говядины</option>
<option>Овощное ризотто</option>
</select>
<select>
<option disabled selected>--Выберите блюдо--</option>
<optgroup label="Закуски">
<option>Цезарь</option>
<option>Весенние роллы</option>
<option>Брускетта</option>
</optgroup>
<optgroup label="Основные блюда">
<option>Гриль лосось</option>
<option>Стейк из говядины</option>
<option>Овощное ризотто</option>
</optgroup>
</select>
<select>
, вспомните про <optgroup>
— и ваши пользователи скажут вам спасибо)Выравниваем иконку с текстом
Сегодня разберём простой и модный способ выравнивания иконки с текстом с помощью CSS. Это особенно полезно, если вы хотите, чтобы размер иконки автоматически подстраивался под размер текста. Всё это делается с помощью единицы измерения 1cap
.
Используем:
— display: flex
для контейнера.
— Единицу измерения 1cap
, чтобы размер иконки соответствовал высоте заглавной буквы текста.
— Свойство aspect-ratio: 1
, чтобы иконка оставалась квадратной.
Реализация:
<div class="icon-text">
<img src="https://cdn1.ozone.ru/s3/multimedia-g/6381734008.jpg" class="icon">
<span>Текст рядом с иконкой</span>
</div>
.icon-text {
display: flex;
align-items: center; /* Выравнивание по центру */
gap: 1px;
font-family: sans-serif;
font-size: 30px;
color: #333;
}
.icon {
height: 1cap; /* Размер иконки равен высоте заглавной буквы */
aspect-ratio: 1;
}
Тёмная тема за 5 минут с помощью CSS-переменных
Давайте сегодня разберем, как сделать тёмную тему для сайта буквально за 5 минут, используя CSS-переменные и немного JS.
Будем использовать переменные , чтобы хранить цвета для тем, а переключать будем через изменение атрибута data-theme
у элемента <html>
.
В :root
— светлая тема, в [data-theme="dark"]
— тёмная:
:root {
--bg-color: #fff;
--text-color: #333;
}
[data-theme="dark"] {
--bg-color: #121212;
--text-color: #fff;
}
body {
background: var(--bg-color);
color: var(--text-color);
}
function toggleTheme() {
const root = document.documentElement;
if (root.getAttribute("data-theme") === "dark") {
root.removeAttribute("data-theme");
} else {
root.setAttribute("data-theme", "dark");
}
}