この記事は ここのえ Advent Calendar 2023 Day 4の記事です。
CSS版ウミガメのスープ
ある男が、とあるWebサイトでTailwindを使用し、portrait と landscape でデザインが変わるようなCSSを実装していた。
FullHDのディスプレイを使用し、デザインの確認をするため、ブラウザのサイズを画面の半分にして、縦向きにした。
しかし、portrait として認識されない。一体、なぜ?
...
答え: ブックマークバーがONになっている。
経緯
先日、SNSから飛んできたときに使ういい感じのリンク集を作っていたのですが、Tailwind CSSのportrait:
, landscape:
を使って、縦画面と横画面でデザインのレイアウトを変えようと試みました。
FullHD画質のディスプレイを使用し、画面の左右にスナップして画面サイズを半分にしました。
この状態はだいたい 960 x 1080
になるため、縦画面になるはずなのですが、一向に portrait
になる気配がありません。
ここでDevToolsのComputed
の項目を確認してみると、どうやら実際に width > height
になってしまっていることが分かります。
CSSが取り扱うのは ビューポートのサイズ なので、ブックマークバーが表示されていると、ビューポートを押し込んでしまい、こういったことが発生してしまいます。泣いちゃった…!!!
対策例
確かにこの状態では portrait
ではないのですが、人間の体感的には縦画面なので、そこでレイアウトがスカスカになって違和感を感じてしましました。
加えてモバイルのサイズでは文字が小さくなってしまう事から、別の配置にしたかったため、
- Mobile
- Desktop (Portrait)
- Desktop (Landscape)
の3パターンに分けて実装を行いました。Vue + Tailwindで実装すると、こんな感じになります。
「体感で縦画面なら縦」で取り扱うために width/height
した値が 1.1
未満の画面比率になっていた場合、portraitとみなします。
<script setup lang="ts">
import { onMounted, ref } from 'vue'
const layout: ref<'mobile' | 'portrait' | 'landscape'> = ref('mobile')
onMounted(() => {
window.addEventListener('resize', () => {
const width = window.innerWidth
const height = window.innerHeight
if (width < 768) {
layout.value = 'mobile'
} else if (width / height < 1.1) {
layout.value = 'portrait'
} else {
layout.value = 'landscape'
}
})
})
</script>
<template>
<div :class="['test', layout]" >
This is a test.
</div>
</template>
<style scoped lang="sass">
.test
@apply bg-black text-white
&.mobile
@apply text-lg
&.portrait
@apply text-red
&.landscape
@apply text-xl
</style>
まとめ
今回のようにブックマークバーなどでビューポートが押されると、一見縦画面のように見えても横長になっている場合があります。
特にwidthとheightの差が数pxだった場合は、コンピュータ的には正しくても、人間の体感としてはレイアウトに違和感を感じる、という事も起きます。
JSも使いながら、柔軟にレイアウトをカスタマイズしていきましょう。