Webサイトはレスポンシブウェブデザインが当たり前になり、要素や画像の幅は基本的に%やvwといった相対単位で指定されるようになりました。
【 用語解説 】
#レスポンシブウェブデザイン(Responsive Web Design, RWD)
#相対単位
*単位に関する記事はこちら*
確かに、width:80vw などと指定しておけば、画面サイズに関係なく、その要素が画面からはみ出てしまう(横スクロールができてしまう)ことはありません。
ですが、「画面が小さなスマホでは80vwでちょうど良いけど、画面が大きなPCで80vwで表示させると大きくなりすぎ…」となってしまうことも少なくありません。
メディアクエリでブレークポイントを指定するのも1つの解決方法ですが、ブレークポイントごとに細かく設定するのは手間ですし、できれば避けたいものです。
【 用語解説 】
#メディアクエリ(media query)
#ブレークポイント(breakpoint)
将来のメンテナンスのことも考えると、CSSは可能な限り簡潔にまとめたいもの。そして、それを可能にしてくれるのが、最大・最小の幅を指定できるmax(min)-widthプロパティです。
要素に最大幅を設定する
「それ以上大きくならないで!」というふうに、要素の最大幅を指定できるのがmax-widthプロパティです。
最大幅を設定したい場合の多くは、PC表示の際に、画像などの表示が大きくなり過ぎるのを防ぎたい場合です。
特に、元々のサイズがそんなに大きくないラスター画像の場合、サイズの大きなPCの画面幅いっぱいに拡大されて元画像のサイズを超えると、画質が劣化してしまいます。
用語解説:#ラスター画像(ビットマップ画像)
設定の仕方はとても簡単で、max-widthプロパティに「それ以上大きくならないで」という数値を値として指定するだけです。
とても簡単ではありますが、一応構文例を確認しておきましょう。
*max-widthの構文例*
{ max-width: 800px; }
値には、widthを指定する時と同じ値を設定することができます。fit-contentなどのキーワード値も有効です。(widthの解説記事はこちら)
max-widthの機能を分かりやすく体感できるよう、max-widthを指定したものと、何も設定していないものを並べて、調節バーで要素の幅を変えることができるものを用意しました。
上の緑のゲージはmax-widthを80%に指定しています。
それに対して、下のピンクのゲージには何も設定していません。
調節バーを最大まで動かしたとき、緑のゲージのみ、80%で止まることを確認してみてくださいね!
せっかくなので、▲調節バー付きmax-width確認ゲージのサンプルコードを公開しておきます笑。
<!DOCTYPE html>
<html lang="ja" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<style>
.materbox1 {
width: 100%;
text-align: center;
}
.outmater {
position: relative;
width: 80%;
background-color: lightgrey;
height: 50px;
border: solid;
border-radius: 20px;
margin: 1rem auto;
box-shadow: 2px 2px white inset;
margin-bottom: inherit;
}
.inmater {
position: absolute;
top: 0;
left: 0;
background-color: rgba(76, 230, 125, 0.83);
width: 50%;
height: 50px;
border-radius: 17px 0 0 17px;
max-width: 80%;
box-shadow: 0px 0px 0 4px white inset;
}
.inmater2 {
position: absolute;
top: 0;
left: 0;
background-color: rgba(230, 76, 163, 0.83);
width: 50%;
height: 50px;
border-radius: 17px 0 0 17px;
box-shadow: 0px 0px 0 4px white inset;
}
.change_per {
display: flex;
align-items: center;
position: absolute;
right: -35px;
bottom: 0;
top: 0;
}
.change_per2 {
display: flex;
align-items: center;
position: absolute;
right: -35px;
bottom: 0;
top: 0;
}
.width_change1 {
color: rgb(43, 109, 142);
outline: solid;
outline-offset: 8px;
outline-style: dashed;
}
</style>
</head>
<body>
<div class="materbox1">
<div class="outmater">
<div class="inmater"><span class="change_per">50%</span></div>
</div>
<p style="color: tomato; background-color: white; padding: 7px; position: relative; width: fit-content;
margin: 0 auto;">*幅調節バー*</p>
<input class="width_change1" type="range" name="" value="50">
<div class="outmater">
<div class="inmater2"><span class="change_per2">50%</span></div>
</div>
</div>
<script type="text/javascript" defer>
{
const inmater = document.querySelector('.inmater');
const inmater2 = document.querySelector('.inmater2');
const width_change = document.querySelector('.width_change1');
const change_per = document.querySelector('.change_per');
const change_per2 = document.querySelector('.change_per2');
let changeWidth = 0;
width_change.addEventListener('input', () => {
changeWidth = event.target.value;
inmater.style.width = changeWidth + '%';
inmater2.style.width = changeWidth + '%';
change_per2.textContent = change_per.textContent = `${changeWidth}` + '%';
if (changeWidth >= 80) {
change_per.textContent = '80%';
}
else {
change_per.textContent = change_per.textContent = `${changeWidth}` + '%';
}
if (changeWidth > 98 ) {
inmater2.style.borderRadius = '17px';
}
else {
inmater2.style.borderRadius = '17px 0 0 17px';
}
});
}
</script>
</body>
</html>
POINT!
- ・max-widthプロパティで、要素の最大幅を指定できる!
- ・PC表示の際、要素(特に画像)が大きく表示され過ぎるのを防ぐ目的が多い!
- ・値は、widthの設定と同じように、数値やキーワード値で指定できる!
要素に最小幅を指定する
先ほどはmax-widthを使って要素に最大幅を設定しましたが、今度は逆です。min-widthプロパティを使って、要素の最小幅を指定していきます。
指定方法は、max-widthと全く同じです。
また、min-widthの適用が想定されるシーンとしては、max-widthと逆で「スマホ表示の際に、縮小されすぎないようにしたい時」などがあります。
例えば、画像のサイズをwidth: 100%;としていても、余白を考慮して画像の親要素の幅を80%にしていたら、画像は最大でも80%の大きさになります。
スマホ画面の横幅が400pxとすると、400pxの80%=320pxの大きさ表示になるということですね。
しかし、画面が小さなスマホでは、画像はできるだけ大きく表示させたいものです。
そこで、画像の親要素にmin-width: 390px;と付け加えることで、最小でも390pxでの表示が約束されます。
*スマホの横幅は350px以下のものもあるので、実際に親要素にmin-width: 390px;としてしまうと、スマホによっては画面に入りきらないのでご注意ください!*
また、状況次第では要素からはみ出てしまう可能性がありますが、記事のタイトルやメニュー項目など、絶対に改行されてしまいたくない場合に、min-width: max-content;とすることもあります。
▲の背景が薄い黄色になった文章は、min-width: max-content;と指定したものです。改行されない幅が確保されていますね。
記事の枠からはみ出すとレイアウトが崩れてしまうので、スクロールできるようにしています。
そして今回も、min-widthの機能を視覚的に確認できるゲージを用意したので、調節バーを動かして確認してみてくださいね!
緑のゲージに、min-width: 20%;を設定しています。
POINT!
- ・min-widthプロパティで、要素の最小幅を指定できる!
- ・スマホ表示の際に、要素が縮小され過ぎてしまうのを防ぐ目的などで使われる!
- ・画像のサイズ調整の他、文字が改行されてしまうと困る場合にも!
最大・最小幅を同時に指定する
max-widthプロパティとmin-widthプロパティは、1つの要素に対して同時に指定することが可能です。
大きな画面に合わせて拡大され過ぎてしまうのを防ぎつつ、小さな画面に合わせて縮小され過ぎてしまうのも防ぐことができるということですね。
設定方法も簡単で、以下のように要素に基準となるwidthを指定した上で、max-widthとmin-widthを指定します。
*max-widthとmin-widthを同時に指定*
{ width: 80%; max-width: 1000px; min-width: 400px; }
このように指定することで、メディアクエリでデバイスの画面サイズに合わせて表示を切り替えなくて済む場合も多いです。すると、
1CSSファイルの行数が少なくなる
2CSSファイルが軽くなり、ページ表示スピードが速くなる
3ブレークポイントを減らせることで、管理も容易になる
このようなメリットがたくさん生じます。特に、ブレークポイントを増やさないで済むというのは非常に大きいです。
2021年6月現在、スマートフォンの進化はだいぶ落ち着いたように思えますが、それでも毎年新しい機種が開発され、画面のサイズも機種によって様々です。折りたたみ式で、開くと実質2画面分の大きさになるスマホが流行ることだってあるかもしれません。
そういった時代の変化に対応しやすいWebサイトにするには、ブレークポイントをいくつも作るよりも、最大幅と最小幅を決めておき、あとは画面のサイズに合わせて可変するようにしておくのがベストです。
下には、max-width: 80%;と、min-width:20%;を設定した緑ゲージを用意しました。
max-widthとmin-widthを同時に指定した時の動作を確認してみてくださいね!
POINT!
- ・1つの要素に、max-widthプロパティとmin-widthプロパティを同時に指定することができる!
- ・同時に指定することで、ブレークポイントを減らせる場合もある!
- ・最大&最小幅の指定を活用して、CSSの管理を少しでも楽にしよう!
max(min)-widthを使わずに、最大・最小幅を設定する方法
条件次第では、max(min)-widthを使わずに要素の最大・最小幅を指定する方法もあります。
その「条件」というのは、フレックスボックスもしくはグリッドレイアウトであること…です。
フレックスボックスでは、以下のサンプルコードのように、flexプロパティのflex-grow、flex-shrink、flex-basisの値を調整することで、実質的に最大や最小幅を指定することができます。
<div class="sample_skyimage">
<img src="https://web-de-asobo.net/wp-content/uploads/2021/06/aozora.jpg" alt="青空の写真">
</div>
.sample_skyimage {
overflow-x: scroll;
display: flex;
}
.sample_skyimage img {
width: 100%;
flex: 1 0 700px;
}
▲の写真は、width: 100%;と設定しているので、本来ならば親要素の幅に合わせて拡大・縮小されます。
しかし、flex: 1 0 700px;としているため、この画像は親要素の幅に合わせて拡大はされますが、縮小されることがなく、最小でも700pxの幅になります。(min-width: 700px;と同じ)
パソコンからこの記事を読んでいる方は、ブラウザの画面幅を変えてみてください。画像が700pxの表示領域を確保できなくなったら、画像が縮小されていくのではなく、画像を横にスクロールできるようになっているはずです。
flexプロパティについての記事は、▶︎こちらをご参照ください。
また、グリッドレイアウトでは、以下のサンプルのようにグリッドアイテムの幅(カラムの幅)をminmax関数で指定することで、max(min)-widthを設定するのと同じように、要素の最大・最小幅を指定することができます。
<div class="sample_skyimage_grid">
<img src="https://web-de-asobo.net/wp-content/uploads/2021/06/aozora.jpg" alt="青空の写真">
</div>
.sample_skyimage_grid {
overflow-x: scroll;
display: grid;
grid-template-columns: minmax(400px,800px);
justify-content: center;
}
.sample_skyimage_grid img {
width: 100%;
}
▲のサンプルでは、grid-template-columns: minmax(400px,800px);としているので、最大幅が800px、最小幅が400pxになります。
まんま、max-width: 800px; min-width:400px;と設定するのと同じですね。
グリッドレイアウトのminmax関数に関しては、▶︎こちらの記事で詳しく解説しています。
このように、max(min)-widthプロパティを使わなくても、要素の最大・最小幅を指定する方法はいくつかありますが、特にグリッドレイアウトではminmax関数で最大と最小幅を同時に設定できる上に、justify-contentプロパティを使って中央揃えも楽にできるので非常に便利です。
もちろん、基本的にはmax(min)-widthプロパティで設定して良いのですが、こういった他の方法・テクニックも覚えておくと、いつかどこかで役に立つかもしれません。
POINT!
- ・フレックスボックスやグリッドレイアウトなら、max(min)-widthを使わなくても最大・最小幅を指定できる!
- ・フレックスボックスの場合はflexプロパティ。グリッドレイアウトの場合はgrid-template-columnsプロパティで最大・最小幅を設定できる!
- ・特にグリッドレイアウトではminmax関数が使えるので便利!