# カード作成(趣味)

趣味のカードを作成していきます。このページでは、外部ライブラリの使い方を学びます。

写真を趣味として掲載したいと考えますが、その際の表現方法として画像をスライドショーに して、多くの画像を表示する仕組みを用意したいと思います。 CSS のアニメーション機能を使用すれば、スライドショー自体は作成できそうです、 しかし、次・前に移動させるボタンを用意したり、スクロール可能なタッチイベントを取得したりする プログラムを作成するのは、少し敷居が高そうです。 また、画像をスライドショーで表示するというのは、他の Web サイトでも表現されているものを 見かけることがあり、一般的な手法に思えます。 そのため、誰かがすでに作成したものの中から、ライブラリとして利用可能なものがあるかもしれません。

このような場合は、自分の要件を満たすことができそうなライブラリを探してみましょう。 今回の用途で、要件を満たすための選定条件(ライブラリに期待する条件)は以下の通りです。

  • 複数の画像をスライドショーとして表示できる。
  • ある程度カスタムして内容を表示できる。
  • メンテナンスされている。
  • JavaScript のライブラリである。
  • CDN でも提供されている。
  • ドキュメント(説明書)がしっかりしている。

今回は、 Swiper.js (opens new window) というライブラリを使用します。

# 内容

以下に、趣味のカードを構成するすべてのコードを記載しています。 今までとは異なり、JavaScript の記述があります。詳細は以降のセクションで説明しています。

~~/public/index.html










 
 
 
 




































 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 









 
 
 
 
 
 
 
 
 
 
 
 
 
 



<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="robots" content="noindex" />
    <title>Yumi's Portfolio</title>
    <link rel="stylesheet" href="./assets/main.css" />
    <link
      rel="stylesheet"
      href="https://unpkg.com/swiper@8/swiper-bundle.min.css"
    />
  </head>
  <body>
    <img
      src="./assets/decorations/lt.svg"
      alt="背景デザイン画像1"
      class="page-bg-icon page-bg-icon-lt"
    />
    <img
      src="./assets/decorations/rb.svg"
      alt="背景デザイン画像2"
      class="page-bg-icon page-bg-icon-rb"
    />
    <div class="page-cover bg-3 text-dark">
      <h1 class="page-title text-1">Portfolio</h1>

      <div class="card-cover bg-white">
        <h2 class="card-title-cover bg-2 text-light">
          <div class="card-title">English Title</div>
          <div class="card-subtitle">日本語タイトル</div>
          <div class="card-title-line"></div>
        </h2>
        <div class="card-contents">内容</div>
      </div>

      <div style="height: 20px"></div>

      <div class="card-cover bg-white">
        <h2 class="card-title-cover bg-2 text-light">
          <div class="card-title">Self-Introduction</div>
          <div class="card-subtitle">自己紹介</div>
          <div class="card-title-line"></div>
        </h2>
        <div class="card-contents">省略...</div>
        <div class="card-contents">省略...</div>
      </div>

      <div style="height: 20px"></div>

      <div class="card-cover bg-white">
        <h2 class="card-title-cover bg-2 text-light">
          <div class="card-title">Hobby</div>
          <div class="card-subtitle">趣味</div>
          <div class="card-title-line"></div>
        </h2>
        <div class="card-contents">
           旅行と写真を取ることが趣味です。スマートフォンで気軽に撮影したものです。
          パノラマ撮影が気に入っています。
        </div>
        <div
          class="swiper-area"
          style="
            --swiper-navigation-color: #fff;
            --swiper-pagination-color: #fff;
          "
        >
          <div class="swiper-wrapper">
            <div class="swiper-slide">
              <div class="swiper-title">静岡県 熱海市 熱海城前</div>
              <img src="./assets/photos/1.jpg" alt="静岡県 熱海市 熱海城前" />
            </div>
            <div class="swiper-slide">
              <div class="swiper-title">夕方の大学</div>
              <img
                src="./assets/photos/2.jpg"
                alt="夕方の大学"
                style="width: auto"
              />
            </div>
            <div class="swiper-slide">
              <div class="swiper-title">高知県 四万十川 沈下橋</div>
              <img src="./assets/photos/3.jpg" alt="高知県 四万十川 沈下橋" />
            </div>
            <div class="swiper-slide">
              <div class="swiper-title">石川県 能登半島 聖域の岬</div>
              <img src="./assets/photos/4.jpg" alt="石川県 能登半島 聖域の岬" />
            </div>
            <div class="swiper-slide">
              <div class="swiper-title">長野県 軽井沢町 白糸の滝</div>
              <img src="./assets/photos/5.jpg" alt="長野県 軽井沢町 白糸の滝" />
            </div>
            <div class="swiper-slide">
              <div class="swiper-title">新潟県 糸魚川 白馬大仏前</div>
              <img src="./assets/photos/6.jpg" alt="新潟県 糸魚川 白馬大仏前" />
            </div>
          </div>
          <div class="swiper-pagination"></div>
          <div class="swiper-button-prev"></div>
          <div class="swiper-button-next"></div>
        </div>
      </div>

      <div style="height: 40px"></div>

      <footer class="footer-cover bg-2 text-light">
        <div style="height: 4px; background-color: rgba(0, 0, 0, 0.1)"></div>
        <div class="footer-contents">&copy; Yumi's web page.</div>
      </footer>
    </div>

    <script src="https://unpkg.com/swiper@8/swiper-bundle.min.js"></script>
    <script>
      var swiper = new Swiper('.swiper-area', {
        direction: 'horizontal',
        spaceBetween: 30,
        autoplay: { delay: 10 * 1000, disableOnInteraction: false },
        loop: true,
        pagination: { el: '.swiper-pagination' },
        navigation: {
          nextEl: '.swiper-button-next',
          prevEl: '.swiper-button-prev',
        },
      })
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

~~/public/assets/main.css



 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

/* ===== CARD | SELF-INTRODUCTION END ===== */

/* ===== CARD | HOBBY BEGIN ===== */
.swiper-area {
  position: relative;
  width: 100%;
  height: 400px;
  overflow: hidden;
}
.swiper-slide {
  background-color: #212121;
}
.swiper-slide img {
  display: block;
  margin: 0 auto;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.swiper-slide .swiper-title {
  margin-top: 4px;
  position: absolute;
  line-height: 1.5em;
  font-size: 14px;
  font-weight: 500;
  background-color: #00000080;
  color: #ffffffdd;
  padding: 0 0.5em;
}
/* ===== CARD | HOBBY END ===== */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 追記する順番

分量が多いため、いきなりこの量を上から順に書くのは不可能です。 以下は、コーディングを行う大まかな順番です。 実際に自分でコーディングをする機会があれば、以下のような順番で進めることをおすすめします。

  1. Swiper.js のリファレンスを読む
  2. Swiper.js を読み込む
  3. 最小記述で動作確認をする
  4. 実際に使用する画像に置き換える
  5. 仕様を読み設定を変更する
  6. デザインを整える

# 1. Swiper.js のリファレンスを読む

まずはライブラリの使い方を知る必要があります。Get Started (opens new window) 等のページを読み、どのように使うか理解しましょう。これは、 Swiper.js 以外の画像スライドショーライブラリが候補にある場合、その中から自分にあったものを探しているときにも行います。今自分が行っている制作方法やすでに使用中のライブラリ・フレームワークに適用可能なものかどうかを確認します。使いやすそうかどうか、というのも重要なポイントです。

import から始まる書き方は、ビルドを必要とする書き方です。このポートフォリオ制作では、直接 HTML ファイルや CSS に記述している(ビルドしていない)ため、使用できません。CDN から読み込む方法を探してみましょう。このライブラリの場合 Get Started (opens new window)Use Swiper from CDN の項目に記載されています。 また、サンプルコードを読み、使い方も簡単に把握しましょう。

Q. CDN とは?

A. CDN は 「Content Delivery Network(コンテンツデリバリーネットワーク)」の略で、ウェブコンテンツをインターネット経由で配信するために最適化されたネットワークのことです。JavaScript のライブラリは様々なものがありますが、通常ライブラリは NPM (opens new window) で管理されています。しかし、これらは Node.js で使用することが前提となっており、JavaScript で使用するには ビルドが必要になります。ビルドが必要な方法は、最近の開発でも一般的であるため、よく使われますが、今回のポートフォリオ制作では 素の HTML/CSS/JavaScript を学習することが目的のため使用していません。 そのため、ビルド済みのライブラリ(そのまま読み込めるライブラリ)を、選定しました。この際、ソースコードが必要になりますが、このソースコードを高速に安定的に配信する仕組みを提供しているのが CDN という技術です。 CDN を提供しているサービスはいくつかありますが、今回は (Swiper.js のサンプルコードを見たところ、) unpkg.com から提供されるものを使用しています。

CDN を使用しない方法としては、予め、ライブラリのサイトからファイルをダウンロードしておき、例えば ~~/public/assets/swiper のようなディレクトリにいれて参照するという方法があります。 swiper-bundle.min.css をダウンロードして配置した場合は以下のように記述することで、CDN を使用せずとも、 自分のサイト内でライブラリの読み込みが完結します。

<link rel="stylesheet" href="/assets/swiper/swiper-bundle.min.css" />
1

# 2. Swiper.js を読み込む

使い方を読むと、CDN からライブラリを読み込むには、CSS と JavaScript を読み込むと良さそうなことがわかります。

通常、CSS は <head /> の中で呼び出します。JavaScript は <body /> の終了タグの直前に書きます。読み込む部分のみを切り出すと以下のようになります。










 
 
 
 















 



<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="robots" content="noindex" />
    <title>Yumi's Portfolio</title>
    <link rel="stylesheet" href="./assets/main.css" />
    <link
      rel="stylesheet"
      href="https://unpkg.com/swiper@8/swiper-bundle.min.css"
    />
  </head>
  <body>
    ...
    <div class="page-cover bg-3 text-dark">
      <h1 class="page-title text-1">Portfolio</h1>

      ...ページの内容...

      <div style="height: 40px"></div>

      <footer class="footer-cover bg-2 text-light">
        <div style="height: 4px; background-color: rgba(0, 0, 0, 0.1)"></div>
        <div class="footer-contents">&copy; Yumi's web page.</div>
      </footer>
    </div>
    <script src="https://unpkg.com/swiper@8/swiper-bundle.min.js"></script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 3. 最小記述で動作確認をする

ドキュメントを読むと、最低限の記述で動作する、サンプルコードがあります。 Get Started (opens new window)Add Swiper HTML Layout の項目に記載されています。

記述に不要そうな部分(...等)や、理解の妨げになりそうなコメントを外して、思ったとおりに動作するライブラリか確認します。

See the Pen ts-swiper by Insell (@insell824) on CodePen.

もし、今作業している index.html を変更する場合は JavaScript を記述する場所に注意してください。 以下のように、Swiper.js ライブラリ読み込んだあとに さらに <script /> タグを使用してプログラムを書きます。








 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 



      <footer class="footer-cover bg-2 text-light">
        <div style="height: 4px; background-color: rgba(0, 0, 0, 0.1)"></div>
        <div class="footer-contents">&copy; Yumi's web page.</div>
      </footer>
    </div>

    <script src="https://unpkg.com/swiper@8/swiper-bundle.min.js"></script>
    <script>
      var swiper = new Swiper(".swiper", {
        direction: "vertical",
        loop: true,
        pagination: {
          el: ".swiper-pagination",
        },
        navigation: {
          nextEl: ".swiper-button-next",
          prevEl: ".swiper-button-prev",
        },
        scrollbar: {
          el: ".swiper-scrollbar",
        },
      });
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 4. 実際に使用する画像に置き換える

実際に使用する画像に置き換えて、動作や見栄えを確認しましょう。 サンプルをもとに作成すると、以下のような感じになると思います。 サンプルから少しクラス名を変えています。

<div class="swiper-area">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <img src="./assets/photos/1.jpg" alt="静岡県 熱海市 熱海城前" />
    </div>
    <div class="swiper-slide">
      <img src="./assets/photos/2.jpg" alt="夕方の大学" />
    </div>
    <div class="swiper-slide">
      <img src="./assets/photos/3.jpg" alt="高知県 四万十川 沈下橋" />
    </div>
    <div class="swiper-slide">
      <img src="./assets/photos/4.jpg" alt="石川県 能登半島 聖域の岬" />
    </div>
    <div class="swiper-slide">
      <img src="./assets/photos/5.jpg" alt="長野県 軽井沢町 白糸の滝" />
    </div>
    <div class="swiper-slide">
      <img src="./assets/photos/6.jpg" alt="新潟県 糸魚川 白馬大仏前" />
    </div>
  </div>
  <div class="swiper-pagination"></div>
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 5. 仕様を読み設定を変更する

標準の動作でも良いですが、このライブラリは高機能のため、いろいろなオプションがあります。ドキュメントを読み、設定をカスタムしましょう。

このライブラリの場合は API (opens new window) というページに様々なオプションが記載されています。(ページの分量が多いため、Ctrl+ F ページ内検索を適宜使用すると便利です。)

今回は、以下のように変更しました。


 
 
 
 
 
 
 
 
 
 
 




    <script>
      var swiper = new Swiper(".swiper-area", {
        direction: "horizontal",
        spaceBetween: 30,
        autoplay: { delay: 10 * 1000, disableOnInteraction: false },
        loop: true,
        pagination: { el: ".swiper-pagination" },
        navigation: {
          nextEl: ".swiper-button-next",
          prevEl: ".swiper-button-prev",
        },
      });
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  • 基準となる範囲は .swiper-area
  • direction: 方向は horizontal
  • spaceBetween: スライドとスライドの間に 30 の余白
  • autoplay: 自動的に次のスライドにする設定、インターバル 10 秒(10,000 ミリ秒)
  • loop: 繰り返しを有効化 true

# 6. デザインを整える

ライブラリの使用方法に慣れてきたら、より自分の Web ページに合うようにデザインを整えていきます。

# 幅の狭い画像を調整する

image

1 つだけ正方形の画像があります。この画像を配置すると、引き伸ばされてきれいに見えません。 試行錯誤したところ、以下のようにスタイルを適用することで収まるように配置されました。







 






<div class="swiper-area">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <img src="./assets/photos/1.jpg" alt="静岡県 熱海市 熱海城前" />
    </div>
    <div class="swiper-slide">
      <img src="./assets/photos/2.jpg" alt="夕方の大学" style="width: auto" />
    </div>
    <div class="swiper-slide">
      <img src="./assets/photos/3.jpg" alt="高知県 四万十川 沈下橋" />
    </div>
    ...
1
2
3
4
5
6
7
8
9
10
11
12










 


 
 
 
 
 













/* ===== CARD | SELF-INTRODUCTION END ===== */

/* ===== CARD | HOBBY BEGIN ===== */
.swiper-area {
  position: relative;
  width: 100%;
  height: 400px;
  overflow: hidden;
}
.swiper-slide {
  background-color: #212121;
}
.swiper-slide img {
  display: block;
  margin: 0 auto;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.swiper-slide .swiper-title {
  margin-top: 4px;
  position: absolute;
  line-height: 1.5em;
  font-size: 14px;
  font-weight: 500;
  background-color: #00000080;
  color: #ffffffdd;
  padding: 0 0.5em;
}
/* ===== CARD | HOBBY END ===== */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

.swiper-slide img { width: 100%; } という設定で、画像に対して 横 100%に表示している ところを、 2.jpg のみ 要素の Style に直接指定して、width: auto とすることで、横いっぱいにならないように上書きしています。

image

また、.swiper-slide { background-color: #212121; } として、背景に暗い色を指定しました。

image

# ボタンの色を変える

デフォルトの青い色から白い色に変えるは、Swiper の対象となる要素に対して以下のような Style を適用するといいそうです。



 
 
 
 










<div
  class="swiper-area"
  style="
    --swiper-navigation-color: #fff;
    --swiper-pagination-color: #fff;
  "
>
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <div class="swiper-title">静岡県 熱海市 熱海城前</div>
      <img src="./assets/photos/1.jpg" alt="静岡県 熱海市 熱海城前" />
    </div>
    ...
  </div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

image

# タイトルを作る

image

今回の場合は、画像左上にタイトルが表示されるようにしました。










 



 



 



 



 



 








<div
  class="swiper-area"
  style="
    --swiper-navigation-color: #fff;
    --swiper-pagination-color: #fff;
  "
>
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <div class="swiper-title">静岡県 熱海市 熱海城前</div>
      <img src="./assets/photos/1.jpg" alt="静岡県 熱海市 熱海城前" />
    </div>
    <div class="swiper-slide">
      <div class="swiper-title">夕方の大学</div>
      <img src="./assets/photos/2.jpg" alt="夕方の大学" style="width: auto" />
    </div>
    <div class="swiper-slide">
      <div class="swiper-title">高知県 四万十川 沈下橋</div>
      <img src="./assets/photos/3.jpg" alt="高知県 四万十川 沈下橋" />
    </div>
    <div class="swiper-slide">
      <div class="swiper-title">石川県 能登半島 聖域の岬</div>
      <img src="./assets/photos/4.jpg" alt="石川県 能登半島 聖域の岬" />
    </div>
    <div class="swiper-slide">
      <div class="swiper-title">長野県 軽井沢町 白糸の滝</div>
      <img src="./assets/photos/5.jpg" alt="長野県 軽井沢町 白糸の滝" />
    </div>
    <div class="swiper-slide">
      <div class="swiper-title">新潟県 糸魚川 白馬大仏前</div>
      <img src="./assets/photos/6.jpg" alt="新潟県 糸魚川 白馬大仏前" />
    </div>
  </div>
  <div class="swiper-pagination"></div>
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37




 














 
 
 
 
 
 
 
 
 
 


/* ===== CARD | SELF-INTRODUCTION END ===== */

/* ===== CARD | HOBBY BEGIN ===== */
.swiper-area {
  position: relative;
  width: 100%;
  height: 400px;
  overflow: hidden;
}
.swiper-slide {
  background-color: #212121;
}
.swiper-slide img {
  display: block;
  margin: 0 auto;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.swiper-slide .swiper-title {
  margin-top: 4px;
  position: absolute;
  line-height: 1.5em;
  font-size: 14px;
  font-weight: 500;
  background-color: #00000080;
  color: #ffffffdd;
  padding: 0 0.5em;
}
/* ===== CARD | HOBBY END ===== */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

.swiper-title に対して position: absolute; を指定しています。 position は CSS のプロパティで、文書内で要素がどのように配置されるかを設定します。

position: absolute; は、もともと配置される予定の領域を削除して配置します。 基準となる位置は、含まれている要素(祖先を含む親要素)に対して position: static; 以外が指定されている最初の親要素になります。

そのため、.swiper-area { position: relative; } を指定して .swiper-area.swiper-title の基準位置になるようにしています。