Transitionプロパティの練習

目標を読んで、下の回答を見ずに自力で実装してみてください。

1. 基本的なTransition効果

目標

ホバー時に背景色が変化するアニメーションを追加します。

html
<div class="transition-example">ホバーしてください</div>
css
.transition-example {
  padding: 20px;
  text-align: center;
  background-color: #ddd;
  transition: background-color 0.5s ease;
}

.transition-example:hover {
  background-color: #aaa;
}

2. 複数のプロパティにTransition適用

目標

ホバー時に、背景色とサイズが変化するアニメーションを追加します。

html
<div class="transition-multiple">ホバーしてください</div>
css
.transition-multiple {
  padding: 20px;
  text-align: center;
  background-color: #ddd;
  width: 100px;
  transition: background-color 0.5s ease, width 0.5s ease;
}

.transition-multiple:hover {
  background-color: #aaa;
  width: 200px;
}

3. Transition Delayの使用

目標

ホバー時に遅延を持つアニメーションを追加します。

html
<div class="transition-delay">ホバーしてください</div>
css
.transition-delay {
  padding: 20px;
  text-align: center;
  background-color: #ddd;
  transition: background-color 0.5s ease 0.5s; /* 0.5秒遅延 */
}

.transition-delay:hover {
  background-color: #aaa;
}

4. All Transition

目標

全てのプロパティの変更にトランジション効果を適用します。

html
<div class="transition-all">ホバーしてください</div>
css
.transition-all {
  padding: 20px;
  text-align: center;
  background-color: #ddd;
  color: black;
  transition: all 0.5s ease;
}

.transition-all:hover {
  background-color: #aaa;
  color: white;
}

5. カスタムタイミング関数

目標

カスタムタイミング関数を使って、ユニークなアニメーションを作成します。

html
<div class="transition-timing">ホバーしてください</div>
css
.transition-timing {
  padding: 20px;
  text-align: center;
  background-color: #ddd;
  transition: background-color 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55);
}

.transition-timing:hover {
  background-color: #aaa;
}

これらの例を通じて、transitionプロパティの基本から応用までを練習することができます。異なるトランジション効果を試して、どのように動作するかを観察しましょう。

練習問題

練習 1: 右端に三角矢印のあるアコーディオンメニュー

目標

アコーディオンメニューの各セクションをクリックすると、内容が展開され、矢印が回転するアニメーションを追加します。

html
<div class="accordion">
  <div class="accordion-item">
    <div class="accordion-header">
      セクション1
      <span class="arrow">&#9660;</span>
    </div>
    <div class="accordion-content">
      ここに内容1が入ります...
    </div>
  </div>
  <div class="accordion-item">
    <div class="accordion-header">
      セクション2
      <span class="arrow">&#9660;</span>
    </div>
    <div class="accordion-content">
      ここに内容2が入ります...
    </div>
  </div>
</div>
css
.accordion {
  margin: 20px;
  border: 1px solid #ddd;
  border-radius: 2px;
}

.accordion-header {
  padding: 10px;
  background-color: #eee;
  cursor: pointer;
  position: relative;
}

.accordion-header .arrow {
  position: absolute;
  right: 10px;
  transition: transform 0.3s ease;
}

.accordion-content {
  max-height: 0;
  overflow: hidden;
  transition: all 0.3s ease;
  padding: 0 10px;
  background-color: #f9f9f9;
}

.accordion-content p {
  margin: 10px 0;
}

.accordion-item.active .accordion-content {
  max-height: 100px; /* コンテンツに応じて調整 */
  padding: 10px;
}

.accordion-item.active .arrow {
  transform: rotate(180deg);
}
javascript
document.querySelectorAll('.accordion-header').forEach(header => {
  header.addEventListener('click', function() {
    const accordionItem = this.parentElement;
    accordionItem.classList.toggle('active');
  });
});

練習 2: ヘッダー右端に横向き三本線のアイコンがあり、そこをクリックして開閉するドロップダウンメニュー

目標

ヘッダーに配置されたメニューアイコンをクリックすると、ドロップダウンメニューがトランジションを伴って表示されます。

html
<div class="header">
  <p class="menu-icon" onclick="toggleDropdown()">☰</p>
  <div class="dropdown-menu">
    <a href="#">メニュー1</a>
    <a href="#">メニュー2</a>
    <a href="#">メニュー3</a>
  </div>
</div>
css
.header {
  background-color: #2196F3;
  color: white;
  padding: 10px 20px;
  position: relative;
  height: 20px;
  border-radius: 2px;
}

.menu-icon {
  cursor: pointer;
  position: absolute;
  right: 20px;
  top: 0;
  height: 20px;
  line-height: 20px;
  margin: 10px 0;
}

.dropdown-menu {
  position: absolute;
  right: 20px;
  top: 50px;
  background-color: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 2px;
  padding: 0 16px;
  z-index: 1;
  transition: opacity 0.5s ease, padding-top 0.5s ease, padding-bottom 0.5s ease;
  opacity: 0;
}
.dropdown-menu.active {
  opacity: 1;
  padding: 12px 16px;
}
javascript
function toggleDropdown() {
  const dropdown = document.querySelector('.dropdown-menu')
  const classList = []
  dropdown.classList.forEach((c) => classList.push(c))
  if (classList.includes('active')) dropdown.classList.remove('active')
  else {
    window.setTimeout(() => {
      dropdown.classList.add('active')
    }, 100)
  }
  if (classList.includes('display-none')) dropdown.classList.remove('display-none')
  else {
    window.setTimeout(() => {
      dropdown.classList.add('display-none')
    }, 1000)
  }
}

練習 3: 画像のスワイパー(スライダー)

目標

画像が水平方向にスムーズにスライドするスワイパー(スライダー)を作成します。画像は Unsplash からランダムに取得します。

html
<div class="swiper-container">
  <div class="swiper-slide"><img src="https://source.unsplash.com/random/800x450?sig=1" alt="Random Image 1"></div>
  <div class="swiper-slide"><img src="https://source.unsplash.com/random/800x450?sig=2" alt="Random Image 2"></div>
  <div class="swiper-slide"><img src="https://source.unsplash.com/random/800x450?sig=3" alt="Random Image 3"></div>
  <!-- 追加のスライドをここに挿入 -->
</div>
<div class="swiper-button-prev">
  <img src="https://icongr.am/entypo/chevron-left.svg?size=128&color=currentColor" alt="Previous">
</div>
<div class="swiper-button-next">
  <img src="https://icongr.am/entypo/chevron-right.svg?size=128&color=currentColor" alt="Next">
</div>
css
.swiper-container {
  position: relative;
  display: flex;
  overflow-x: hidden;
  scroll-snap-type: x mandatory;
}

.swiper-slide {
  flex: none;
  scroll-snap-align: start;
  margin-right: 10px;
}

.swiper-slide img {
  max-width: 100%;
  height: auto;
  display: block;
}

.swiper-button-prev, .swiper-button-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
  background-color: white;
}

.swiper-button-prev img, .swiper-button-next img {
  width: 24px;
  height: 24px;
}

.swiper-button-prev {
  left: 10px;
}

.swiper-button-next {
  right: 10px;
}
javascript
const container = document.querySelector('.swiper-container');
let slides = document.querySelectorAll('.swiper-slide');
const prevButton = document.querySelector('.swiper-button-prev');
const nextButton = document.querySelector('.swiper-button-next');

let index = 0;

function moveToSlide(n) {
  index = n;
  container.scroll({
    left: slides[n].offsetLeft,
    behavior: 'smooth'
  });
}

nextButton.addEventListener('click', () => {
  index++;
  if (index >= slides.length) {
    index = 0;
  }
  moveToSlide(index);
});

prevButton.addEventListener('click', () => {
  index--;
  if (index < 0) {
    index = slides.length - 1;
  }
  moveToSlide(index);
});