<div class="modal-01__thumb js-modal-01" data-target="modal-target-01"><img src="https://picsum.photos/id/1000/400/200" width="400" height="200" /><span class="modal-01__thumb-icon"></span></div>
<div class="modal-01" id="modal-target-01">
    <div class="modal-01__bg"></div>
    <div class="modal-01__content">
        <div class="modal-01__head">
            <div class="modal-01__heading">見出しが入ります</div>
        </div>
        <div class="modal-01__body">
            <div class="modal-01__text">テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</div>
            <div class="modal-01__img"><img src="https://picsum.photos/id/1000/400/200" width="400" height="200" /></div>
        </div><a class="modal-01__close"></a>
    </div>
</div>
.modal-01__thumb.js-modal-01(data-target='modal-target-01')
  img(src=img, width=width, height=height)
  span.modal-01__thumb-icon
.modal-01#modal-target-01
  .modal-01__bg
  .modal-01__content
    .modal-01__head
      .modal-01__heading #{ heading }
    .modal-01__body
      .modal-01__text #{ text }
      .modal-01__img
        img(src=img, width=width, height=height)
    a.modal-01__close
{
  "heading": "見出しが入ります",
  "text": "テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。",
  "img": "https://picsum.photos/id/1000/400/200",
  "width": 400,
  "height": 200
}
  • Content:
    $BLOCK_NAME: '.modal-01';
    
    // 変数
    $color_primary: #43ceb2;
    $color_white: #fff;
    $color_gray: #ddd;
    $scrollbar_width: 8px;
    @mixin scrollbar() {
      padding-right: $scrollbar_width;
      margin-right: -$scrollbar_width;
      &::-webkit-scrollbar {
        -webkit-appearance: none;
      }
      &::-webkit-scrollbar-thumb {
        background-color: $color_primary;
        border: 0;
        border-radius: $scrollbar_width / 2;
      }
      &::-webkit-scrollbar-track {
        background: $color_gray;
        border-radius: $scrollbar_width / 2;
      }
      &::-webkit-scrollbar:vertical {
        width: $scrollbar_width;
      }
    }
    
    #{ $BLOCK_NAME } {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      z-index: 9999;
      display: none;
      align-items: center;
      justify-content: center;
      font-family: '游ゴシック体', YuGothic, '游ゴシック', 'Yu Gothic',
        'Hiragino Kaku Gothic Pro', 'ヒラギノ角ゴ Pro W3', Meiryo, メイリオ,
        sans-serif;
      &.is-active {
        display: flex;
      }
    
      &__bg {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        background: rgba(0, 0, 0, 0.7);
      }
    
      &__content {
        position: relative;
        z-index: 1;
        display: flex;
        flex-direction: column;
        width: 800px;
        max-width: calc(100% - 24px);
        max-height: calc(100% - 24px);
        padding: 72px 72px 60px;
        background: $color_white;
        border-radius: 24px;
      }
    
      &__head {
        position: relative;
        flex-shrink: 0;
      }
    
      &__heading {
        font-size: 20px;
        font-weight: bold;
      }
    
      &__body {
        @include scrollbar();
        margin-top: 24px;
        overflow: auto;
      }
    
      &__img {
        margin: 36px auto 0;
        text-align: center;
      }
    
      &__close {
        position: absolute;
        top: 24px;
        right: 24px;
        width: 28px;
        height: 28px;
        cursor: pointer;
        transition: all 0.5s;
        &:hover {
          transform: scale(1.1);
        }
        &::before,
        &::after {
          position: absolute;
          top: 0;
          right: 0;
          bottom: 0;
          left: 0;
          width: 3px;
          margin: auto;
          content: '';
          background: $color_primary;
        }
        &::before {
          transform: rotate(45deg);
        }
        &::after {
          transform: rotate(-45deg);
        }
      }
    
      &__thumb {
        position: relative;
        width: 400px;
        cursor: pointer;
      }
    
      &__thumb-icon {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        width: 120px;
        height: 120px;
        margin: auto;
        background: rgba(0, 0, 0, 0.7);
        border-radius: 50%;
        transition: transform 0.3s;
        @at-root #{ $BLOCK_NAME }__thumb:hover & {
          transform: scale(1.1);
        }
        &::before,
        &::after {
          position: absolute;
          top: 0;
          right: 0;
          bottom: 0;
          left: 0;
          margin: auto;
          content: '';
          background: $color_primary;
          transition: transform 0.3s;
          @at-root #{ $BLOCK_NAME }__thumb:hover & {
            transform: rotate(180deg);
          }
        }
        &::before {
          width: 28px;
          height: 4px;
        }
        &::after {
          width: 4px;
          height: 28px;
        }
      }
    }
    
  • URL: /components/raw/modal01/modal01.scss
  • Filesystem Path: src/components/modals/modal01/modal01.scss
  • Size: 3.2 KB
  • Content:
    'use strict';
    
    export const modal01 = () => {
      const modalEls = document.querySelectorAll('.js-modal-01');
      [...modalEls].forEach(el => {
        const modal = new Modal01(<HTMLElement>el);
        modal.init();
      });
    }
    
    class Modal01 {
      el: HTMLElement;
      modalEl: HTMLElement;
      bgEl: HTMLElement;
      closeEl: HTMLElement;
      constructor(el: HTMLElement) {
        this.el = el;
        if (!this.el) return;
        const targetId = this.el.dataset.target;
        this.modalEl = document.getElementById(targetId);
        this.bgEl = this.modalEl.querySelector('.modal-01__bg');
        this.closeEl = this.modalEl.querySelector('.modal-01__close');
      }
    
      /**
       * 初期化
       */
      init(): void {
        if (!this.el) return;
        this.onClickOpenHandler();
        this.onClickCloseHandler();
        this.onClickBgHandler();
      }
    
      /**
       * ウインドウ固定
       */
      fixWindow(): void {
        const scrollBarWidth = window.innerWidth - document.body.clientWidth;
        document.body.style.paddingRight = `${scrollBarWidth}px`;
        document.documentElement.style.overflow = 'hidden';
      }
    
      /**
       * ウインドウ固定を解除
       */
      clearWindow(): void {
        document.body.style.paddingRight = null;
        document.documentElement.style.overflow = null;
      }
    
      /**
       * モーダルを開く
       */
      open(): void {
        this.fixWindow();
        this.modalEl.classList.add('is-active');
      }
    
      /**
       * モーダルを閉じる
       */
      close(): void {
        this.modalEl.classList.remove('is-active');
        this.clearWindow();
      }
    
      /**
       * 開く要素クリック時の挙動
       */
      onClickOpenHandler(): void {
        this.el.addEventListener('click', e => {
          e.preventDefault();
          this.open();
        });
      }
    
      /**
       * 閉じるボタンクリック時の挙動
       */
      onClickCloseHandler(): void {
        this.closeEl.addEventListener('click', e => {
          e.preventDefault();
          this.close();
        });
      }
    
      /**
       * 背景クリック時の挙動
       */
      onClickBgHandler(): void {
        this.bgEl.addEventListener('click', e => {
          e.preventDefault();
          this.close();
        });
      }
    }
    
  • URL: /components/raw/modal01/modal01.ts
  • Filesystem Path: src/components/modals/modal01/modal01.ts
  • Size: 2.2 KB