В чем техническая и визуальная разница между visibility:hidden и display:none в CSS?
Что проверяют
Понимаете ли вы разницу в участии элемента в раскладке, и знаете ли, как это влияет на доступность и на анимации.
Как отвечать
display: none убирает элемент из потока целиком: он не занимает места, соседи сдвигаются, потомки тоже исчезают независимо от их собственных стилей.
visibility: hidden оставляет элемент в раскладке: место занято, соседи стоят как стояли, элемент просто не отрисован. Потомку при этом можно вернуть видимость через visibility: visible, чего с display не сделать.
Практические следствия:
- события: ни тот, ни другой не кликаются;
- доступность: оба скрывают элемент от скринридера. Если нужно спрятать визуально, но оставить для чтения с экрана, используют приём с абсолютным позиционированием и обрезкой, а не эти свойства;
- анимации и переходы:
visibilityанимируется дискретно, поэтому связкаopacityплюсvisibilityдаёт плавное исчезновение с последующим выключением, аdisplayдо недавнего времени переход обрывал (сейчас это решается черезtransition-behavior: allow-discrete); - измерения: у элемента с
display: noneнет размеров,offsetHeightвернёт ноль. Отсюда классическая проблема измерения скрытого блока; - стоимость: изменение
displayвызывает пересчёт раскладки,visibilityтолько перерисовку, поэтому для часто переключаемых элементов второе дешевле.
Есть и третий вариант: атрибут hidden и content-visibility для отложенной отрисовки больших блоков.
Где спотыкаются
Считают, что visibility: hidden оставляет элемент кликабельным.
Пытаются анимировать display.
Измеряют размеры элемента, скрытого через display: none.
Думают, что визуальное скрытие оставляет элемент доступным скринридеру.