Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Overflow and layers

Sometimes the content is bigger than its block: long text in a card of fixed height, a wide table on a narrow screen. The overflow property decides what to do with the excess. And when elements overlap, z-index decides which of them is seen on top.

Overflow

Overflow is the situation when the content does not fit into the size of a block. By default the excess simply sticks out and runs over the neighbours:

<style>
  .box { width: 260px; height: 50px; border: 2px solid crimson; margin-bottom: 40px; }
</style>
 
<div class="box">This text does not fit into a block 50 pixels tall. It goes on below the frame and sticks out of it, running over whatever comes next.</div>
<p>The next paragraph</p>

The overflow property

ValueWhat happens to the excess
visibleSticks out (the default)
hiddenIs cut off and not visible
autoA scrollbar appears, only when needed
scrollScrollbars are always there
<style>
  .box { width: 260px; height: 60px; border: 2px solid seagreen; overflow: auto; }
</style>
 
<div class="box">This text does not fit either, but the block got its own scrolling. Scroll it with the mouse wheel or a finger to read to the end. And here is the end.</div>

Most often you need auto: the scrollbar appears only when it is really needed.

Horizontal scrolling

overflow-x and overflow-y control the directions separately. A wide table is wrapped in a block with overflow-x: auto — the table scrolls, not the whole page:

<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>January</td><td>February</td><td>March</td><td>April</td><td>May</td><td>June</td><td>July</td><td>August</td><td>September</td><td>October</td></tr>
  </table>
</div>

An ellipsis

To cut a line and put "…" at the end, three properties are needed together: no wrapping, clipping and the ellipsis itself:

<style>
  .title { width: 220px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
</style>
 
<p class="title">A very long article title that does not fit on one line</p>

z-index: who is on top

When elements overlap, the one that comes later in the HTML is on top. z-index changes this order: the bigger the number, the higher the layer. It works on elements whose position is not static, and also on flex and grid items:

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

The blue block comes earlier in the HTML, but lies on top thanks to its bigger z-index.

Stacking context

An element with a position and a z-index creates a stacking context — a separate pile of layers. Its children are compared only with each other: a child with z-index: 999 will not rise above its parent's neighbour if the parent itself lies lower. That is why huge numbers do not help — look at which ancestors have a z-index.

Common mistake

z-index on an element without position in the normal flow has no effect. However big the number, the block stays below:

<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, but no position</div>
<div class="b">I am on top</div>

Give the blue block position: relative — and it ends up on top.

Thanks for reading!

Donate to the site — we work hard for you.