Реактивность в CSS
#CSS #JS #Лаборатория_веб_платформы
Реактивность — это когда изменение состояния одной штуки приводит к реакции — изменению состояния других штук. К примеру, если температура воздуха опустилась ниже 0°C, вода замёрзнет и сожмётся.
Реактивность в программировании тоже про реакцию на изменение состояния. Пример:
Число
Такая «ручная реактивность» неоптимальна. Современные JS-фреймворки, например Svelte, умеют в автоматическую реактивность. Для этого «реактивное» значение нужно явно определить, а фреймворк будет автоматически следить за изменением «источников» и пересчитывать состояние:
Нативные переменные в CSS — сразу реактивные «из коробки». Браузер будет следить за их изменением и пересчитывать все зависящие от них значения.
#CSS #JS #Лаборатория_веб_платформы
Реактивность — это когда изменение состояния одной штуки приводит к реакции — изменению состояния других штук. К примеру, если температура воздуха опустилась ниже 0°C, вода замёрзнет и сожмётся.
Реактивность в программировании тоже про реакцию на изменение состояния. Пример:
let doubled = number * 2;
// doubled равно 4
Число
number — это переменная состояния. Удвоенное число doubled «выводится» из этой переменной. Если число меняется, то удвоенное число по умолчанию не «обновится», нужно явно вычислить его ещё раз:
let doubled = number * 2;
// doubled равно 4
number = 5;
doubled = number * 2;
// doubled равно 10
Такая «ручная реактивность» неоптимальна. Современные JS-фреймворки, например Svelte, умеют в автоматическую реактивность. Для этого «реактивное» значение нужно явно определить, а фреймворк будет автоматически следить за изменением «источников» и пересчитывать состояние:
$: doubled = number * 2;
// doubled равно 4
number = 5;
// doubled стало 10
Нативные переменные в CSS — сразу реактивные «из коробки». Браузер будет следить за их изменением и пересчитывать все зависящие от них значения.
</div>
<div class="block modified">
</div>
--number: 20px;
--doubled: calc(var(--number) * 2);
width: var(--doubled);
/* width равно 40px */
}
.block.modified {
--number: 50px;
/* width стало 100px */
}
❤1
Плавный скролл в CSS
#CSS #Лаборатория_веб_платформы
Переход по якорным ссылкам внутри страницы мгновенно «перебрасывает» к нужному месту:
Такое моментальное перемещение может вызвать непонимание, что именно произошло, а это плохой UX. Именно поэтому такой скролл лучше делать плавным, чтобы было видно явно, откуда скролл «выехал» и где остановился.
Нативное решение можно сделать и на JS, и на CSS.
JS-решение
В метод
CSS-решение
Контейнеру со скроллом задаётся свойство
Когда скролл к элементу произошёл, то верхняя часть экрана «упрётся» прямо в блок, к которому произошёл скролл. Чтобы такого «прилипания» не произошло, можно воспользоваться свойством
Таким образом от верхнего края экрана до блока, к которому произошёл скролл, останется «зазор» в 20 пикселей.
#CSS #Лаборатория_веб_платформы
Переход по якорным ссылкам внутри страницы мгновенно «перебрасывает» к нужному месту:
<a class="back-to-top" href="#top">Scroll to Top</a>
Такое моментальное перемещение может вызвать непонимание, что именно произошло, а это плохой UX. Именно поэтому такой скролл лучше делать плавным, чтобы было видно явно, откуда скролл «выехал» и где остановился.
Нативное решение можно сделать и на JS, и на CSS.
JS-решение
В метод
scroll или scrollIntoView передаётся настройка behavior: 'smooth':
backLink.addEventListener('click', (e) => {
// отключаем «перескок» по умолчанию
e.preventDefault();
// плавно скроллим к самому верху страницы
window.scroll({ top: 0, behavior: 'smooth' });
// или скроллим к элементу с id="top"
document.querySelector('#top').scrollIntoView({ behavior: 'smooth' });
});
CSS-решение
Контейнеру со скроллом задаётся свойство
scroll-behavior. Это может быть и вся страница, то есть контейнер самого верхнего уровня — html:
scroll-behavior: smooth;
}
Когда скролл к элементу произошёл, то верхняя часть экрана «упрётся» прямо в блок, к которому произошёл скролл. Чтобы такого «прилипания» не произошло, можно воспользоваться свойством
scroll-margin, которое задаст элементу внешние отступы, учитывающиеся только при скролле.
scroll-margin-top: 20px;
}
Таким образом от верхнего края экрана до блока, к которому произошёл скролл, останется «зазор» в 20 пикселей.
❤1
Когда overflow: hidden не работает
#CSS #Лаборатория_веб_платформы
Есть несколько причин, по которым дочерние боксы элементов, могут «вываливаться» из родительских.
Например, когда в дочернем боксе есть длинное неразрывое слово типа
Или когда дочернему боксу задана ширина или высота явно больше, чем у родительского бокса.
Также если дочернему боксу заданы отрицательное значение
И известный способ ликвидировать эффект «вываливания» — применить свойство
Но
Пример:
В примере бокс
Пример в codepen
#CSS #Лаборатория_веб_платформы
Есть несколько причин, по которым дочерние боксы элементов, могут «вываливаться» из родительских.
Например, когда в дочернем боксе есть длинное неразрывое слово типа
Тунгнафедльсйёкюдль, «вырывающееся» за пределы контейнера.Или когда дочернему боксу задана ширина или высота явно больше, чем у родительского бокса.
Также если дочернему боксу заданы отрицательное значение
margin или элемент абсолютно спозиционирован так, что он выходит за пределы родителя.И известный способ ликвидировать эффект «вываливания» — применить свойство
overflow: hidden. В таком случае части бокса, вышедшие за пределы родительского элемента обрежутся без возможности доскроллить до них вручную.Но
overflow: hidden не всегда обрезает выходящее за пределы содержимое бокса. Есть исключение: абсолютно спозиционированный элемент не будет обрезаться родительским элементом с overflow: hidden, если родитель не является содержащим блоком (containing block), то есть ему не заданы position со значением absolute, relative или fixed.Пример:
<div class="overflow">
<div class="absolute-child">LonglonglonglonglongAbsolute</div>
<div class="static-child">LonglonglonglonglongStatic</div>
</div>
</div>
position: relative;
}
.overflow {
overflow: hidden;
}
.absolute-child {
position: absolute;
}
.static-child {
position: static;
}
В примере бокс
.absolute-child не обрезается по границам бокса .overflow, а при этом .static-child — обрезается, так как он имеет обычное позиционирование.Пример в codepen
❤1
var(--) валидно?
#CSS #Лаборатория_веб_платформы
Представьте себе CSS-код:
Как вы думаете, сработает ли такой код в браузерах, и валидно ли имя кастомного свойства
Ответ: да, в июне 2021 код работает в Chrome, Firefox и Safari. Но имя переменной
Текущий черновик спеки о кастомных свойствах зарезервировал кастомное свойство
Объясню идею авторов спеки.
В CSS есть наследование: значения некоторых свойств (например,
Если эффект наследования нежелателен, его можно отменить ключевым словом
Если же хочется отменить все наследуемые свойства, но при этом не хочется их все перечислять, есть свойство
У свойства
Так вот идея авторов спеки — сделать свойство с именем
Несмотря на то, что это пока черновик спеки, решение было уже обсуждено рабочей группой, то есть скорее всего будет зафиксировано и в будущей рекомендации.
А пока что не используйте
Баг уже починен в Firefox Nightly, а в Chrome багрепорт пока только заведён.
#CSS #Лаборатория_веб_платформы
Представьте себе CSS-код:
--: honeydew;
background-color: var(--);
}
Как вы думаете, сработает ли такой код в браузерах, и валидно ли имя кастомного свойства
--?Ответ: да, в июне 2021 код работает в Chrome, Firefox и Safari. Но имя переменной
-- формально невалидно.Текущий черновик спеки о кастомных свойствах зарезервировал кастомное свойство
-- для будущего использования в CSS.Объясню идею авторов спеки.
В CSS есть наследование: значения некоторых свойств (например,
color или font-size), а также кастомных свойств передаются от родителя к детям:
color: rgb(51, 51, 51);
--gap-size: 10px;
}
p {
/* color тоже будет rgb(51, 51, 51) */
padding: var(--gap-size); /* 10px */
}
Если эффект наследования нежелателен, его можно отменить ключевым словом
initial:
color: rgb(51, 51, 51);
--gap-size: 10px;
}
p {
color: initial; /* значение rgb(0, 0, 0) */
--gap-size: initial; /* значение «пустое» */
}
Если же хочется отменить все наследуемые свойства, но при этом не хочется их все перечислять, есть свойство
all, которое обращается сразу ко всем возможным CSS-свойствам сразу:
color: rgb(51, 51, 51);
font-size: 20px;
}
p {
all: initial;
/*
color: initial, то есть rgb(0, 0, 0)
font-size: initial, то есть 16px
*/
}
У свойства
all есть пара исключений: одно из них — оно не затрагивает кастомные свойства, для сброса их придётся перечислять все до единого:
--prop-1: 123;
--prop-2: red;
--prop-3: 10px;
}
p {
--prop-1: initial;
--prop-2: initial;
--prop-3: initial;
}
Так вот идея авторов спеки — сделать свойство с именем
-- аналогом all только для кастомных свойств. Чтобы можно было написать:
--prop-1: 123;
--prop-2: red;
--prop-3: 10px;
}
p {
--: initial;
/*
--prop-1: initial, то есть значение «пустое»
--prop-2: initial, то есть значение «пустое»
--prop-3: initial, то есть значение «пустое»
*/
}
Несмотря на то, что это пока черновик спеки, решение было уже обсуждено рабочей группой, то есть скорее всего будет зафиксировано и в будущей рекомендации.
А пока что не используйте
var(--), если вдруг эта мысль вам приходила в голову, так как оно вероятно перестанет работать.Баг уже починен в Firefox Nightly, а в Chrome багрепорт пока только заведён.
❤1