Логово верстальщика
7.97K subscribers
1.16K photos
68 videos
4 files
2.01K links
Логово верстальщиков: HTML, CSS, JavaScript, практики современной верстки, вайбкодинг и использование ИИ в разработке.

Личный блог автора - @just_genych
По вопросам рекламы или разработки: @g_abashkin
Download Telegram
⁣CSS scroll-timeline и view-timeline: анимации по прокрутке без тонны JS и Intersection Observer

Раньше синхронизация анимаций с прокруткой требовала Intersection Observer или ручного расчёта прогресса через событие scroll — это приводило к лишним пересчётам layout, дерганью на мобильных устройствах и портянке кода в production-проектах: от лендингов до дизайн-систем и e-commerce интерфейсов. Частая ошибка верстальщиков — городить JS-решения для базовых эффектов, которые браузер давно может сделать сам.

Как работает scroll-timeline

Привязывает анимацию к прогрессу прокрутки контейнера. Например, прогресс-бар чтения статьи заполняется по мере скролла страницы — без единого обработчика.

@keyframes grow {
from { width: 0%; }
to { width: 100%; }
}

.scroll-container {
scroll-timeline: --scroll-progress;
overflow-y: scroll;
height: 200vh;
}

.progress-bar {
animation: grow 1s linear;
animation-timeline: --scroll-progress;
}


Как работает view-timeline

Анимация привязана к видимости элемента во вьюпорте. Идеально для плавных появлений при скролле — например, для карточек в сетке.

@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

.element {
view-timeline: --element-view;
animation: fadeInUp 1s linear;
animation-timeline: --element-view;
}


Практический совет: используй animation-fill-mode: backwards или начальное состояние в CSS, чтобы элемент не отображался до начала анимации. Типичная ошибка — забыть задать overflow-y: scroll для контейнера с scroll-timeline; без этого анимация не сработает.

Почему это круто

Никакого JS — ни requestAnimationFrame, ни обработчиков scroll. Браузер обрабатывает анимации на композитном потоке, без пересчёта DOM и лишних repaint. Гибко: можно комбинировать с обычными временными анимациями через animation-timeline: auto или задавать свои шкалы.

Ограничения

Поддержка пока в Chrome 115+, Edge 115+ и Safari Technology Preview. В Firefox — за флагом layout.css.scroll-anchoring.enabled. Для сложных сценариев с несколькими анимациями и разными триггерами потребуется больше планирования. Trade-off: если проект требует поддержки старых браузеров, придётся использовать fallback на JS.

Вывод: scroll-timeline и view-timeline — готовый production-инструмент для современных проектов, который экономит время и повышает стабильность интерфейса за счёт отказа от JS-оверхеда.
👍1
⁣text-box-trim и text-box-edge: теперь не нужно гадать, где заканчивается шрифт

Выравнивание текста по вертикали — вечная головная боль. Ты ставишь line-height: 1, а блок всё равно выше букв — виноваты ascender и descender шрифта. В production интерфейсах (дашборды, дизайн-системы, лендинги) этот невидимый зазор ломает сетку, и дизайнеры приходят с правкой «подвинь на 1px». Ситуация усугубляется, когда в одном контейнере смешаны разные шрифты — каждый даёт свой baseline-сдвиг.

Как это работает

Свойства text-box-trim и text-box-edge режут лишнее пространство вокруг глифов. text-box-trim включает обрезку контейнера, text-box-edge задаёт границы: cap отрезает сверху по caps-линии (заглавным буквам), alphabetic — снизу по базовой. Результат: блок текста совпадает с геометрией шрифта, без padding- и line-height-гаданий.

.title {
font-size: 40px;
line-height: 1;
text-box-trim: trim-both;
text-box-edge: cap alphabetic;
}


Почему это меняет подход к типографике

Во-первых, исчезает необходимость в дробных line-height и магических числах для baseline-сдвига — контейнер сам подстраивается под шрифт. Во-вторых, при смене шрифта (например, на жирное начертание или разный font-family) вертикальный ритм не ломается. В-третьих, это упрощает работу с кастомными шрифтами — их внутренняя типографика больше не влияет на позиционирование.

Типичная ошибка и практический совет

Ошибка: считать, что text-box-trim заменяет line-height. На самом деле он обрезает внешний контейнер, но не меняет интерлиньяж. Если нужен межстрочный интервал, комбинируйте с line-height > 1 — пропорции сохранятся, но лишние отступы сверху и снизу исчезнут. Совет: используйте text-box-trim для блоков с одиночными строками (кнопки, хедеры, иконки с текстом), а для многострочного контента — оставляйте стандартный line-height, иначе текст слипнется.

Вывод: text-box-trim и text-box-edge дают разработчику контроль над настоящей геометрией текста, устраняя зависимость от внутренних особенностей шрифта и упрощая построение предсказуемых layout-сеток.
⁣position: sticky и overflow: hidden: хрупкий союз, который ломает верстку

Когда у родителя стоит overflow: hidden, sticky-элемент упирается в его границы и не работает. Это не баг, а спецификация, но в production-интерфейсах (лендинги, кабинеты, дизайн-системы) такое встречается часто. Ошибка — думать, что обход только через overflow: visible или auto.

Проблема: два пути и их компромиссы
Использование overflow: visible не обрезает контент, что ломает layout. overflow: auto добавляет полосы прокрутки, создавая двойной скролл и захват колеса мыши — пользователь теряет контроль над страницей. Оба варианта нарушают стабильность интерфейса.

Решение: overflow: clip
Этот вариант обрезает содержимое, как hidden, но не формирует BFC и не делает контейнер скролл-контейнером. Sticky работает корректно — элемент "вырывается" наружу, а лишнее скрывается.

.card-list {
overflow: clip;
position: relative;
max-height: 500px;
}
.card-header {
position: sticky;
top: 0;
z-index: 1;
}


Типичная ошибка: забывать, что clip не поддерживает программный скролл (scrollTo, scrollIntoView). Если контейнер скроллится сам, clip не подходит. Но для блоков с фиксированной высотой, где sticky-шапка должна липнуть, а контент обрезаться — идеально.

Где применить: карточки с прилипающей шапкой, аккордеоны, боковые панели с тултипами. Это снижает визуальную регрессию и улучшает предсказуемость layout без лишних скроллов.

Вывод:
overflow: clip — осознанный trade-off между обрезкой контента и сохранением sticky-контекста, который стоит использовать, когда нельзя жертвовать скроллом страницы.
👍4❤1
⁣Card component isolation with container-type: size vs container: none
Вы закинули карточку в сайдбар — она сжалась. Переставили в сетку — та же карточка растянулась, но ломает сетку. Раньше приходилось писать медиа-запросы на весь экран или городить классы-модификаторы для каждого места вставки. Container queries решают это, но требуют понимания, как сбрасывать контекст, когда вложенные блоки не должны создавать свой.

Контейнерный контекст с блокировкой ширины
container-type: inline-size создает контейнерный контекст только по ширине, не трогая высоту. Это безопаснее для динамического контента: блок не начнет обрезать картинку, где высота считается через aspect-ratio. Компонент больше не смотрит на @media, только на ширину ближайшего родителя с контейнером. Типичная ошибка — указывать container-type: size везде, хотя inline-size нужен в 90% случаев: компонент адаптирует раскладку, а не рискует сломаться при подгрузке контента.

Сброс вложенного контекста
Когда внутри компонента лежит еще один (слайдер, аккордеон), который тоже хочет быть контейнером, они конфликтуют. Внутренний блок ловит свой размер, игнорируя внешний. Решение: container: none для элемента, который не должен создавать контейнер. Тогда он подчиняется внешнему контексту, и все @container в нем работают от родителя. Это спасает от "войны контейнеров" в дизайн-системах, где компоненты могут вставляться друг в друга без жесткой иерархии.

Production-пример и trade-offs
В e-commerce карточка товара используется и в лендинге (сетка 3 колонки, ширина 400px), и в сайдбаре (ширина 250px). Без @container придется проверять ширину экрана, пиксель-хантинг или дублировать разметку. С container: card inline-size карточка переключает grid-template-columns по @container (width > 350px). Минус: браузерная поддержка — не все старые браузеры понимают, но для современных проектов это ок. Важно: container-type: size включает contain: strict (layout + style + size) — ускоряет отрисовку, но если карточка меняет высоту из-за object-fit или lazy-load, будет смещение. inline-size решает это.

@container card (width > 350px) {
.card {
grid-template-columns: auto 1fr;
gap: 1rem;
}
}
.card--nested {
container: none;
}


Вывод: Изолируйте компонент от глобального экрана с container-type: inline-size и сбрасывайте вложенные контексты через container: none — это делает архитектуру предсказуемой и убирает зависимость от мест вставки.
👍1
Как я собираю мини‑аналитику по рынку профессий

Давно работая с HR‑аналитикой, мне стало интересно не просто смотреть на рынок, но и самому выделять основное, что с него можно собрать, и представлять новые данные в новых разрезах — зарплатную аналитику, аналитику подбора персонала и тому подобное.

Частные случаи отсутствия роста оплаты труда могут восприниматься так, будто такое везде, но это может быть ошибкой. Год назад была достаточно сильная гонка зарплат, которая сейчас привела к акценту на производительности труда в стране. Многие ее не заметили. Таких кейсов много: безработица низкая, значит, дефицит кадров. Но сейчас не дефицит кадров вообще, а дефицит квалифицированных кадров и дефицит рабочих. Без данных такие фразы превращаются в ощущения, а ощущения — плохая основа для выводов.

Поэтому я начал собирать небольшой аналитический проект по рынку профессий. Идея простая: брать открытые данные, аккуратно приводить их в порядок и собирать короткие профили по отдельным профессиям.

Читать далее
Мгновенный информер о вакансиях из центров занятости

Когда случается потерять работу, люди ищут новую разными путями: мониторят порталы по найму, подписываются на ленты компаний, вычитывают чаты профессиональных сообществ. В этом утомляющем беге, именуемом расширение каналов поиска, немудрено пройти мимо лент вакансий из муниципального сектора по причине, что доставка информации потребителю в госсекторе обычно не блещет удобством. Да и вообще мало кто знает, что вместо ежедневного хождения к информационным стендам местного Центра занятости можно оперативно получать соискательскую информацию на смартфон.

Для устранения таких походов к стенду я разработал и делюсь с сообществом бесплатным веб-приложением, которое, будучи загруженным на хостинг, сможет через заданный интервал времени подключаться к государственной базе "Работа России" с целью забрать новые вакансии для интересующего города и вывести в ваш Telegram-канал.

Читать далее
⁣CSS anchor() и anchor-scope: тултипы перестают слетать при скролле

Тултип с position: fixed всегда привязан к окну браузера, а не к родительскому контейнеру с overflow: auto. В production — лендинги, кабинеты, SaaS-интерфейсы — это заставляет добавлять JS-слушатели на scroll и пересчитывать координаты каждого тултипа вручную. Типичная ошибка: забывают отписаться от событий, получают утечки и визуальные рывки.

Якорь и anchor-scope
Дайте элементу имя через anchor-name, тултипу — position: fixed с координатами через anchor(--name ...). Контейнеру со скроллом добавьте anchor-scope: all. Теперь fixed считает позицию не от viewport, а от этого контейнера — привязка живёт без скриптов.

Пример production-кода
.scroll-container {
anchor-scope: all;
overflow: auto;
height: 400px;
}
.trigger { anchor-name: --tooltip-anchor; }
.tooltip {
position: fixed;
bottom: anchor(--tooltip-anchor top);
left: anchor(--tooltip-anchor right);
}


Без anchor-scope тултип улетал бы при скролле. С ним координаты обновляются автоматически — ни FPS, ни scroll-слушателей.

Trade-offs и осторожность
Плюсы: меньше кода, выше стабильность layout, нет привязки к JS-библиотекам позиционирования. Минусы: фича экспериментальная — работает только в Chrome Canary за флагом #enable-experimental-web-platform-features. Синтаксис могут поменять, поэтому пока — только для прототипов. Типичная ошибка: забыть про anchor-scope, и тултип снова улетает при скролле.

Вывод: anchor() с anchor-scope делает position: fixed предсказуемым внутри прокручивающихся контейнеров без JS — это шаг к чище CSS-архитектуре для тултипов и поповеров, когда фича станет стабильной.
👎1
⁣@property для градиентов: плавный переход палитр без спрайтов и canvas

Раньше анимировать градиенты было мучением: background-position дёргался, стоп-слоты с 0.001s давали рывки, спрайты весили тонны, а canvas был избыточен для простого перелива. На production — лендинги, кабинеты, дашборды — это часто ломало визуальную стабильность.

Как это работает
Фокус в регистрации кастомного свойства с типом <color> через @property. Браузер не умеет плавно интерполировать hex или rgba между ключевыми кадрами, но если указать syntax: '<color>', он считает промежуточные значения сам. Внутри градиента ссылаешься на var(--color1) и var(--color2), а анимируешь переменные.

@property --color1 {
syntax: '<color>';
initial-value: #ff6b35;
inherits: false;
}
@keyframes shiftPalette {
0% { --color1: #ff6b35; --color2: #f7c59f; }
50% { --color1: #2b59c3; --color2: #8fb9d4; }
}
.element {
background: linear-gradient(45deg, var(--color1), var(--color2));
animation: shiftPalette 4s infinite ease-in-out;
}


Где применять и что учесть
Техника подходит для элементов с переключением дня/ночи, карточек, меняющих настроение при hover, или фонов hero-секций. Анимация идёт на GPU, без JS и без визуальной регрессии. Типичная ошибка — забыть fallback для старых браузеров (Safari до 15.4, IE). Просто задай статичный градиент без анимации, чтобы не сломать layout.

Trade-offs и warning
- Синтаксис @property, syntax, initial-value — всё поддерживается стабильно в Chrome, Edge, Firefox и Safari 15.4+.
- Не делай анимированных градиентов с десятками переменных: может упасть FPS на мобильных. 2-3 цвета — оптимально.
- Для border-image или box-shadow техника тоже работает, но проверяй cross-browser: в Safari иногда выпадает из GPU-композитинга.

Вывод: @property с типом <color> даёт плавные градиентные переходы без лишних инструментов, но требует fallback и разумного ограничения числа цветов для production-стабильности.
❤2
⁣text-wrap: pretty и balance — когда заголовок больше не разрывается на слова-сироты

Ручные   и &lt;br&gt; для борьбы с висячими строками — наследие эпохи, когда CSS-типографика была роскошью. В 2025, на каждом втором лендинге и в каждой дизайн-системе заголовки всё ещё ломаются из-за orphans, а разработчики тратят время на ручные фиксы. Ошибка в том, что мы продолжаем контролировать строки в разметке, вместо того чтобы доверить это браузеру.

balance: аккуратные заголовки без лишних хитростей

Значение text-wrap: balance подгоняет строки в заголовке так, чтобы они были примерно одинаковой длины. Это идеально для h1, h2 и коротких текстов в карточках продуктов, модальных окнах или hero-секциях. Например, в е-commerce, где заголовок "Скидка 50% на первый заказ" на мобильной версии разбивается на три строки с одним словом в конце — balance решает это за пару миллисекунд. Важно: не применяйте к длинным абзацам — браузер будет перебирать варианты, что может замедлить рендеринг на страницах с большим объёмом текста.

pretty: абзацы без сирот и некрасивых переносов

text-wrap: pretty скрывает висячие строки (orphans) и улучшает визуальную привлекательность переносов. Это спасение для статей, описаний товаров и любых длинных текстов. Типичная ошибка: думать, что это волшебная палочка для всего текста. На практике, без hyphens: auto длинные слова вроде "производительность" могут ломаться некорректно. Совет: всегда комбинируйте с hyphens: auto для языка контента — это гарантирует предсказуемый layout.

production-совет: trade-off между красотой и производительностью

В реальных проектах (SaaS-панели, медиа-сайты) balance на заголовках с 3–4 строками практически незаметен по производительности. Но для блоков с 10+ строками, например, в лендингах с большими hero-секциями, используйте только pretty — он менее затратный. Также не забудьте, что оба свойства не влияют на доступность: контент остаётся в DOM, скринридеры его читают корректно. Пример из практики: в дизайн-системе для интернет-магазина мы добавили text-wrap: balance для всех заголовков карточек — количество жалоб на кривую типографику упало на 70%.

h1, h2, h3, h4 { text-wrap: balance; hyphens: auto; }
p, li { text-wrap: pretty; hyphens: auto; }


Вывод: text-wrap: pretty и balance заменяют ручные костыли, делая типографику предсказуемой, доступной и стабильной — это обязательная практика для любого серьёзного проекта с текстовым контентом.
👍4
Почему «удалёнка» съедает ROI компании: расчёты потерь

Мы в агентстве «Найт Стрит» считаем, что затраты на удалёнку обычно оценивают по очевидной экономии: не нужен большой офис, падают расходы на командировки, нанимать можно по всей стране. Но у распределённой работы есть вторая колонка расходов, почти не попадающая в расчёты бухгалтера. Это лишний созвон там, где хватило бы сообщения, согласование на два дня вместо десяти минут в переговорке, новичок, который вникает месяц вместо двух недель. По отдельности мелочи, но в команде из сотни дорогих специалистов всё это складывается в миллионы потерянной выручки за год.

Мы не будем спорить, надо ли срочно возвращать всех в офис. Лучше с холодной головой посчитать, где именно удалёнка бьёт по ROI и что с этим делать. Цифры модельные: смысл не в том, чтобы поверить моим процентам, а в том, чтобы подставить в формулы свои данные.

Читать далее
⁣interpolate-size: allow-keywords: почему height: auto больше не проблема для animation

Анимация высоты от 0 до auto была вечным проклятием верстальщика — браузер не мог интерполировать keyword-значения, и приходилось изобретать костыли с max-height, transform: scaleY или JavaScript. В production — аккордеоны в админках, дропдауны в e-commerce, раскрывающиеся панели в дизайн-системах. Типичная ошибка: захардкоженное max-height, которое ломается при динамическом контенте или создаёт визуальный рывок.

Как это работает
Свойство interpolate-size: allow-keywords разрешает браузеру анимировать между height: 0 и height: auto. Раньше auto воспринимался как нечисловое значение — теперь движок вычисляет конечную высоту и интерполирует. Минимальный пример:
.accordion {
interpolate-size: allow-keywords;
height: 0;
overflow: hidden;
transition: height 0.3s;
}
.accordion.open {
height: auto;
}

Никаких подгонов, работает с любым объёмом контента.

Где и как применять
* Аккордеоны, спойлеры, тултипы — везде, где контент меняется динамически (например, описание товара с отзывами).
* Компоненты дизайн-системы: экспандеры, dropdown-меню с серверными данными.
* Поддерживает не только auto, но и fit-content, min-content, max-content — это закрывает кейсы с max-height и width.

Типичная ошибка и trade-off
Ошибка: пытаться применить свойство к родителю при анимировании дочернего блока. interpolate-size нужно вешать именно на тот элемент, который меняет высоту. Trade-off: пока поддержка только в Chrome 129+ и Edge 129+ (Firefox и Safari — в процессе). Для production используй с @supports как прогрессивное улучшение — браузеры без фичи увидят честное auto без анимации, это лучше, чем баг с max-height.

Практический совет
Комбинируй с content-visibility: auto для скрытых панелей — это отложит рендеринг, улучшив производительность при большом количестве элементов. Пример: лендинг с FAQ на 50 вопросов — interpolate-size убирает дёрганье, content-visibility снижает время загрузки.

Вывод:
interpolate-size: allow-keywords позволяет забыть про max-height-хаки и делать предсказуемую анимацию раскрытия блоков с любым контентом, сохраняя стабильность layout в production-интерфейсах.
👍1
Техгиганты увольняют людей — к чему готовиться джунам

Этой весной американский разработчик Oracle уволил почти 30 000 сотрудников в ходе трансформации компании. Председатель совета директоров Ларри Эллисон уверен, что завтра выиграют те, кто сегодня строит инфраструктуру для ИИ, поэтому бизнес инвестирует миллиарды в строительство дата-центров. В 2027 году объем инвестиций в это направление составит $70 млрд, а увольнения позволят высвободить до $12 млрд в год.

Oracle — не единственная технологическая компания, запустившая массовые сокращения. В прошлом году Microsoft уволила 15 000 сотрудников, Meta — 8 000, а Amazon за два года отказалась почти от 50 000 сотрудников. В общей сложности без работы уже остались 165 000 представителей технологического сектора.

Пока тренд особенно заметен на западном рынке труда, но волна, вероятно, дойдет и до России. Предпосылки уже есть: сокращение и избирательность найма, «скрытые» увольнения, заморозка роста заработных плат и другие признаки охлаждения рынка.

Источник
Код я написал за две недели. Продавать его боюсь до сих пор

Три недели назад расширение автора прошло ревью и появилось в Chrome Web Store. С тех пор не было ни анонса, ни поста, ни сообщения людям, которые его ждали. Это уже не первый раз: в мае автор точно так же на месяц пропал в код, лишь бы не заниматься продвижением. В статье разбирается, почему разработчик прячется от собственного продукта, и приводятся замеры, что происходит с цифрами, когда прятаться перестаёшь.

Читать далее
⁣content-visibility: auto — как предотвратить скролл-джампинг и получить детерминированный lazy-rendering

В production-проектах, таких как лендинги, каталоги e-commerce или медиа-сайты с бесконечным скроллом, одна из самых частых ошибок — использование JavaScript для ленивой загрузки контента. Intersection Observer часто приводит к гонкам таймингов: scrollbar меняет длину при подгрузке, что вызывает раздражение пользователя и визуальную регрессию. CSS-свойство content-visibility: auto решает это на уровне браузера, гарантируя стабильный scrollbar без костылей.

Как добиться детерминизма

Браузер с content-visibility: auto резервирует точное место для элемента до его рендеринга. Для этого нужна известная высота — задайте её через contain-intrinsic-size: auto 300px. Это не fallback для старых версий, а обязательное условие: без него блок схлопнется в 0px, и scrollbar «прыгнет» после подгрузки контента. В production для каталога товаров:

.product-card {
content-visibility: auto;
contain-intrinsic-size: auto 350px;
}


Браузер синхронизирует рендеринг при скролле на расстоянии ~1500px от viewport, игнорируя layout и paint для скрытых блоков. Это даёт до 30% ускорения первого отклика без потери стабильности.

Типичная ошибка и её решение

Многие разработчики путают content-visibility: auto с hidden. hidden не резервирует место — используйте его только для временного скрытия блоков, например, в аккордеонах. auto же идеален для шаблонных секций: список товаров, блоки с повторяющимися карточками, секции «рекомендации».

Предупреждение: не применяйте auto для первых 1-2 экранов — это добавляет оверхед, так как браузер всё равно их отрисовывает сразу. Для них используйте content-visibility: visible (по умолчанию).

Практический совет для адаптивности

На мобильных, где скролл может быть плавным, scrollbar не должен «дёргаться». Убедитесь, что высота контейнера задана через contain-intrinsic-size с единицами, не зависящими от viewport (например, px). Избегайте auto в комбинации с min-height: 100vh — это приведёт к скачкам, так как браузер не может предсказать окончательную высоту до рендеринга.

Вывод: content-visibility: auto — это не микро-оптимизация, а стандартный инструмент для детерминированного рендеринга, который решает проблему scrollbar-джампинга без JS-костылей, если правильно настроить размеры.
❤2👍1
⁣CSS box-decoration-break: clone для production-заголовков

Многострочный заголовок с градиентным фоном и border-radius часто выглядит как бракованный: на второй строке скругления исчезают, фон обрывается. Это не баг браузера, а дефолтное поведение box-decoration-break: slice. В production — лендинги, блоги, админки — такая ошибка ломает визуальную цельность компонента.

Как работает box-decoration-break: clone
По умолчанию браузер режет декорации inline-элемента по границам строк. Свойство box-decoration-break: clone заставляет каждую строку отрисовывать padding, background, border-radius и box-shadow как независимый фрагмент. Для Safari нужен префикс -webkit-box-decoration-break: clone. Пример:
.heading {
display: inline;
background: linear-gradient(to right, #ff7e5f, #feb47b);
padding: 0.2em 0.5em;
border-radius: 8px;
box-decoration-break: clone;
-webkit-box-decoration-break: clone;
}

Без clone на второй строке фон плоский, паддинги не срабатывают. С clone каждая строка получает полный набор декораций.

Где это критично в production
Динамические заголовки статей — длина строки плавает, ошибка проявляется непредсказуемо. Градиентные фоны со скруглениями на inline-элементах в UI-библиотеках. Списки с рамкой на каждом пункте-строке. Инлайн-элементы с box-shadow — без clone тень обрезается по краю строки. Поддержка: Chrome, Firefox, Safari, Edge — с префиксом для Safari. IE — нет.

Типичная ошибка и совет
Ошибка: применять к блочным элементам — эффекта ноль, работает только на display: inline или inline-block. Совет: скрести с background-clip: text — тогда каждая строка текстовой маски получит свой фон, что даёт неожиданно чистый визуальный результат для заголовков с прозрачным текстом. Trade-off: увеличивается сложность отладки визуальной регрессии, особенно для адаптивных сеток с переполнением строки.

Вывод: box-decoration-break: clone — обязательное свойство для консистентных inline-декораций в production, предотвращающее визуальные артефакты на многострочных заголовках.
👍1
⁣field-sizing: content — auto-height textarea без scrollHeight хаков

Раньше для авто-высоты textarea приходилось писать скрипты: подписываться на input, сбрасывать height в 0, читать scrollHeight, присваивать обратно — и всё это ломалось при ресайзе окна или в SSR. Теперь в CSS появилось свойство field-sizing: content, которое решает проблему на уровне браузера.

Как это работает

Добавьте одно свойство на textarea или input, и браузер сам подстроит размер под содержимое:

textarea {
field-sizing: content;
min-height: 3em;
max-height: 20em;
}


Для input ширина тоже подгоняется под текст. Никакого JavaScript: scrollHeight и height = 0 больше не нужны.

Подводные камни и совместимость

Пока поддержка только в Chromium 123+ (Chrome, Edge, Opera). Firefox и Safari ещё в разработке. Главное ограничение: если задать явные width или height в px или rem, свойство не сработает. Для textarea лучше сразу отключать стандартный resize, иначе авто-высота конфликтует с ручным ресайзом.

Типичная ошибка: игнорирование фоллбэка

Для production-интерфейсов (формы в кабинетах, SaaS, e-commerce) просто положиться на field-sizing нельзя — в Safari высота останется фиксированной. Практический совет: сделайте постепенное улучшение с фоллбэком через CSS и JS:

textarea {
field-sizing: content;
overflow-y: hidden;
resize: none;
}
textarea:not(:focus) {
height: 3em;
}


Для старых браузеров добавьте полифил на scrollHeight. Так вы получите стабильный layout без визуальной регрессии.

Вывод: field-sizing: content — инженерно чистый способ убрать зависимость авто-высоты от JS, но для production в 2024 году обязательно закладывайте фоллбэк, пока Firefox и Safari не догонят Chromium.
👍3
Как я хакнул рынок труда: пишем свой ИИ-комбайн для автооткликов на HH.ru

Всем привет! Если вы хоть раз искали работу в IT за последний год, то знаете, что рынок беспощаден к новичкам. Нужно откликнуться на сотни вакансий, а в итоге получаешь отказы от роботов. Чтобы пробиться через фильтры HR, нужно под каждую вакансию писать уникальное сопроводительное письмо.

В этой статье я сделаю полный разбор того, как я написал собственного автономного ИИ-агента, который ищет вакансии, фильтрует мусор с помощью локальной нейросети, пишет персонализированные сопроводительные письма и отчитывается мне в Telegram, пока я спокойно занимаюсь своими делами. Я хотел, чтобы скрипт был бесплатным, автономным и не требовал танцев с бубном вокруг платных API.

Читать далее
😁3
⁣Анимация появления без костылей: CSS @starting-style для display: none

Долгое время плавное появление модалок, тултипов или выпадашек с display: none было головной болью. Браузер просто не успевал проиграть анимацию при переключении — элемент уже отображался, а transition не срабатывал. Приходилось городить костыли с setTimeout или requestAnimationFrame. В production это особенно критично для лендингов и кабинетов, где часто встречается всплывашка с плавным появлением.

Как это работает

В CSS появилось решение — @starting-style. Это директива, которая задаёт начальные стили для момента, когда элемент появляется в DOM или display меняется с none на что-то видимое. Элемент висит с display: none. При смене, скажем, на block, браузер сначала применяет стили из @starting-style, а затем переходит к обычным. Если у элемента прописаны transition или @keyframes — анимация проигрывается.

Пример production-кода

.popup {
display: none;
opacity: 0;
transform: scale(0.8);
transition: opacity 0.3s ease, transform 0.3s ease;
}

@starting-style {
.popup {
opacity: 0;
transform: scale(0.8);
}
}

.popup.is-open {
display: block;
opacity: 1;
transform: scale(1);
}


После добавления класса .is-open элемент плавно появляется, а при удалении — скрывается. Где пригодится: модальные окна, тултипы, дропдауны, появление элементов при клике или переключении вкладок.

Типичная ошибка и trade-offs

Если у элемента в обычном состоянии уже прописаны opacity: 0 или transform: scale(0.8), @starting-style может не сработать. Нужно убедиться, что display: none задан явно, иначе браузер проигнорирует директиву. Поддержка: Chrome 117+, Safari 17.2. Firefox пока в разработке. Работает и с transition, и с @keyframes. Можно указывать несколько селекторов внутри @starting-style. Практический совет: тестируй анимацию в Chrome DevTools с ручным переключением display — это помогает отловить сценарии, когда @starting-style не применяется из-за каскада.

Вывод: @starting-style — это инженерный шаг к чистому CSS без JS-обвязки для анимации элементов с display: none, устраняющий визуальную регрессию при монтировании.
👍1
Анатомия парного доклада: как мы собирали «PROvoke» на Analyst Days. Часть 2 — выступление и фидбек

Привет, Хабр! В первой части я рассказывал, как мы с Татьяной Маркиной готовили доклад «Провоок» на Analyst Days — про споры, студию в Краснодаре, логистический ад и идею с кнутом и пряником. А сегодня — второй части: что произошло на сцене, какие роли мы играли, почему корсет так и не вышел в свет, и как один разговор в кулуарах перевернул моё понимание публичных выступлений.

Читать далее
⁣CSS навигация без JS: psevdokoordinaty i otstupy pod hatkoj

Два svojstva - ::target-text i scroll-margin - reshayut problemy yakorej, hash-kollizij i pryachego pod headeron na storone HTML/CSS. Na proizvodstvennykh sajtah s dinamicheskim kontentom ili dizajn-sistemami chasto ignorirujut ony, vyodja JS-koostili i narushayut stabilnost layouta.

Podsvetka fragmenta bez ID
Psewdoelement ::target-text v Chrome 131+ pozvolyaet podsvetit tekst, na kotoryj ssylayetsya cherez #:~:text=. Eto rabotaet bez ykornej i bez skriptov. Naprimer, sdelat' link:
/#:~:text=nuzhnyj+tekst
Ili s kontekstom:
#:~:text=nachalo-,do,-konec
CSS minimalen:
::target-text {
background-color: yellow;
color: black;
}

Minus: net podderzhki v Firefox i Safari. No kak progressivnoe uluchshenie dlya Chromium - otlichno.

Otstup pod hatkoj s scroll-margin
Fixed header pyatatet zagolovok pri perekhode po #id. Ranshe eto trebovalo padding na bloke ili JS-vychisleniya. S scroll-margin yor sam znayet svoj otstup:
.anchor {
scroll-margin-top: 80px;
}

Rabotaet s lyubymi hosh-ssylkami i scrollIntoView(). Dlya dublikatov ID - ne dublikat. Esli vtoraja vstrechaetsya, navigatsiya lomaetsya.

Tipovaya oshibka i trade-off
Chertaya sozdavat' mnogo ykorej v HTML, sozdayut kollizii dublikatov ID. Reshenie: ispolzovat ::target-text dlya podsvetki teksta bez privyazki k ID. No uchyot, eto progressivnoe uluchshenie: dlya polzovatelej v Firefox nichego ne podsvetitsya. Zachem? Dlya medijnyh sajtov, e-commerce, gde nado delegirovat' kontekst v URL.

Prakticheskij sovet
Combo-priem dlya stabilnosti:
.anchor {
scroll-margin-top: 80px;
}
:target {
outline: 2px dashed blue;
}
::target-text {
background: rgba(255, 255, 0, 0.5);
}

scroll-margin i :target mozhno bez straktha v production. ::target-text - kak bonus dlya Chrome, no bez eto ne lomat.

Vyvod:
S zamenoj JS-ykorej na scroll-margin i ::target-text ty poluchish predskazuemyj layout bez bagov ot paddingov i bez poteri dostupnosti.
👎9😁3
Сидеть и работать в корпорации страшно, жизнь-то мимо проходит. Уходить строить бизнес страшно, а вдруг прогорит. Один из вариантов - разрабатывать свой пет-проект по вечерам. Многие успешные компании, например, Twitter, создавались именно так. Это не значит, что ваш проект обязательно заработает миллиарды, но заработать больше, чем в найме, и получить ценный опыт вполне реально.

Перед началом разработки появляется множество вопросов, например:

– Как выбрать идею для пет-проекта?
– Что нужно знать про маркетинг?
– Как запуститься и довести до первых продаж не имея бюджета на рекламу?

В телеграм-канале Твой пет проект, Михаил Табунов делится своим опытом с разработчиками и менеджерами.

Он рассказывает, где искать идею для нового проекта, что нужно знать о маркетинге, как запустить стартап и привлечь первых 10 клиентов, а также о многих других важных вещах.

Подписывайтесь на Твой пет проект получайте пользу от практиков рынка!