Search code examples
cssflexboxmargin

How to reduce gap between items in a flex


I'm trying to reduce the gap in between my images that expand when hovered over.

I want it to look like this: expectation

But it currently looks like this: reality

What I currently have:

.container {
  display: flex;
  width: 100%;
  box-sizing: border-box;
  padding: 0 15%;
  height: 100vh;
}

.mask {
  flex: 1;
  clip-path: polygon(40% 0, 60% 0, 30% 100%, 10% 100%);
  transition: 0.2s ease-in;
  gap: 2px;
}

.mask>img {
  width: 100%;
  height: calc(100% - 10vh);
  object-fit: cover;
}

.mask:hover {
  flex: 1 2 5%;
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
<div class="container">
  <div class="mask">
    <img src="https://picsum.photos/id/22/4434/3729">
  </div>
  <div class="mask">
    <img src="https://picsum.photos/id/15/2500/1667">
  </div>
  <div class="mask">
    <img src="https://picsum.photos/id/10/2500/1667">
  </div>
  <div class="mask">
    <img src="https://picsum.photos/id/3/5000/3333">
  </div>
</div>

I tried playing around with margins, using negative values even, but that doesn't seem to be right.

Appreciate any advice, thank you.


Solution

  • clip-path won't make elements become smaller, they are still here but invisible. So the gap you want to reduce is the actual width of elements.

    I have two solutions but both not perfect.

    1. Use clip-path and change width of .mask by flex-basis and flex-grow.

    .container {
      --gap: 2px;
      display: flex;
      justify-content: center;
      width: 100%;
      box-sizing: border-box;
      padding: 0 15%;
      height: 100vh;
      gap: var(--gap);
    }
    
    .mask {
      transition: 0.2s ease-in;
      height: calc(100% - 10vh);
      flex-basis: calc(calc(100% - 3 * var(--gap)) / 4 * 0.6);
      clip-path: polygon(40% 0, 100% 0, 60% 100%, 0 100%);
    }
    
    .mask>img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
    
    .mask:hover {
      flex-grow: 1;
      clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
    }
    <div class="container">
      <div class="mask">
        <img src="https://picsum.photos/id/22/4434/3729">
      </div>
      <div class="mask">
        <img src="https://picsum.photos/id/15/2500/1667">
      </div>
      <div class="mask">
        <img src="https://picsum.photos/id/10/2500/1667">
      </div>
      <div class="mask">
        <img src="https://picsum.photos/id/3/5000/3333">
      </div>
    </div>

    1. Use skewX and avoid .mask overlap by margin. If .container's height will change. You may need js to calculate perfect margin.

    .container {
      --gap: 10px;
      display: flex;
      justify-content: center;
      width: 100%;
      box-sizing: border-box;
      padding: 0 15%;
      height: 100vh;
      gap: var(--gap);
    }
    
    .mask {
      transition: 0.2s ease-in;
      height: calc(100% - 10vh);
      flex-basis: 50px;
      transform: skewX(-10deg);
    }
    
    .mask>img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
    
    .mask:hover {
      flex-grow: 1;
      margin: 0 40px;
      transform: skewX(0);
    }
    <div class="container">
      <div class="mask">
        <img src="https://picsum.photos/id/22/4434/3729">
      </div>
      <div class="mask">
        <img src="https://picsum.photos/id/15/2500/1667">
      </div>
      <div class="mask">
        <img src="https://picsum.photos/id/10/2500/1667">
      </div>
      <div class="mask">
        <img src="https://picsum.photos/id/3/5000/3333">
      </div>
    </div>