CSS フォトギャラリー
スタイルシートCSS を用いたフォトギャラリーのサンプルをご紹介します。
※サンプル表示はスマホのように狭い画面では正常に表示されないものもあります。
Contents
記録付きフォトギャラリー
画像に日付、タイトル、メモなどのコメントを自由に設定できるシンプルなフォトギャラリーです。アルバムや実験記録、カタログなどに応用できます。
最近のモダンブラウザ(IE10〜、Chrome、Firefox、Opera、Safari)ではflex
プロパティで、IE9 以前は float
プロパティで動作するシンプルなレスポンシブフォトギャラリーと、
テーブルレイアウト display: table
プロパティを使用してある程度レスポンシブに対応したサンプルです。(2016年 2月)
flex、float
併用による記録付きフォトギャラリー
下図のように、上から「タイトル」、「画像」、「コメント」、「日付」を表示するボックスを並べ、画面幅に応じて3列から2列、1列と変化するものです。
HTML
定義リスト dl 要素のボックスを、最近のモダンブラウザでは flex プロパティで、IE9 以前は float プロパティで配置するようにします。順不同リストの ul、li でも可能ですが、ドキュメント構造に適合するように dl 要素にしています。 そのボックス内を dt 要素でタイトルを表示し、dd 要素で画像、コメント文、撮影日など項目別に記述します。
dd タグに class を設定しておくことで、それらの項目別にスタイルを決められます。コメント欄の大きさはテキスト内容がその範囲内に収まるようにします。
<div id="gallery">
<dl>
<dt>エビネ</dt>
<dd><img src="./img/f1.gif" alt="エビネ"</dd>
<dd class="comment">根に節が多く、海老の背に似ていることからエビネと
呼ばれています。</dd>
<dd class="date">4月29日</dd>
</dl>
上記と同じように<dl>〜</dl>を画像の枚数分ならべます。(省略)
</div>
サムネイル画像を並べ拡大表示したいときは、次のように<a>
タグでリンクします。
<dd><a href="元の原寸画像パス"><img src="縮小画像パス"></a></dd>
CSS
フレキシブルボックスレイアウト display: flex
は、空き領域を柔軟に利用してマルチスクリーンに対応できますが、未対応の IE9 以前に対しては、float
で対応します。
通常、下記のような IE5〜IE9 だけに機能する IE 独自機能の「条件付きコメント」を HTML 内に記述して CSS を切替えますが、IE10 以降のモダンブラウザは、子要素の flex アイテムに float 指定があれば width 指定も含めて無視します。
一方、flex
未対応の場合は float
も同時に設定しているので float
が機能します。したがって CSS を区別しなくてもよいので条件付きコメントは使用しません。
【 IE10 以降と IE 以外のブラウザに CSS を設定する条件付きコメント例 】
<!--[if !IE]><!-->
<link rel="stylesheet" href="./non-ie.css" type="text/css">
<!--<![endif]-->
IE9 以下では、伸縮せずそのままのサイズで折り返します。
【 厄介な最後の行 】
flex
による表示は、空きスペース全体に折り返し表示されるので最後の行のボックスサイズは横長になります。上段と同じサイズにしたい場合、下記のように擬似要素を使用して空きスペース制限用ボックスを flex
アイテムとして画像ボックスと同じように領域だけのボックスを設置することで上段と同じサイズで折り返しできる場合があります。
(2019年 5月 追加修正)
#gallery:after {
content: "";
flex: 140px;
margin-right: 5px;
display: block;/* IE10 対策 */
}
【 最後の行ボックスを上段と同じサイズにする対策 】
上記のように空きスペース制限用ボックスを flex
アイテムとして領域だけのボックスを設置し最後の行ボックスを上段と同じサイズにする場合の条件つき対応策です。
- 最後の行が折り返したとき、上段のカラム数が 3 カラムか、4 カラムになるようにブレークポイント
flex-basis
値を調整します。 - 上段のカラム数が 3 カラムのときは、擬似要素の
flex
パラメータとマージン値を画像ボックスと同じにします。 - 上段のカラム数が 4 カラムのときは、画像ボックス 2 個分になるように、
flex
パラメータとマージンを 2 倍にします。例えば、上記の例では、flex: 2 280px; margin-right: 10px;
になります。 - 2、3 項のどちらかの方法で対応します。
#gallery {
font-family: Arial, "MS Pゴシック", sans-serif;
max-width: 670px; /* 可変幅にします。*/
margin: 0 auto;
display: flex; /* 親要素 flex コンテナ */
flex-flow: wrap; /* 左から右に折り返し */
}
#gallery dl {
flex: 140px; /* IE10〜モダンブラウザ対応 */
float: left; /* IE9 以前のブラウザ対応 */
width: 160px; /* float は必須 */
margin-right: 5px;
margin-bottom: 1em;
padding: 0;
font-size: 14px;
background-color: #ffd;
border:1px solid #933;
text-align: center; /* 画像を中心配置 */
box-sizing: border-box;
}
#gallery:after { /* 最後の行の折り返しスペース制限 */
content: "";
flex: 140px;
margin-right: 5px;
display: block;/* IE10 対策 */
}
#gallery dl img {
border: 0;
width: 100%;
height: auto;
}
#gallery dt {
margin: 0;
padding: 2px;
font-weight: bold;
text-align: center;
}
#gallery dd {
margin: 0;
padding: 0;
}
#gallery dd.comment {
height: 5em; /* コメント文字数により調整 */
padding: 2px 5px;
line-height: 1.3;
text-align: left;
}
#gallery dd.date {
padding: 3px;
margin: 0;
text-align: right;
background-color: #fdd;
}
flex、float 併用による記録付きフォトギャラリー表示
CSS Grid レイアウトを使用する
Flexbox を使用した場合に上記のように最後の行が横長になりますが、IE 以外のモダンブラウザで使用可能になった CSS Grid レイアウトに変更した例です。カラム数に無関係に対応できます。(2019年 5月)
次のように minmax
関数の最小値をマージンを加えた値(140px + 5px)にし、flex
関連を削除します。他はそのままで置き換えられます。
#gallery {
font-family: Arial, "MS Pゴシック", sans-serif;
max-width: 670px;
margin: 0 auto;
display: flex;
flex-flow: wrap;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(145px, 1fr));
}
#gallery dl {
flex: 140px;
float: left;
width: 160px;
margin-right: 5px;
margin-bottom: 1em;
padding: 0;
font-size: 14px;
background-color: #ffd;
border:1px solid #933;
text-align: center;
box-sizing: border-box;
}
#gallery:after {
content: "";
flex: 140px;
margin-right: 5px;
display: block;
}
display: table
による記録付きフォトギャラリー
HTML は基本的に上記と同じでテーブルレイアウトによるフォトギャラリーです。画面幅に応じて折り返しませんが、画像は縦横同一比で伸縮するリキッドタイプです。
CSS
幅を%指定することでリキッドタイプにしたテーブルレイアウト CSS で、上記 flex
使用と異なる部分です。
#gallery-tbl {
font-family: Arial, "MS Pゴシック", sans-serif;
max-width: 670px; /* 可変幅にします。*/
width: 100%; /* 幅 % 指定(必須) */
margin: 0 auto;
display: table;
table-layout: fixed;
border-collapse: separate;/* ボーダーを分離(省略可)*/
border-spacing: 5px 1em; /* 左右 5px、上下 1em */
}
.tbl-row {
display: table-row;
}
#gallery-tbl dl {
display: table-cell;
padding: 0;
font-size: 14px;
background-color: #ffd;
border:1px solid #933;
text-align: center; /* 画像を中心配置 */
vertical-align: middle;
}
img {
max-width: 100%; /* 画像の伸縮 */
height: auto;
}
@media screen and (max-width: 420px) {
#gallery-tbl dl { /* 狭い画面対応(省略可)*/
font-size: 12px;
}
}
display: table による記録付きフォトギャラリー表示
参考
マルチカラム columns
によるレスポンシブフォトギャラリー
マルチカラムレイアウト columns
プロパティを使用したシンプルなレスポンシブフォトギャラリーです。画面幅に応じて横方向を均等に分割して画像を敷き詰めます。表示面を最大限利用することで、
比較的多くの画像を大きなサイズでレスポンシブ対応することができます。(2016年 4月)
前記の flex
は、縦方向を最も高いボックスに揃えて横方向も柔軟に整形しますが、columns
プロパティは、均等に分割して左から右に流し込むように動作します。
HTML
ボックスのなかに画像を並べるだけです。ここでは画像にコメントを重ね書きするため、親ブロック p
のなかに画像を入れて、それぞれの文字位置を決めてから span
で名前や簡単なコメントを後に続けています。
<div id="gallery" class="org">
<p><img src="./img/eyes0345.jpg" alt="オオムラサキ">
<span class="name">オオムラサキ</span></p>
<p><img src="./img/eyes0270.jpg" alt="梅">
<span class="name">梅</span></p>
以下、同じように画像を並べます。(省略)
</div>
CSS
このサンプルでは画面幅の狭いスマホでもきれいに見えるようにしています。メディアクエリで分割制御する必要はありません。
【 カラム幅の設定 】
カラム幅の設定を小さくすれば、分割数が増えて画像も小さくなり可視範囲も広くなり、ブレークポイントが増えます。どのように決めるかが悩ましいところです。いくつか試してみると画面幅(320px)の80% 前後にすると比較的広い範囲で 320px 前後の画像幅になるようなので 260px に設定しています。
マルチカラムレイアウトのアルゴリズムから、設定するカラム幅に対する表示カラム幅とカラム数が、画面サイズでどのように変化するかをシミュレーションできます。下記の参考欄のページを参考にしてください。
* { margin: 0; padding: 0;}
body {
font-family: Arial, sans-serif;
background-image: url('./img/w-ruins16.gif');
background-repeat: repeat;
}
#gallery {
columns: 260px;
column-gap: 10px;
margin: 10px;
}
#gallery img {
width: 100%;
height: auto;
padding: 8px; /* 写真外枠を白フチに */
background-color: #fff;
margin-bottom: 10px;
box-sizing: border-box;
box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.7);
}
/* コメントを画像に重ねる CSS */
.org p {
display: inline-block;
width: 100%;
position: relative;/* 画像位置を基準に */
line-height: 1;
}
.name {
position: absolute;
top: 0.8em; /* テキストの始点 */
left: 0.8em;
color: orange;
font-weight: bold;
text-shadow: 0px 3px 4px #000;
z-index: 1;/* position: absolute 指定なので */
}
参考
フレキシブル flex
によるレスポンシブフォトギャラリー
フレキシブルボックスレイアウト flex
プロパティを使用したレスポンシブフォトギャラリーです。サイズの異なる画像を回転させて散らかしたように配置した例と、画像の高さを固定して格子状に配置し画像をトリミング伸縮した例をご紹介します。
散らかしタイプフォトギャラリー
ボックスシャドウを加えて少し回転させ適当に重なるようにしているので、写真を散らかしたようになります。(2016年 4月)
HTML
<div id="gallery">
<p class="pic-r1"><img src="./img/eyes0345.jpg" alt="オオムラサキ"></p>
<p class="pic-r2"><img src="./img/eyes0270.jpg" alt="梅"></p>
以下、同じように画像を並べます。(省略)
</div>
CSS
flex
プロパティについては、下記の付記欄のページを参考にしてください。ベンダープレフィックスは不要です。傾斜角度や z-index
は、適当な値にしています。
【 flex
アイテムは z-index
が機能する 】
flex
アイテムとして並べる写真は、position
が static
であっても、z-index
値により、重ね合わせ順序を変えられます。更に、order
プロパティで描画順を変更することでも影響します。
* { margin: 0; padding: 0; }
body {
font-family: Arial, sans-serif;
background-image: url('./img/w-stone14.jpg');
background-repeat: repeat;
}
#gallery {
width: 80%;
margin: 1em auto;
display: flex;/* 親要素 flexコンテナ */
flex-flow: wrap;/* 折り返し */
}
#gallery img {
width: 100%;
height: auto;
border: none;
max-width: 380px;/* 大きくなり過ぎないように */
margin: 1em 0;
padding: 8px; /* 写真外枠を白フチに */
background: #fff;
box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.7);
}
#gallery p {
flex: 260px;/* 子要素 flexアイテム */
}
.pic-r1 {
z-index: 2;
transform: rotate(-10deg);
}
.pic-r2 {
z-index: 5;
transform: rotate(15deg);
}
.pic-r3 {
z-index: 3;
transform: rotate(5deg);
}
.pic-r4 {
z-index: 5;
transform: rotate(-3deg);
}
.pic-r5 {
z-index: 5;
animation: animation-1 4s infinite ease 1s both;
} /* アニメでお遊びです */
@keyframes animation-1 {
from {
transform: rotate(8deg);
}
to {
transform: rotate(-15deg);
}
}
マルチカラム columns
にした場合
マルチカラム columns:*
でもそのまま置き換えできますが、マルチカラムの場合、 transform: rotate
で画像に傾斜をつけたことで、ブレークポイント付近のカラムボックスからはみ出したエッジ部分は表示されません。
Firefox だけは、はみ出して表示されます。カラム内ボックスのマージンまたはパディングで回避可能ですが、その分画像の表示サイズは小さくなります。
格子タイプフォトギャラリー
異なるサイズの写真を高さを揃えて格子状に配置し object-fit: cover;
プロパティでトリミング伸縮したシンプルなレスポンシブフォトギャラリーです。(2018年 10月)
HTML
<div id="gallery">
<p><img src="./img/eyes0345.jpg" alt="オオムラサキ"></p>
<p><img src="./img/eyes0270.jpg" alt="梅"></p>
以下、同じように画像を並べます。(省略)
</div>
CSS
この例では画像の高さを 250px に固定しています。この高さ指定により表示画像の大きさがきまります。縦長の画像は小さくなるので見やすさの点で、前記マルチカラムフォトギャラリーよりは劣ります。また、画像はトリミングプロパティ object-fit: cover;
で縦横等比例でトリミング加工表示します。
IE は未対応です。
厄介な最後の行
問題は最後の行で起こります。最後の行に画像がほとんどない場合は、横長に行全体に伸張します。このようなときそれらの画像を大きく伸張させないようにする必要があります。
それで下記のように、最後の行の最後に空の flex アイテムを追加し強制的に適度に大きくすることで、最後の行のスペース配分量を少なくして伸び過ぎないようにします。
#gallery:after {
content: '';
flex-grow: 10; /* 強制的に大きくする */
display: block;/* IE10 対策 */
}
flexbox では余白をいかに有効に活用するかを目的にしていますが、逆に特定部分を利用させないこのアイディアは、後記の参考記事(Pure CSS implementation ・・)によるものです。
* {
margin: 0; padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background: url('./img/w-stone14.jpg');
background-repeat: repeat;
}
#gallery {
display: flex;
flex-wrap: wrap;
}
#gallery:after {/* 最後の行に配置される画像がほとんどないとき */
content: ''; /* 画面いっぱいに横長サイズで表示されないように*/
flex-grow: 10;
display: block;/* IE10 対策 */
}
#gallery p {
flex: auto; /* flex-grow: 1; でも可 */
height: 250px;
margin: 5px;
}
#gallery p img {
height: 250px;
min-width: 100%;
max-width: 300px; /* ブラウザIE対策 */
object-fit: cover; /* 等比トリミング */
font-family: 'object-fit: cover'; /* IE 等比トリミング */
border: 8px solid #fff; /* 写真外枠を白フチに*/
box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.7);
}
object-fit
プロパティを IE に対応させる
トリミングプロパティ object-fit
を未対応の IE に対応させる場合は、GitHub の object-fit-images からプラグインをダウンロードし、以下のようにします。
1、object-fit-images
読み込み
ダウンロードした中の「dist」フォルダー内にある、「ofi.min.js」というファイルを任意の場所に置いて HTML ファイルから読み込みます。
<script src="./js/ofi.min.js"></script>
この例ではサーバー側のディレクトリー(フォルダー) js に置いています。パーミッション設定は、HTML と同じ 644 か 604 です。ディレクトリーは 755 か 705 にします。
2、IE 用の特別スタイル font-family: 'object-fit: cover';
を追加
CSS のトリミングしたい画像のセレクタに、IE 以外の通常のものと併記します。
#gallery p img {
object-fit: cover; /* IE 以外等比トリミング */
font-family: 'object-fit: cover';/* IE 等比トリミング */
3、スクリプトを呼び出す
最後に、</body>
の前でスクリプトを呼び出します。( )内は、画像のセレクタ名を記入します。省略して( )内を空白にするとすべての img が対象になります。
<script>objectFitImages('#gallery p img');</script>
【 IE 対応した場合の注意点 】
今回の例のように写真の外枠に白フチをつける場合、前記のマルチカラムフォトギャラリーでは padding
を使用しましたが、IE 対応スクリプト加工にすると padding
エリアを計算しないようなので削られます。そのため border
を使用しました。
参考
- フレキシブルボックスレイアウト
- Pure CSS implementation of Google Photos / 500px image layout
- 1 行追加で OK ! CSSだけでトリミングできる「object-fit」プロパティ
シンプルなスライド式フォトギャラリー
たくさんの CSS のサンプルを掲載している海外(UK)サイト、「 CSS play 」のフォトギャラリーを参考にしたシンプルなスライド式ギャラリーの例をご紹介します。
ソースは、右クリック「ソースの表示」で参照してください。
CSS デモサイト CSSplay
このサイトは、ナビゲーションボタン、フォトギャラリー、吹き出しなどたくさんのCSS テクニックを駆使したサンプルを掲載しています。JavaScript を使用したような動きのあるものなど、「CSS でこんなことまでできるのか!」と驚きです。高度な CSS テクニックだけでなくデザインセンスも参考になります。 英語のページですが、デモのタイトルで内容が分かりますので一度ご覧になってください。商用のものは許可が必要です。
HTML
<div id="gallery">
<ul>
<li><a href="#nogo">
<img src="./img/eyes0345.jpg" alt="オオムラサキ"></a>
</li>
<li><a href="#nogo">
<img src="./img/eyes0270.jpg" alt="梅"></a>
</li>
以下、同じように画像を並べます。(省略)
</ul>
</div>
上記のように画像をリストタグで並べアンカータグの、href="#nogo"
という行き先のない URI を指定しています。
href="#"
に指定すると、ブラウザによってはページのトップに戻る動作をしますが、しないのもありそこに着目されたようです。文法的にはどうなのかな?
と思いますが、W3C からもリンクされているようですから問題ないのでしょう。CSS を高度に使いこなすには、ブラウザのレンダリングの知識も必要なのかもしれません。
あとは、CSS で元の画像をそのままサイズダウンした画像を並べてスライドしながら元の画像を表示できるように擬似クラスのリンク設定をしています。
このサンプルはシンプルなので、主要なブラウザ IE6〜8、Firefox、Opera 、Safari、Google Chrome で問題ないようです。動作は、JavaScript の onMouseOver イベントハンドラーと同じなので JavaScript でも同様にできます。下記は同じものを JavaScript にした例です。CSS も簡単なものです。
JavaScript に書き換えた HTML
<div id="gallery">
<div id="thumbs">
<img src="サムネイル-1"
onMouseOver="document.BigPhoto.src='元の画像-1'">
<img src="サムネイル-2"
onMouseOver="document.BigPhoto.src='元の画像-2'">
以下、同じように画像を並べます。(省略)
</div>
<p><img class="waku" src="表紙画像" name="BigPhoto"></p>
</div>
スクロール式フォトギャラリー
前記の例と同じように CSSplay サイトのフォトギャラリーを参考にしたもので、多くの画像を配置でき、タイトル、コメントを付けられるスクロール式の例をご紹介します。
サムネイル画像なので、画像が多くても初期表示は速いです。ソースは、「表示」→「ソース」で参照してください。
HTML
<div id="holder">
<div id="scrollbox">
<div id="thumbs">
<a class="gallery slide1" href="#nogo">
<span><img src="元の画像"><br>タイトル<br>コメント
</span></a>
以下、同じように画像を並べます。(省略)
</div>
</div>
</div>
前記、フォトギャラリーと基本的に同じですが、縮小サムネイル画像を準備してスクロールボックスに
背景画像として並べてスライドしながら元の画像を表示するように、
同一タグに複数のクラスを記述し、インライン要素
<span>
タグでサムネイル画像と元の画像をそれぞれ分けてスタイルを設定して巧みに擬似クラスでリンクしています。
JavaScript に書き換えた例
CSS で作成した例の場合は、ブラウザの挙動が一致していない特殊なテクニックで行なっているため難しいところもありますが、 JavaScript ならば私のような初心者でも作成できるもので CSS も複雑にはなりません。JavaScript を使用できる環境ならば主要ブラウザで正常に表示します。
画像のタイトルやコメントの表示は、innerHTML プロパティで HTML タグ内から取得してdocument.write("コメント")で表示しています。