Шлёпаем формы и красим кнопки... Блог про фронтенд — просто, понятно и с юмором. Всех обнял, приподнял, пошел пилить для вас годноту) Связь: @advertos
Убираем отступ под изображением
Микро лайфхак для новичков.
Когда мы вставляем изображение на страницу, то тег <img src="image.jpg">
по умолчанию является строчным элементом, а поэтому и получаем отступ снизу (для "хвостиков" букв, вроде gjpqy).
Чтобы пофиксить этот момент достаточно изображение сделать блочным элементом:
img {
display: block;
}
line-height: 0
.img {
display: block;
max-width: 100%;
height: auto;
}
Управление цепочкой прокрутки окна
Замечали такое, что когда открыто модальное окно, в котором туча текста и есть скролл, мы скроллим модальное окно, а когда доскроллим его до конца, то начинается скроллиться уже окно барузера?
Вот это называется "цепочка прокрутки", когда после окончания одного скролла, идет скролл внешнего элемента.
Победить это дело можно с помощью свойства overscroll-behavior
.
С его помощью можно настроить прокрутку так, чтобы вложенные элементы не передавали скролл родителю.
Достаточно указать overscroll-behavior: contain;
— скролл только в пределах текущего элемента.
Пример работы можно увидеть здесь, попробуйте удалить overscroll-behavior: contain;
и как говорится, ощутите разницу)
Плавная прокрутка с эффектом привязки: CSS Scroll Snap
Модный эффект для верстки лендингов) Когда нужна плавная прокрутка с привязкой к секциям.
Давайте разберем, как это дело можно реализовать.
Создадим разметку:
<div class="scroll-wrapper">
<div class="scroll-section section1"><h2>Section 1</h2></div>
<div class="scroll-section section2"><h2>Section 2</h2></div>
<div class="scroll-section section3"><h2>Section 3</h2></div>
</div>
.scroll-wrapper {
height: 100vh;
overflow-y: auto;
scroll-snap-type: y mandatory;
}
.scroll-section {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
scroll-snap-align: start;
}
scroll-snap-type: y mandatory
— включает привязку прокрутки по оси Y, фиксируя каждую секцию.scroll-snap-align: start
— выравнивает секции по верхнему краю при прокрутке.Горячие клавиши в VS Code
Принес еще немного годноты для ускорения верстки)
Вроде бы очевидные вещи, которые реально помогают, но многие про них не знают или забывают, так что если что, то теперь знайте или не забывайте)
Ну, а здесь можно найти официальные PDF с хоткеями для каждой ОС в VS Code:
■ Windows
■ macOS
■ Linux
Меняем кнопку Enter виртуальной клавиатуры
Разберем интересный и простой трюк, который сделает наши формы, на мобильных устройствах, умнее — атрибут enterkeyhint
.
Он позволяет менять надпись на клавише Enter в зависимости от того, что делает пользователь — ищет информацию, отправляет сообщение или переходит к следующему полю.
Браузеры моб. устройств отображают эту кнопку по-разному, в зависимости от значения атрибута.
Добавляем атрибут к <input>
или <textarea>
:
<input type="text" id="message" placeholder="Введите сообщение..." enterkeyhint="send">
enter
— стандартная кнопка (по умолчанию)done
— «Готово»go
— «Перейти» next
— «Далее»search
— «Найти»send
— «Отправить»Адаптивные колонки
Если вам вдруг позарез необходимо сверстать адаптивные текстовые колонки, то можно обойтись без флексов и гридов, использовав columns
, все делается буквально одной строчкой:
.container {
columns: auto 20rem;
}
auto
— означает автоматическое определение количества колонок.20rem
— минимальная ширина каждой колонки.Нарезаем изображения
Сегодня давайте бегло пробежимся по CSS-свойству, благодаря которому мы можем делать изображения таких форм, которые нафантазировали в своих головах дизайнеры)
Это свойство clip-path
, которое позволяет обрезать изображение по заданной форме.
Основные формы:
1. Круг:
.circle {
clip-path: circle(50% at center);
}
.ellipse {
clip-path: ellipse(25% 40% at 50% 50%);
}
.rhombus {
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
}
X% Y%
. Точки соединяются в указанном порядке."Липкая" шапка таблицы с 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
на дочернем элементе заставляет браузер автоматически распределить доступное пространство поровну со всех сторон блока.Предпросмотр картинки перед загрузкой
Если в форму на сайте нужно отправить какую-то картинку, то бывает полезно сделать предпросмотр этой картинки, перед загрузкой.
Давайте, разберем здесь простой пример, как это можно реализовать.
<div class="upload-container">
<label class="upload-label">Загрузите картинку любого формата (JPG, JPEG, PNG, GIF)</label>
<div class="file-input-wrapper">
<input type="file" id="imageInput" class="file-input" accept="image/*">
<label for="imageInput" class="file-button">Обзор...</label>
<span class="filename" id="filename">Файл не выбран</span>
</div>
</div>
URL.createObjectURL
, потом отображаем ее в <img>
. Размытый фон для изображений на CSS
Бывает, что контейнер шире изображения, изображение растянуть нельзя, но хочется, чтобы фон выглядел красиво.
Разберем интересный способ заполнить пространство контейнера с помощью размытого фона.
Создадим контейнер с изображением:
<div class="image-container">
<img src="image.jpg" class="main-image">
</div>
.image-container {
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.image-container::before {
content: "";
position: absolute;
background-image: url("image.jpg");
background-size: 100% 100%;
filter: blur(5px) brightness(50%);
z-index: 0;
}
.main-image {
z-index: 1;
object-fit: contain;
}
100vh vs 100dvh
Вы задали блоку высоту 100vh
, чтобы он занимал весь экран, но на мобильном устройстве появился скролл. Бывало такое?)
Разберемся почему это происходит и как это пофиксить.
Когда мы используем 100vh
— моб. браузеры интерпретируют это, как 100% от максимальной высоты экрана, а не фактической видимой области.
Результат: часть содержимого может быть "съедена" панелью навигации браузера и появляется лишний скролл.
Для решения этой проблемы существует единица измерения dvh
(dynamic viewport height), которая учитывает фактическую доступную высоту экрана, исключая адресную строку и навигационную панель браузера на мобильных устройствах.
Поддерживается в большинстве современных браузеров, но если хотите подстраховаться, то можно сделать так:
.full-height {
height: 100vh; /* Fallback для старых браузеров */
height: 100dvh; /* Для современных браузеров */
}
Отступы для прокрутки — scroll-padding
Было у вас такое, что вы сделали якорную ссылку для скролла к элементу, все было классно, но потом узнали, что хедер должен быть фиксированным?
Зафиксировали хедер, теперь скролл доходит до элемента, но половина контента скрыта под этим хедером, который никому не нужен, но "по дизайну так надо")
Раньше мы решали это костыльными способами:
■ Добавляли невидимый div
перед нужным элементом.
■ Писали JavaScript для подсчета высоты хедера.
Но теперь все проще, есть scroll-padding-top
, который решает проблему в одну строчку:
html {
scroll-padding-top: 80px; /* Высота хедера */
}
Текстовый фрагмент
Недавно узнал про еще одну интересную фишку, под названием "ссылка на текстовый фрагмент". Т.е. мы можем напрямую ссылаться на определенную часть текста, не используя при этом идентификатор и т.п.
Делается это с помощью #:~:text=
в ссылке.
Реализуется таким образом:
<a href="#:~:text=фрагмент">ссылка на фрагмент</a>
::target-text
:::target-text {
background: black;
color: white;
}
CSS Nesting
Кто не знал, в нативном CSS уже есть такая штука, как nesting(вложенность). Вещь удобная, но в целом не новая, если вы раньше работали с SASS, LESS и.т.д.
Так вот, теперь CSS начал это уметь "из коробки".
Пример простой разметки:
<div class="card">
<h2 class="title">Карточка</h2>
<button class="button">Кнопка</button>
</div>
.card {
background: #f5f5f5;
padding: 16px;
.title {
font-size: 20px;
}
.button {
background: #007bff;
color: #fff;
padding: 8px;
&:hover {
background: #0056b3;
}
}
}
.card {
background: #f5f5f5;
padding: 16px;
}
.card .title {
font-size: 20px;
}
.card .button {
background: #007bff;
color: #fff;
padding: 8px;
}
.card .button:hover {
background: #0056b3;
}
clip-path для блоков
Кстати, свойство clip-path
можно юзать не только, для обрезки изображений.
С помощью этого свойства можно стилизовать в целом любые блоки, к примеру, на лендингах можно выделять различные смысловые секции.
Так можно запилить скошенный блок для первой секции, как на картинке в превью поста:
.hero {
min-height: 50vh;
background: #4a6bff;
color: white;
display: flex;
flex-direction: column;
justify-content: center;
clip-path: polygon(0 0, 100% 0, 100% 80%, 0 100%);
}
Фигурные обтекания с shape-outside
Частенько, особенно при верстке лендингов, приходится делать фигурное обтекание картинок текстом.
Свойство shape-outside
, как раз на этом специализируется. Оно позволяет задать форму, вокруг которой будет обтекать текст и не просто прямоугольник, а круг, треугольник или даже сложную SVG-фигуру.
Чтобы все обтекало, как надо, достаточно задать блоку float
и shape-outside
. Форму можно определить через:
■ circle()
■ ellipse()
■ polygon()
■ url()
если форма задана в SVG
Пример с кругом:
.shape {
float: left;
shape-outside: circle(50%);
width: 200px;
height: 200px;
background: #3498db;
border-radius: 50%;
}
Круглые аватарки с 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 auto
header
) занимает столько места, сколько нужно (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: 1
flex-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
Когда джун получил первый апрув на свой пул-реквест)
Читать полностью…