JSFiddle - React, Tailwind, and code Playground

by FiNGAHOLiC

HTML

<div class="items">
  <div class="item">
    <div class="img"><img src="http://placehold.it/300x300"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque in ipsum id orci porta dapibus.</div>
  </div>
  <div class="item">
    <div class="img"><img src="http://placehold.it/300x300"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque in ipsum id orci porta dapibus.</div>
  </div>
  <div class="item">
    <div class="img"><img src="http://placehold.it/300x300"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque in ipsum id orci porta dapibus.</div>
  </div>
  <div class="item">
    <div class="img"><img src="http://placehold.it/300x300"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque in ipsum id orci porta dapibus.</div>
  </div>
  <div class="item">
    <div class="img"><img src="http://placehold.it/300x300"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque in ipsum id orci porta dapibus.</div>
  </div>
  <div class="item">
    <div class="img"><img src="http://placehold.it/300x300"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque in ipsum id orci porta dapibus.</div>
  </div>
  <div class="item">
    <div class="img"><img src="http://placehold.it/300x300"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque in ipsum id orci porta dapibus.</div>
  </div>
  <div class="item">
    <div class="img"><img src="http://placehold.it/300x300"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque in ipsum id orci porta dapibus.</div>
  </div>
  <div class="item">
    <div class="img"><img src="http://placehold.it/300x300"></div>
    <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing...

SCSS

$breakpoint-mobile: 600px;

$col-count: 4;

$gap-width: 20px;
$gap-count: $col-count - 1;
$gap-width-total: $gap-width * $gap-count;

$items-width: 100vw;

$item-text-font-size: 14px;
$item-text-line-height: 20px;

$item-width: calc((#{$items-width} - #{$gap-width-total}) / #{$col-count});
$item-height: $item-width + $item-text-line-height;

.items {
  background: skygray;
  display: grid;
  grid-auto-flow: dense;
  grid-auto-rows: $item-height;
  grid-column-gap: $gap-width;
  grid-row-gap: $gap-width;
  grid-template-columns: repeat(#{$col-count}, #{$item-width});
  width: $items-width;
  @media screen and (max-width: $breakpoint-mobile) {
    grid-auto-rows: auto;
    grid-template-columns: 1fr;
  }

  // 基本的なアイテムの大きさを設定
  .item {
    background: white;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
    overflow: hidden;
    .img {
      img {
        height: auto;
        width: 100%;
        vertical-align: top; 
      }
    }
    .text {
      font-size: $item-text-font-size;
      line-height: $item-text-line-height;
      overflow: hidden;
      padding: 10px;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }

  // 1, 11, 21...
  // 10, 20, 30...
  .item:nth-child(10n + 1),
  .item:nth-child(10n + 10) {
    grid-column: span 2 / auto;
    grid-row: span 2 / auto;
    @media screen and (max-width: $breakpoint-mobile) {
      grid-column: auto / auto;
      grid-row: auto / auto;
    }
  }

  // 8, 18, 28...
  .item:nth-child(10n + 8) {
    // そのままだと1列に収まってしまうので、カラム番号1を始点とする
    grid-column: 1 / auto;
    @media screen and (max-width: $breakpoint-mobile) {
      grid-column: auto / auto;
    }
  }

  // 9, 19 ,29...
  .item:nth-child(10n + 9) {
    // そのままだと1列に収まってしまうので、カラム番号2を始点とする
    grid-column: 2 / auto;
    @media screen and (max-width: $breakpoint-mobile) {
      grid-column: auto / auto;
    }
  }
}