Search code examples
cssflexboxtabscss-gridmargin

How to style elements to overlap per container width (to look like tabs)?


I have a list of items that are styled to display in a row, with each one overlapping the other slightly, to look like tabs. Using only CSS (no JS), I would like the overlap to change responsively to the window width, such that when the window decreases in width, the overlap of each list item becomes greater. How can this be accomplished?

Below is simplified example code. I’m accomplishing the overlap via negative margin, but if there’s a better way, I’m open to it. How can I write a calc() function (or use some other method) to do this? Or should I be using flexbox or grid-template-columns somehow instead?

li {
  background-color  : orange;
  border            : 5px dashed red;
  box-sizing        : border-box;
  display           : inline-block;
  font-size         : 20px;
  height            : 100%;
  line-height       : 30px;
  opacity           : 0.75;
  position          : relative;
  width             : 100px;
  margin            : 0;
  margin-right      : -10px;
  /* 
-15px;      This would make a greater overlap, but I want it to be responsive to the container width.
calc(100%); How can something like that be calculated?
  */
  }
ul {
  background  : brown;
  box-sizing  : border-box;
  font-size   : 0;
  height      : 40px;
  margin      : 0;
  overflow    : hidden;
  padding     : 0;
  position    : relative;
  text-align  : center;
  white-space : nowrap;
  width       : 100%;
  }
<ul>
  <li>item 1</li>
  <li>item 2</li>
  <li>item 3</li>
  <li>item 4</li>
  <li>item 5</li>
  <li>item 6</li>
  <li>item 7</li>
  <li>item 8</li>
</ul>

Here is a Codepen for your sandbox editing if helpful: https://codepen.io/jtheletter/pen/vYveLZJ


Solution

  • something like that, for your calculation?

    ul > li {
      display          : inline-block;
      background-color : whitesmoke;
      border           : 1px solid black;
      border-radius    : 1em;
      width            : 4em;
      height           : 2em;
      line-height      : 2em;
      padding          : 0 .7em;
      margin           : 0 0 0 calc( 4vw - 60px ); /* same as (-60px - ( 4vw * -1 )); */
      list-style       : none;
      }
      
    /* class for testing width values : */
    div { height: 2em; margin: 1em ; }
    div.q1 { width:  4vw;             background: lightblue; }
    div.q2 { width: 60px;             background: yellow;    }
    div.q3 { width: calc(60px - 4vw); background: orangered; }
    <ul>
      <li>item 1</li>
      <li>item 2</li>
      <li>item 3</li>
      <li>item 4</li>
      <li>item 5</li>
      <li>item 6</li>
      <li>item 7</li>
    </ul>
    
    <p><br>tests of width values :</p>
    
    <div class="q1">4vw</div>
    <div class="q2">60px</div>
    <div class="q3">60px&nbsp;-&nbsp;4vw</div>