2021年8月11日
イメージと文字をラッパーで囲んだ構成で、そのラッパーに比率(以下は16:9に設定した例)を設定する。ラッパーは position: relative; height: 0; 、
ラッパーの下位の階層に於いては、position: absolute; にして、width: 100%; height: 100%; object-fit: cover; にする。
object-fit: cover; …置換コンテンツはアスペクト比を維持したまま、要素のコンテンツボックス全体を埋めるように拡大縮小される。オブジェクトのアスペクト比がボックスのアスペクト比と合わない場合は、オブジェクトの方が合うように切り取られる。
<div class="aspect-ratio-16-9">
<h2 class="image-on-txt">Alpine A110</h2>
<img src="images/car.jpg" alt="Image description">
</div>
.aspect-ratio-16-9 {
--aspect-ratio: 16/9; /* 56.25% */
position: relative;
height: 0;
padding-bottom: calc(100%/(var(--aspect-ratio)));
}
.aspect-ratio-16-9 > * {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.aspect-ratio-16-9 img {
padding: 3%;
background: gold;
z-index: 1;
}
h2.image-on-txt {
position: absolute;
color: #fff;
font-size: 1.25rem;
text-align: left;
left: 30px;
top: 10px;
z-index: 2;
}
以下は4:3に設定した例
2021年8月18日
<img src="images/car.jpg" alt="Alpine A110" class="property-aspect-ratio-16-9">
.property-aspect-ratio-16-9 {
width: 100%;
padding: 3%;
background: gold;
aspect-ratio: 16 / 9;
object-fit: cover;
}
イメージに対してプロパティの「aspect-ratio: 4 / 3;」を設定する。
<img src="images/car.jpg" alt="Alpine A110" class="property-aspect-ratio-4-3">
.property-aspect-ratio-4-3 {
width: 100%;
padding: 3%;
background: gold;
aspect-ratio: 4 / 3;
object-fit: cover;
}
以下は幅を 50% にして黄金比で表示してみた。
<img src="images/car.jpg" alt="Alpine A110" class="property-aspect-ratio-golden-ratio">
.property-aspect-ratio-golden-ratio {
width: 50%;
padding: 3%;
background: gold;
aspect-ratio: 1618 / 1000; /* padding-topを使用した場合 padding-top: 61.80% */
object-fit: cover;
}
プロパティの aspect-ratio: は、width / height の比率を設定するものだ。ボックスのアスペクト比を定義でき、画像や動画のアスペクト比を保持して配置することができる。
@supports not を使った Fallback という書き方があったので、メモしておこう。not 演算子は、新たな式を作成するために任意の式の前に置くことができ、元の式を否定する。
div {
background: #f7f7f7;
width: 100%;
/* New aspect-ratio property */
aspect-ratio: 16 / 9;
}
/* Fallback (current, using padding hack) */
@supports not (aspect-ratio: 16 / 9) {
div::before {
float: left;
padding-top: 56.25%;
content: '';
}
div::after {
display: block;
content: '';
clear: both;
}
}
@supports (display: flex) {
div{Flexboxをサポートしている場合のスタイル}
}
@supports not(display: flex) {
div{Flexboxをサポートしていない場合のスタイル}
}
2021年9月12日
全てのモダンブラウザにサポートされたCSSの比較関数がとても便利そうだ。しかし、どういう局面で使い勝手が良いのか、これから探ることになる。頭部にある min と max が付いた関数とプロパティは似ているようでニュアンスが全然異なるので注意が必要だ。
例えば、width: max(50%, 280px); 関数は1つ以上のコンマ区切りの計算が含まれ、それらの最大値を表す。max() を使用することで最小値を設定することができる。この記述で、要素は必ず280px以上になる。
<div class="element-1">幅を50%をベースに、要素は必ず280px以上にする場合</div>
.element-1 {
width: max(50%, 280px);
background: lavender;
margin: 0 auto;
text-align: center;
}
min-width: 280px; は、要素の幅の最小値を280pxに指定したプロパティ。width: 50%; と併記することで上の場合と同じ内容になる。
<div class="element-11">幅を50%をベースに最大値は280pxにする場合</div>
.element-11 {
width: 50%;
min-width: 280px;
background: lavender;
margin: 0 auto;
text-align: center;
}
例えば、width: min(50%, 280px); 関数には、1つ以上のコンマ区切りの計算が含まれ、それらの最小値を表す。最大値を設定するにはmin()を使用する。この記述で、要素の最大幅は280pxになる。
<div class="element-2">幅を280pxより大きくならないように幅を50%をベースにする場合</div>
.element-2 {
width: min(50%, 280px);
background: lavender;
margin: 0 auto;
padding: 16px;
text-align: center;
}
max-width: 280px; は、要素の幅の最大値を280pxに指定したプロパティ。width: 50%; と併記することで上の場合と同じ内容になる。
以下の書き方も同義。
.element-22 {
width:50%;
max-width:280px;
background:lavender;
margin: 0 auto;
padding: 16px;
text-align: center;
}
<div class="element-3">最低幅を200px、最大幅を280pxに、50%をベースにする場合</div>
.element-3 {
width: clamp(200px, 50%, 280px);
background: lavender;
margin: 0 auto;
padding: 16px;
text-align: center;
}
minmax(min, max)は最小(min)以上および最大(max)以下のサイズ範囲を定義、こんな CSS グリッドで使用される。
2021年9月1日
このレスポンシブデザインはメディアクエリーを使ってブレイクポイントを四種類設け、テキストのフォントサイズのみを切り分けている。この部分は従来通り。
html 構成
<div class="container-center">
<div class="card">
<h1 class="subject-txt">TROY</h1>
<h2 class="subject-txt-2">Achilles</h2>
<div class="pic"></div>
<div class="pic-2"></div>
<div class="koushi"></div>
</div>
</div>
新しい方法で、イメージにはアスペクト比を設定しているので、イメージの配置については、メディアクエリのブレークポイントを必要としない。以前はブレークポイント毎に vw を使って幅と高さを設定していたことを考えると楽だ。
css aspect-ratio 設定の抜粋
.container-center .card {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: repeat(12, 1fr);
width: 100%;
aspect-ratio: 2 / 1; /* aspect-ratio */
position: relative;
background-color: #f7f7f7;
overflow: hidden;
border-radius: 1vw;
box-shadow:
inset 0 -0.375vw 3em rgba(0,0,0,0.1),
0 0 0 0 rgb(255,255,255),
0.375vw 0.375vw 1.25vw rgba(0,0,0,0.3);
box-shadow:0 0 0.625vw 0.234vw #ccc;
}
大きいスクリーンサイズに於いてテキストサイズが大きくなり過ぎないように、font-size:clamp() を試している。これは新たに追加したもの。
css font-size:clamp( , , ) 設定の抜粋
@media (orientation: landscape) and (min-width:1024px) {
.container-center .card h1.subject-txt {
-webkit-transition: all 0.2s ease;
transition: all 1.5s ease;
z-index: 102;
font-family: 'Noto Sans JP', sans-serif;
font-size:clamp( 69px, 6.8vw, 87px) !important; /* font-size:clamp( , , ) */
justify-self: end; align-self: end;
font-weight: 900;
color: #fff;
position: absolute;
top: 0;
right: 20px;
opacity: 0;
}
}
余白の設定は、同一のブレイクポイントの異なるデバイス間で vw を使うと余白の見栄えがかなりギャップを感じるものが出ることが確認できた。そういうものは px 指定の方が良い場合もある(上の場合がそうだ)。この辺りは勘と経験を積み重ねていくしかない。
上のデザインはイメージの部分の css はひとつの書き方で大丈夫だが、テキストを使ったために、メディアクエリーの四種類のブレークポイントの記述が必要になりボリュームが膨れたのが欠点だ。
2021年9月9日
アスペクト比について、実際にどういう局面で使い勝手が良いのだろうか?
例えば、モバイルの portrait では 1 対 3 、landscape では 2 対 1 の別々のアスペクト比を組んで表示するなどの類では見せ方として有効である(chrome デベロッパーツールで確認してほしい)。しかしながら、iPhone 実機にて最新バージョンの Chrome で確認すると、上手く表示されなかった。
因って、上の場合でpadding-bottom を使った例である。こちらの方式が今のところ安全かもしれない。
また、レスポンシブデザインに於いて、複数のイメージやテキストが含まれると、各サイズの指定が必要になる。vw というサイズをイメージとテキストに使ったとしても各ブレークポイント毎に適正なサイズや調整を決定しなければならない。これは手数がかかる作業を強いられる。
だが、この全てをイメージに変えてアスペクト比を設定できるとすれば、とても素晴らしい結果が待っている。例えば、アスペクト比で組まれた 2 対 1 はどんなスクリーンサイズでも変わらない数値だ。そういうことをこのページで検証した。
イメージを複数配置するには、CSS grid を使って設定するのが個人的な好みだ。
<div class="container-center">
<div class="card">
<div class="subject-3"><img src="images/achilles.gif" style="width: 100%;" alt="アキレス"></div>
<div class="subject-4"><img src="images/troy.gif" style="width: 100%;" alt="トロイ"></div>
<div class="pic"></div>
<div class="pic-2"></div>
<div class="koushi"></div>
</div>
</div>
.container-center {
display: grid;
place-items: center;
padding: 1.6vw;
}
.container-center .card {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: repeat(12, 1fr);
width: 100%;
aspect-ratio: 2 / 1;
position: relative;
background-color: #f7f7f7;
overflow: hidden;
border-radius: 1vw;
box-shadow:
inset 0 -0.375vw 3em rgba(0,0,0,0.1),
0 0 0 0 rgb(255,255,255),
0.375vw 0.375vw 1.25vw rgba(0,0,0,0.3);
box-shadow:0 0 0.625vw 0.234vw #ccc;
}
.container-center .card .pic {
grid-column: 1 / 7;
grid-row: 1 / 13;
z-index: 100;
background-image: url("images/gladiator.jpg");
width: 100%;
height: 0;
padding-bottom: 100%;
background-size: cover;
filter: grayscale(100%);
opacity: 0.8;
}
.container-center .card .pic-2 {
grid-column: 7 / 13;
grid-row: 1 / 13;
z-index: 100;
background-image: url("images/aspect.jpg");
width: 100%;
height: 0;
padding-bottom: 100%;
background-size: cover;
filter: grayscale(100%);
opacity: 0.8;
}
.container-center .card:hover .pic {
filter: grayscale(0); /* 100%で完全にモノクロ */
}
.container-center .card:hover .pic-2 {
filter: grayscale(0); /* 100%で完全にモノクロ */
}
.koushi {
grid-column: 1 / 13;
grid-row: 1 / 13;
margin: 0;
background-image: url("images/koushi.gif");
width: 100%;
height: 0;
padding-bottom: 50%;
background-size: cover;
}
テキストをイメージに変えた部分のCSS
.container-center .card div.subject-3 {
grid-column: 8 / 13;
grid-row: 8 / 9;
-webkit-transition: all 0.2s ease;
transition: all 1.5s ease;
z-index: 102;
justify-self: end; align-self: end;
position: absolute;
top: 0;
right: 0;
opacity: 0;
}
.container-center .card div.subject-4 {
grid-column: 8 / 13;
grid-row: 6 / 7;
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
z-index: 101;
justify-self: end; align-self: center;
position: absolute;
top: 0;
right: 0;
opacity: 0;
}
.container-center .card:hover div.subject-3 {
opacity: 0.9;
-webkit-transform: scale(1);
transform: scale(1);
-moz-text-shadow: 0.5vw 0.75vw 0px rgba(0, 0, 0, 1);
-webkit-text-shadow: 0.5vw 0.75vw 0px rgba(0, 0, 0, 1);
-ms-text-shadow: 0.5vw 0.75vw 0px rgba(0, 0, 0, 1);
text-shadow: 0.5vw 0.75vw 0px rgba(0, 0, 0, 1);
}
.container-center .card:hover div.subject-4 {
opacity: 0.9;
-webkit-transform: scale(1);
transform: scale(1);
-moz-text-shadow: 0.5vw 0.75vw 0px rgba(0, 0, 0, 1);
-webkit-text-shadow: 0.5vw 0.75vw 0px rgba(0, 0, 0, 1);
-ms-text-shadow: 0.5vw 0.75vw 0px rgba(0, 0, 0, 1);
text-shadow: 0.5vw 0.75vw 0px rgba(0, 0, 0, 1);
}
上で使った html にアニメーションを追加して作ったサンプル。アスペクトが設定されていれば転用が楽だ。
2021年9月15日