Переполнение и слои
Иногда содержимое больше блока: длинный текст в карточке фиксированной высоты, широкая таблица на узком экране. Свойство overflow решает, что делать с лишним. А когда элементы накладываются друг на друга, z-index определяет, какой из них виден сверху.
Переполнение
Переполнение — ситуация, когда содержимое не помещается в размеры блока. По умолчанию лишнее просто вылезает наружу и налезает на соседей:
<style>
.box { width: 260px; height: 50px; border: 2px solid crimson; margin-bottom: 40px; }
</style>
<div class="box">Этот текст не помещается в блок высотой 50 пикселей. Он продолжается ниже рамки и вылезает за её пределы, налезая на то, что идёт следом.</div>
<p>Следующий абзац</p>Свойство overflow
| Значение | Что происходит с лишним |
|---|---|
visible | Вылезает наружу (по умолчанию) |
hidden | Обрезается и не видно |
auto | Появляется прокрутка, только если нужно |
scroll | Полосы прокрутки есть всегда |
<style>
.box { width: 260px; height: 60px; border: 2px solid seagreen; overflow: auto; }
</style>
<div class="box">Здесь текст тоже не помещается, но у блока появилась своя прокрутка. Прокрутите его колёсиком мыши или пальцем, чтобы дочитать до конца. Вот и конец.</div>Чаще всего нужен auto: прокрутка появится только тогда, когда она действительно нужна.
Прокрутка по горизонтали
overflow-x и overflow-y управляют направлениями по отдельности. Широкую таблицу заворачивают в блок с overflow-x: auto — прокручивается таблица, а не вся страница:
<style>
.scroll { overflow-x: auto; border: 1px solid silver; }
table { border-collapse: collapse; }
td { padding: 6px 12px; border: 1px solid silver; white-space: nowrap; }
</style>
<div class="scroll">
<table>
<tr><td>Январь</td><td>Февраль</td><td>Март</td><td>Апрель</td><td>Май</td><td>Июнь</td><td>Июль</td><td>Август</td><td>Сентябрь</td><td>Октябрь</td></tr>
</table>
</div>Многоточие
Чтобы обрезать строку и поставить в конце «…», нужны три свойства вместе: запрет переноса, обрезка и само многоточие:
<style>
.title { width: 220px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
</style>
<p class="title">Очень длинное название статьи, которое не влезает в одну строку</p>z-index: кто сверху
Когда элементы накладываются, сверху оказывается тот, что идёт позже в HTML. z-index меняет этот порядок: чем больше число, тем выше слой. Он работает у элементов с position, отличным от static, а также у flex- и grid-элементов:
<style>
.stack { position: relative; height: 110px; }
.stack div { position: absolute; width: 100px; height: 70px; padding: 6px; }
.a { top: 0; left: 0; background: lightskyblue; z-index: 2; }
.b { top: 30px; left: 50px; background: gold; z-index: 1; }
</style>
<div class="stack">
<div class="a">z-index: 2</div>
<div class="b">z-index: 1</div>
</div>Голубой блок идёт в HTML раньше, но лежит сверху благодаря большему z-index.
Контекст наложения
Элемент с position и z-index создаёт контекст наложения — отдельную стопку слоёв. Его дети сравниваются только между собой: ребёнок с z-index: 999 не поднимется выше соседа родителя, если сам родитель лежит ниже. Поэтому огромные числа не помогают — нужно смотреть, у кого из предков задан z-index.
Частая ошибка
z-index у элемента без position в обычном потоке не действует. Сколько ни увеличивай число, блок останется снизу:
<style>
.a { background: lightskyblue; padding: 12px; z-index: 10; }
.b { background: gold; padding: 12px; margin-top: -20px; position: relative; }
</style>
<div class="a">z-index: 10, но position нет</div>
<div class="b">Я сверху</div>Добавьте голубому блоку position: relative — и он окажется сверху.