pure cssで作るタブメニュー

input(表示/非表示切り替え) + label(タブ) + div(コンテンツ)

  • input radio チェックの有無でコンテンツの表示非表示を切り替え
  • input + label + divで1セット増減はセットごとに

親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて

つれづれなるまゝに、日暮らし、硯にむかひて、心にうつりゆくよしなし事を、 そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

HTML

<div class="tab_01_wrap">
  <input id="tab_01_1" type="radio" name="tab_group" checked="checked" />
  <label for="tab_01_1">坊ちゃん</label>
  <div class="tab-content"><p>親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて</p></div>
  <input id="tab_02" type="radio" name="tab_group" /><label for="tab_02">徒然草</label>
  <div class="tab-content"><p>つれづれなるまゝに、日暮らし、硯にむかひて、心にうつりゆくよしなし事を、 そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。</p></div>
  <input id="tab_03_1" type="radio" name="tab_group" /><label for="tab_03_1">Lorem ipsum</label>
  <div class="tab-content"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
</div>

CSS

:root {
  interpolate-size: allow-keywords;
}
.tab_01_wrap {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0 2px;

  overflow: hidden;
  outline: rgb(26, 160, 71) 1px solid;
  @media (736px >= width) {
    grid-template-columns: 1fr;
    grid-template-rows: repeat(3, auto);
  }
  & label {
    cursor: pointer;
    font-weight: bold;
    padding: 1em;
    position: relative;
    display: grid;
    place-content: center;
    background-color: #eee;
    transition: all 0.3s ease-out;
    @media (736px >= width) {
      border-top: solid #fff 1px;
    }
    &::after {
      content: "";
      display: inline-block;
      background-color: rgb(26, 160, 71);
      height: 2px;
      position: absolute;
      bottom: 0;
      opacity: 0;
      translate: -100% 0;
      transition: all ease-out 0.3s;
      width: 100%;
    }
    @media (736px >= width) {
      &::before {
        content: "";
        display: inline-block;
        position: absolute;
        top: 50%;
        right: 1em;
        background-color: #dad;
        height: 12px;
        width: 12px;
        clip-path: polygon(0 45%, 45% 45%, 45% 0, 55% 0, 55% 45%, 100% 45%, 100% 55%, 55% 55%, 55% 100%, 45% 100%, 44% 55%, 0 55%);
        translate: 0 -50%;
      }
    }
    &:hover {
      &::after {
        opacity: 1;
        translate: 0 0;
      }
    }
  }

  & input[type="radio"]:checked + label::after {
    opacity: 1;
    translate: 0 0;
  }

  & .tab-content {
    height: 0;
    opacity: 0;
    transition:
      height 0.2s ease-in-out,
      opacity 0.4s ease-out;
    width: 100%;
    @media (737px < width) {
      grid-area: 2 / 1 / 3 / 4;
    }
    & p {
      filter: blur(5px);
      padding: 1em;
      transition: filter 0.3s ease-in-out;
    }
  }

  & input[type="radio"] {
    display: none;
    &:checked {
      & + label {
        color: #009102;
        background-color: #1aa04733;
        @media (736px >= width) {
          order: -2;
          &::before {
            content: none;
          }
        }
        & + .tab-content {
          height: auto;
          opacity: 1;
          order: 1;
          @media (736px >= width) {
            order: -1;
          }
          & p {
            padding-block: 1em;
            filter: blur(0);
          }
        }
      }
    }
  }
}

height: autoでもアニメーションさせる interpolate-size
:root {

interpolate-size: allow-keywords;

}

input(IDで表示非表示切り替え) + nav label(タブ) + div(コンテンツ)

  • input radio チェックの有無でコンテンツの表示非表示を切り替え
  • 項目が増えた場合css側の:checked ~を増やす必要あり

親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて

つれづれなるまゝに、日暮らし、硯にむかひて、心にうつりゆくよしなし事を、 そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

HTML

<div id="tab_03">
  <div class="contents">
    <input type="radio" name="tab-group" id="tab1-trigger" checked />
    <input type="radio" name="tab-group" id="tab2-trigger" />
    <input type="radio" name="tab-group" id="tab3-trigger" />
    <nav class="tab-menu">
      <label for="tab1-trigger">坊ちゃん</label>
      <label for="tab2-trigger">徒然草</label>
      <label for="tab3-trigger">Lorem ipsum</label>
    </nav>
    <div class="tab-content" id="content1"><p>親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて</p></div>
    <div class="tab-content" id="content2"><p>つれづれなるまゝに、日暮らし、硯にむかひて、心にうつりゆくよしなし事を、 そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。</p></div>
    <div class="tab-content" id="content3"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
  </div>
</div>

CSS

#tab_03 {
input[name="tab-group"] {
display: none;
}

& .tab-content {
display: none;
background-color: #fff;
& p {
padding: 1em;
}
}

& #tab1-trigger:checked ~ #content1,
& #tab2-trigger:checked ~ #content2,
& #tab3-trigger:checked ~ #content3 {
display: block;
}

& #tab1-trigger:checked ~ .tab-menu label[for="tab1-trigger"],
& #tab2-trigger:checked ~ .tab-menu label & #tab3-trigger:checked ~ .tab-menu label[for="tab3-trigger"] {
background-color: #fff;
color: #333;
}
& .tab-menu {
display: flex;
gap: 1px;
background-color: #ccc;
& label {
cursor: pointer;
padding: 1em 2em;
background-color: #2a8146;
color: #fff;
transition: all 0.3s ease-in-out;
&:hover {
filter: invert();
}
}
}
}

:target

  • 初期値以外のタブが :target になったら、初期値を非表示に
  • 初期値以外のコンテンツの呼び出し空タグを入れる必要あり
  • urlにID(ハッシュ以降)が表示される

親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて

つれづれなるまゝに、日暮らし、硯にむかひて、心にうつりゆくよしなし事を、 そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

HTML

<div id="tab_02">
  <nav>
    <a href="#tab_02_1">坊ちゃん</a>
    <a href="#tab_02_2">徒然草</a>
    <a href="#tab_02_3">Lorem ipsum</a>
  </nav>
  <div class="contents">
    <div id="tab_02_2" class="target-anchor"></div>
    <div id="tab_02_3" class="target-anchor"></div>
    <div id="tab_02_1" class="tab-content"><p>親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて</p></div>
    <div id="tab2-content" class="tab-content"><p>つれづれなるまゝに、日暮らし、硯にむかひて、心にうつりゆくよしなし事を、 そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。</p></div>
    <div id="tab3-content" class="tab-content"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p></div>
  </div>
</div>

CSS

#tab_02 {
  outline: 1px solid #333;
  & nav {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2px;
    & a {
      color: #fff;
      background-color: #333;
      padding: 1em;
      display: grid;
      place-content: center;
      transition: all 0.3s ease-in-out;
      &:hover {
        filter: invert();
      }
      &:active {
        background-color: #2a8146;
        color: #fff;
      }
    }
  }

  & .tab-content {
    display: none;
    background-color: #fff;
    padding: 1em 2em;
  }

  & #tab_02_1 {
    display: block;
  }

  & :target ~ #tab_02_1 {
    display: none;
  }

  & #tab_02_2:target ~ #tab2-content,
  & #tab_02_3:target ~ #tab3-content {
    display: block;
  }

  /* アンカー用 場所を取らないようにする */
  & .target-anchor {
    position: absolute;
  }
}
CSS

前の記事

includeでパンくずリスト変更