Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между Opacity и Visibility
Opacity и Visibility - это два CSS свойства, которые влияют на видимость элемента, но делают это очень по-разному. Разница между ними критична для понимания CSS и создания правильной верстки.
Быстрое сравнение
| Свойство | Виден ли элемент | Занимает место | Интерактивен | Используется |
|---|---|---|---|---|
opacity: 0 | Нет (прозрачный) | ДА | ДА | скрытие, эффекты |
visibility: hidden | Нет | НЕТ | НЕТ | скрытие, макеты |
display: none | Нет | НЕТ | НЕТ | удаление из потока |
Opacity: прозрачность
Opacity контролирует прозрачность элемента.
.element {
opacity: 1; /* Полностью виден (по умолчанию) */
opacity: 0.5; /* 50% прозрачен */
opacity: 0; /* Полностью невидим */
}
Характеристики Opacity:
-
Элемент остаётся в потоке документа
- Занимает место в макете
- Другие элементы расположены как обычно
-
Элемент остаётся интерактивным
- Можно кликать на него
- Можно фокусировать (табулация) -触发 события
-
Создаёт новый контекст наложения (stacking context)
- Влияет на z-index
Пример Opacity:
<div class="container">
<button>Видимая кнопка</button>
<button style="opacity: 0">Невидимая кнопка (но кликабельная!)</button>
<button>Ещё одна кнопка</button>
</div>
button:nth-child(2) {
opacity: 0;
}
Результат:
- Вторая кнопка не видна
- Но занимает место (видишь промежуток между 1-й и 3-й кнопкой)
- Если кликнешь на её место - кнопка сработает!
// Это всё работает, хотя opacity: 0
const btn = document.querySelector('button:nth-child(2)');
btn.addEventListener('click', () => console.log('clicked!')); // сработает
btn.focus(); // может получить фокус
Visibility: видимость
Visibility контролирует видимость элемента.
.element {
visibility: visible; /* Видим (по умолчанию) */
visibility: hidden; /* Скрыт */
visibility: collapse; /* Только для таблиц */
}
Характеристики Visibility:
-
Элемент НЕ видим, но занимает место
- Не отрисовывается
- Но место зарезервировано
-
Элемент НЕ интерактивен
- Нельзя кликать
- Нельзя фокусировать
- События не работают
-
Не создаёт контекст наложения
Пример Visibility:
<div class="container">
<button>Видимая кнопка</button>
<button style="visibility: hidden">Невидимая кнопка</button>
<button>Ещё одна кнопка</button>
</div>
button:nth-child(2) {
visibility: hidden;
}
Результат:
- Вторая кнопка не видна
- Но занимает место (видишь промежуток между 1-й и 3-й кнопкой)
- Кликнуть на её место нельзя - событие не сработает
// Это НЕ работает, потому что visibility: hidden
const btn = document.querySelector('button:nth-child(2)');
btn.addEventListener('click', () => console.log('clicked!')); // НЕ сработает
btn.focus(); // не может получить фокус
Прямое сравнение
HTML
<div class="example">
<div class="box visible">Видимый</div>
<div class="box opacity-hidden">Opacity: 0</div>
<div class="box visibility-hidden">Visibility: hidden</div>
<div class="box display-none">Display: none</div>
</div>
CSS
.box {
width: 100px;
height: 100px;
margin: 10px;
background: blue;
border: 2px solid black;
}
.visible { /* по умолчанию */ }
.opacity-hidden {
opacity: 0;
}
.visibility-hidden {
visibility: hidden;
}
.display-none {
display: none;
}
Результат в браузере:
[Видимый]
<- место для opacity: 0 (видишь промежуток)
<- место для visibility: hidden (видишь промежуток)
[Display: none]
Ключевые отличия:
- Opacity: 0 - коробка невидима, но место видно (прозрачная коробка)
- Visibility: hidden - коробка невидима, но место видно (пустое место)
- Display: none - коробка и место удалены полностью
Практические примеры
Когда использовать Opacity?
1. Плавное скрытие/показ
.modal {
opacity: 0;
transition: opacity 0.3s ease;
}
.modal.open {
opacity: 1;
}
<div className={cn('modal', { open: isOpen })}>
{/* контент */}
</div>
2. Эффекты при наведении
.card:hover {
opacity: 0.8;
transform: scale(1.05);
}
3. Водяные знаки (watermarks)
.watermark {
opacity: 0.1;
position: fixed;
top: 50%;
left: 50%;
font-size: 100px;
}
4. Отключённые кнопки (if you want them to be clickable)
button:disabled {
opacity: 0.5; /* видишь что это отключено, но может быть кликабельным */
}
Когда использовать Visibility?
1. Скрытие элемента, но сохранение места в макете
.placeholder {
visibility: hidden;
height: 200px; /* место зарезервировано */
}
.placeholder.loaded {
visibility: visible;
}
2. Таблицы (где нужно сохранять место строк)
tr.hidden {
visibility: hidden; /* строка невидима, но место занимает */
}
3. Скрытие элементов в макете, которые могут появиться
.tooltip {
visibility: hidden;
}
.element:hover .tooltip {
visibility: visible;
}
Когда использовать Display: none?
1. Полное удаление элемента из макета
.sidebar {
display: none; /* на мобилях скрыта полностью */
}
@media (min-width: 768px) {
.sidebar {
display: block;
}
}
2. Условное отображение
{isLoggedIn && <UserMenu />} // если false - display: none
Влияние на производительность
Opacity
- Переходы opacity происходят быстро (работает GPU)
- Создаёт слой композиции
- Хорошо для анимаций
/* ХОРОШО для анимаций */
.fade {
animation: fadeOut 0.3s ease;
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
Visibility
- Просто скрывает элемент
- Не создаёт слой композиции
- Не подходит для анимаций (бинарная смена)
/* ПЛОХО для анимаций - меняется мгновенно */
.hide {
animation: hideShow 0.3s ease;
}
@keyframes hideShow {
0% { visibility: visible; }
100% { visibility: hidden; }
}
Доступность (Accessibility)
Opacity: 0
- Элемент остаётся в DOM
- Скринридер его видит
- Клавиатурная навигация работает
- МОЖЕТ быть проблема UX: пользователь видит фокус, но не видит элемент
<!-- ПРОБЛЕМА: видишь фокус на невидимой кнопке -->
<button style="opacity: 0">Невидимая кнопка</button>
Visibility: hidden
- Элемент остаётся в DOM
- Скринридер НЕ видит его
- Клавиатурная навигация НЕ работает
- Лучше для скрытия временного контента
<!-- ХОРОШО: скринридер не видит, фокуса не будет -->
<div style="visibility: hidden">Скрытый контент</div>
Display: none
- Элемента нет в DOM
- Скринридер не видит
- Никаких проблем доступности
- Используй для условного рендера
Таблица выбора
Нужно плавное скрытие? -> opacity
Нужно скрыть, но сохранить место? -> visibility
Нужно полностью удалить? -> display: none
Нужно отключить взаимодействие? -> pointer-events: none
Комбинирование свойств
/* Часто используется вместе */
.disabled-element {
opacity: 0.5;
pointer-events: none; /* запрещает клики */
}
/* Или */
.hidden-but-spaced {
visibility: hidden;
height: 200px; /* занимает место */
}
/* Или */
.fade-out {
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
}
Вывод
Opacity vs Visibility:
- Opacity изменяет прозрачность, элемент остаётся интерактивным
- Visibility скрывает элемент, но место занимает
- Display: none полностью удаляет из потока
Выбирай правильное свойство для своей задачи: