Последние три бага в моей практике оказались связаны с тем, что где-то в глубине стеков технологий лежат специфичные правила рендеринга. Сегодня — подборка реальных кейсов, которые заставляют перепроверять, казалось бы, базовые вещи.
Когда скроллбар становится дизайн-системой
WebKit даёт кастомизировать скроллбары через префиксные псевдоэлементы, но составные части оказываются неожиданно сложными:
body::-webkit-scrollbar {
width: 1em; /* толщина всей конструкции */
}
body::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); /* фон трека */
}
body::-webkit-scrollbar-thumb {
background-color: darkgrey;
outline: 1px solid slategrey; /* сам бегунок */
}
На практике:
outlineна thumb работает как border, но не влияет на геометриюbox-shadowна track — единственный способ сделать “вдавленный” эффект- В Firefox эти стили просто проигнорируются, нужен
scrollbar-colorиscrollbar-width
Флексбокс vs. скролл: битва в Safari
Типичный сценарий: контейнер с display: flex и overflow: scroll вдруг перестаёт скроллиться в Safari. Причина — внутренняя оптимизация WebKit, которая считает, что флекс-дети не могут быть скроллящимися областями.
Решение нашлось на Stack Overflow:
- Переносим
overflow: scrollна внутренний контейнер - Убеждаемся, что этот контейнер — не флекс-элемент
- Если нужно сохранить структуру, добавляем промежуточный
div-враппер
/* Так не сработает */
.flex-container {
display: flex;
overflow: scroll; /* Safari проигнорирует */
}
/* А так — да */
.scroll-host {
overflow: scroll;
}
text-transform: магия и ограничения
Казалось бы, что может пойти не так с преобразованием регистра? Но и здесь есть нюансы:
.lowercase { text-transform: lowercase } /* ВСЁ в нижний */
.uppercase { text-transform: uppercase } /* ВСЁ в верхний */
.capitalize { text-transform: capitalize } /* Первая буква каждого слова */
Подвохи:
capitalizeне делает слово title-case — он трогает только первую букву- В некоторых языках (например, турецком)
iпревращается не вI, а вİ - Если применять к
::first-letter, поведение может отличаться между браузерами
React.cloneElement: когда пропсы не доходят до детей
Вот типичный кейс из мира React: у вас есть компонент-контейнер, и нужно прокинуть пропсы всем детям, даже если они переданы как undefined. Нативный {children} не сработает — нужен клон:
// Вместо этого:
<Container>{children}</Container>
// Делаем так:
React.cloneElement(this.props.children, {
loggedIn: this.state.loggedIn
})
Особенности:
- Работает только с одним ребёнком (для массивов нужен
React.Children.map) - Клонирование создаёт новые элементы, что может влиять на производительность
- В новых версиях React можно использовать Context API для подобных сценариев
Выводы для практики
- Safari — это отдельная вселенная: любые взаимодействия flexbox и overflow требуют тестирования
- Префиксные псевдоэлементы — не временное решение, а часть спецификации
- Кастомные скроллбары всё ещё остаются хаками, несмотря на десятилетия развития CSS
- React-паттерны вроде cloneElement постепенно уступают место контекстам и хукам
Что попробовать: если ещё не сталкивались с проблемой flex + scroll в Safari, создайте тестовый пример — это один из тех багов, который проще предупредить, чем искать в продакшне.
Источник: https://dev.to/ld8/daily-notes-4lde