正方形のテクニックはいろいろある
vminなどの Viewport units を使ったり、横幅ベースの正方形要素の作り方というものがいくつかあります。
前者はともかく後者はなかなか難しいことをしていてけっこう大変ですが、とりあえずビュー基準か親要素の横幅基準で正方形要素を作ることは可能です。
さて、ここで問題になってくるのは、親の高さベースで正方形をどうやって作ればよいかです。
今回やり方がかっこ悪くて全然おすすめはできないものの、一つ方法を思いついたのでメモっておきます。
基本的な考え方
画像は例えば height: auto
の時 width: 100%
とかすると、親要素の横幅いっぱいまで画像を広げ、高さはそれに合わせてアスペクト比を維持して拡大されます。
これの横幅と高さを入れ替え、画像の大きさに合わせる要素(display: inline-blockとかposition: absoluteとか
)を用意すれば、親の縦をベースにした正方形要素がうまく作れそうです。
今回はSVG画像をBase64変換して <img>
に埋め込み、正方形の土台にします。
実際のコード
元のSVG
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="1" width="1"></svg>
サイズを1,1にすることで、正方形の空画像を作ります。
Base64変換された画像
Base64+ヘッダにいろいろつけた、<img>
に直接埋め込める状態にしたのが以下です。
data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4xIiBoZWlnaHQ9IjEiIHdpZHRoPSIxIj48L3N2Zz4=
HTML
<div class="parent">
<div class="square">
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4xIiBoZWlnaHQ9IjEiIHdpZHRoPSIxIj48L3N2Zz4=">
<div class="contents"></div>
</div>
</div>
CSS
/* 親要素の高さを3emにするので、正方形は3em*3emになる */
.parent { height: 3em; }
/* 正方形にする要素 */
.square {
background-color: gray;
/* 今回は 横幅をコンテンツに合わせるためinline-blockにする */
display: inline-block;
/* 自分の中のコンテンツの配置のため、relativeにしておく */
position: relative;
/* 高さは親に合わせる */
height: 100%;
}
/* 正方形に拡大する画像 */
img {
/* 横幅は縦に合わせ、縦は親に合わせる */
width: auto;
height: 100%;
}
/* 正方形内のコンテンツ */
.contents {
/* コンテンツは正方形目いっぱいの大きさにする */
width: 100%;
height: 100%;
/* 画像の上に設置する */
position: absolute;
top: 0;
}
まとめ
今回はSVG画像を使ったこともあり、画像サイズの比率を変えればそこそこ応用が効く実装になったのではないかと思います。
ただ、元々ShadowDOMを使っている時に親要素の高さベースで正方形を描画したいのに、どうにもならない上になんか求めている解決方法がなかったので頑張りましたが、できればCSSだけでシンプルに解決したいものです。
他に何かいい方法があったら教えてください。