Square

Album

Zoom: 50% | 100% →

Album

Jessica Felicio
pink stare

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Janko Ferlič
brown smile

Vestibulum pretium mauris sit amet sodales sagittis.

Alexander Krivitskiy
gray scaled

Aliquam euismod nisi quis orci sodales, a tincidunt massa luctus.

Shane Devlin
bright white

Vestibulum eget nisi dignissim, placerat purus et, vestibulum quam.

Amir Seilsepour
smiling teeth

Nam tempor nisi sodales erat facilisis, eget mattis nisl hendrerit.

Seth Doyle
snow shade

Pellentesque malesuada lectus vitae metus sollicitudin pretium.

Qasim Sadiq
focused red

Quisque sed nibh commodo, tincidunt magna vitae, fermentum urna.

Julian Wan
orange flower

Phasellus eget ex pulvinar, commodo sapien sed, finibus risus.

Shayan Rostami
crayon blue

Duis vitae mauris sagittis, vulputate dui et, volutpat tellus.

Ahmadreza Najafi
red squid

Aliquam gravida tellus ut dui posuere suscipit.

import=recipes/square/recipes-square-album.vue padding=0 zoom
<template>
  <main>
    <div class="header">
      <h2>Album</h2>

      <nav>
        <button @click="prev" :class="{'active': hasPrev, 'inactive': !hasPrev}">
          <svg viewBox="0 0 24 24">
            <path d="m9.8 12 5 5a1 1 0 1 1-1.4 1.4l-5.7-5.7a1 1 0 0 1 0-1.4l5.7-5.7a1 1 0 0 1 1.4 1.4l-5 5z"/>
          </svg>
        </button>
        <button @click="next" :class="{'active': hasNext, 'inactive': !hasNext}">
          <svg viewBox="0 0 24 24">
            <path d="m14.3 12.1-5-5a1 1 0 0 1 1.4-1.4l5.7 5.7a1 1 0 0 1 0 1.4l-5.7 5.7a1 1 0 0 1-1.4-1.4l5-5z"/>
          </svg>
        </button>
      </nav>
    </div>

    <vue-horizontal ref="horizontal" class="horizontal" :button="false" @scroll-debounce="onScrollDebounce">
      <div class="item" v-for="item in items" :key="item.id">
        <div class="image" :style="{background: `url(${item.img.srcset.sm})`}">
          <div class="overlay">
            <div class="text">{{ item.img.credit.name }}</div>
          </div>
        </div>
        <div class="content">
          <h6>{{ item.title }}</h6>
          <p>{{ item.description }}</p>
        </div>
      </div>
    </vue-horizontal>
  </main>
</template>

<script>
// For convenience sake, I import a collection of images from unsplash.
import {portrait} from '../../../../assets/img'

export default {
  data() {
    return {
      items: portrait.items,
      hasPrev: false,
      hasNext: true,
    }
  },
  methods: {
    prev() {
      this.$refs.horizontal.prev()
    },
    next() {
      this.$refs.horizontal.next()
    },
    onScrollDebounce({hasPrev, hasNext}) {
      this.hasPrev = hasPrev
      this.hasNext = hasNext
    }
  },
}
</script>

<!-- Content Design -->
<style scoped>
.image {
  background-position: center !important;
  background-size: cover !important;
  background-repeat: no-repeat !important;
  padding-top: 100%;
  position: relative;
}

.overlay {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
  background: linear-gradient(345deg, #00000080 0, #00000060 5%, #00000040 20%, #00000000 50%);
}

.overlay .text {
  padding: 12px;
  line-height: 1;
  font-weight: 700;
  font-size: 14px;
  color: white;
}

.content {
  margin-top: 6px;
}

.content h6 {
  font-size: 14px;
  text-transform: capitalize;
  line-height: 1.5;
}

.content p {
  line-height: 1.5;
  font-size: 12px;
  margin-top: 2px;

  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.header {
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

nav {
  display: flex;
  align-items: center;
}

svg {
  width: 24px;
  height: 24px;
  fill: currentColor;
  color: black;
}

button.inactive svg {
  color: #BBB;
}

button {
  padding: 4px;
}

button:focus {
  outline: none;
}

</style>

<!-- Parent CSS (.container) -->
<style scoped>
main {
  padding: 24px;
}

@media (min-width: 768px) {
  main {
    padding: 48px;
  }
}
</style>

<!-- Responsive Breakpoints -->
<style scoped>
.horizontal {
  --count: 2;
  --gap: 16px;
}

@media (min-width: 640px) {
  .horizontal {
    --count: 3;
    --gap: 24px;
  }
}

@media (min-width: 768px) {
  .horizontal {
    --count: 4;
  }
}

@media (min-width: 1024px) {
  .horizontal {
    --count: 5;
  }
}

@media (min-width: 1280px) {
  .horizontal {
    --count: 6;
  }
}

.item {
  width: calc((100% - ((var(--count) - 1) * var(--gap))) / var(--count));
  margin-right: var(--gap);
}
</style>