Search code examples
javascripthtmlcsssassimage-slider

Image slider with diagonal lines separator


I made a 5 image slider container that previews each of the next and previous images. The only problem I have is that I need to make that images are separated by diagonal lines instead of horizontal lines.

This is my code:

const images = document.querySelectorAll(".slider-img")

function clearActiveImage() {
  images.forEach(function(image) {
    image.classList.remove("active-slider");
  });
}

images.forEach(function(image, index) {
  image.onclick = function() {
    event.stopPropagation()
    if (images[index].classList.contains("active-slider")) {
      images[index].classList.remove("active-slider")
    } else {
      clearActiveImage(index)
      images[index].classList.add("active-slider")
    }
  }
})

window.addEventListener("click", () => {
  clearActiveImage()
})
.slider-container {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  height: 150px;
  width: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.slider-main {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  aspect-ratio: 1.5 / 1;
  display: flex;
  overflow: hidden;
  width: 100%;
  height: 100%;
}

.slider-main:has(.img.active) .img:not(.active) {
  filter: grayscale(100%)
}

.slider-img {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  height: 100%;
  width: calc(100% / 5);
  object-fit: cover;
  overflow: hidden;
  border: none;
  transition: all 0.4s cubic-bezier(0.32, 0, 0.67, 0);
  cursor: pointer;
}

.active-slider {
  width: 200%;
}
<div class="slider-container">
  <div class="slider-main">
    <img class="slider-img active-slider" src="https://image.shutterstock.com/image-photo/mountains-fog-beautiful-night-autumn-260nw-1233564241.jpg" alt="">
    <img class="slider-img" src="https://image.shutterstock.com/image-photo/sunset-ruby-beach-260nw-35902396.jpg" alt="">
    <img class="slider-img" src="https://image.shutterstock.com/image-photo/streelights-uttakleiv-village-shine-below-260nw-2333054447.jpg" alt="">
    <img class="slider-img" src="https://image.shutterstock.com/image-photo/twilight-light-over-isolated-sandwood-260nw-2333055437.jpg" alt="">
    <img class="slider-img" src="https://image.shutterstock.com/image-photo/silhouette-young-traveler-watched-star-260nw-1730791102.jpg" alt="">
  </div>
</div>

I already tried using "transform: skewX(-20deg)" but then my whole images get distorted. I am attaching an image of how it should look like. Example


Solution

  • That's the use case of clip-path.

    But this might need to use media query to set the css variable --ms in .slider-img to different value to fit different screen size.

    const images = document.querySelectorAll(".slider-img");
    const clearActiveImage = ({ target }) => images.forEach((image) => image !== target && image.classList.remove("active-slider"));
    images.forEach((image) => image.addEventListener("click", ({ currentTarget }) => currentTarget.classList.toggle("active-slider")));
    window.addEventListener("click", clearActiveImage);
    .slider-container {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      height: 150px;
      width: 50%;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .slider-main {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      aspect-ratio: 1.5 / 1;
      display: flex;
      overflow: hidden;
      width: 100%;
      height: 100%;
    }
    
    .slider-main:has(.img.active) .img:not(.active) {
      filter: grayscale(100%);
    }
    
    .slider-main:has(.active-slider) .slider-img {
      width: calc(100% / 5);
    }
    
    .slider-img {
      --ms: 40px;
      position: relative;
      z-index: var(--i);
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      height: 100%;
      width: calc(100% / 5 + var(--ms));
      flex-shrink: 0;
      object-fit: cover;
      overflow: hidden;
      border: none;
      transition: all 0.4s cubic-bezier(0.32, 0, 0.67, 0);
      cursor: pointer;
      clip-path: polygon(0 0, 100% 0, calc(100% - var(--ms)) 100%, 0 100%);
    }
    
    .slider-img:not(:first-child) {
      margin-left: calc(var(--ms) * -1);
    }
    
    .slider-img:last-child {
      clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
    }
    
    .slider-img.active-slider {
      width: calc(100% / 5 + var(--ms) * 4) !important;
    }
    <div class="slider-container">
      <div class="slider-main">
        <img style="--i: 4" class="slider-img active-slider" src="https://image.shutterstock.com/image-photo/mountains-fog-beautiful-night-autumn-260nw-1233564241.jpg" alt="">
        <img style="--i: 3" class="slider-img" src="https://image.shutterstock.com/image-photo/sunset-ruby-beach-260nw-35902396.jpg" alt="">
        <img style="--i: 2" class="slider-img" src="https://image.shutterstock.com/image-photo/streelights-uttakleiv-village-shine-below-260nw-2333054447.jpg" alt="">
        <img style="--i: 1" class="slider-img" src="https://image.shutterstock.com/image-photo/twilight-light-over-isolated-sandwood-260nw-2333055437.jpg" alt="">
        <img style="--i: 0" class="slider-img" src="https://image.shutterstock.com/image-photo/silhouette-young-traveler-watched-star-260nw-1730791102.jpg" alt="">
      </div>
    </div>