Веб-платформа
2.01K subscribers
5 photos
2 videos
160 links
📍 О том, как всё устроено в веб-платформе и что происходит в индустрии фронтенда

⭐️ Новости, полезные выжимки, находки и напоминания

👨‍💻 Вопросы и предложения @web_platform_support

🔗 juwain.github.io/web-platform-site
Download Telegram
Реактивность в 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 #Лаборатория_веб_платформы

Переход по якорным ссылкам внутри страницы мгновенно «перебрасывает» к нужному месту:

<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 #Лаборатория_веб_платформы

Есть несколько причин, по которым дочерние боксы элементов, могут «вываливаться» из родительских.

Например, когда в дочернем боксе есть длинное неразрывое слово типа Тунгнафедльсйёкюдль, «вырывающееся» за пределы контейнера.

Или когда дочернему боксу задана ширина или высота явно больше, чем у родительского бокса.

Также если дочернему боксу заданы отрицательное значение 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-код:


--: 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