CSSのセレクタを記述するとき、box-sizingはデフォルトでcontent-boxになっている。
content-boxの場合はボックスのwidthやheightを表現するときにpaddingやborderを含まない。
一方のborder-boxでは、widthやheightにpaddingとborderを含む表現なる。
レスポンシブ環境においては表示領域のサイズの変化に応じて、その中のボックスのサイズも自動的に拡縮することになるが、その際に基準になるのはwidthかheightのいずれかであり、そのクリチカルな条件に合わせてボックスのサイズが変化する。
ボックスのサイズが変化するとき、その縦横比を一定に保つ必要があり、そのためにはwidthとheightからなるアスペクト比を一定に維持する必要がある。
このとき、表示領域と接触し、その影響を受けるのはボックスの外形すなわちpaddingとborderを含んだ最も外側の枠であり、それはCSSで定義するwidthとheightで定められる領域の外枠とは異なる。
paddingとborderの幅の分が異なるだけなのだが、アスペクト比はそれらを区別しなければならない。
具体例で示すと、表示域の大きさが変化する場合、padding=30 と border=20 は変わらないとすると、
(1)width=300、height=200、padding=30、border=20
borderを含む外形は350×250
width/heightのaspect比 = 300/200 = 1.5
外形のaspect比 = 350/250 = 1.4
(2)表示域が縦横半分に小さくなった場合
borderを含む外形は175×125 と縦横が半分になる
width=145、height=105、padding=30、border=20
width/heightのaspect比 = 115/85 = 1.35294
外形のaspect比 = 175/125 = 1.4
外形はaspect比1.4で一定でもwidth/heightで表されるボックスの縦横比は変化する。
このことから、aspect比が関係する処理においては都度paddingとborderの値を引いてから演算し、その結果にpadding値とbordera を加算しなければならない。
これは大変な負担で、単に計算式が込み入るだけではなくて、処理のロジックを組み立てる上で複雑な構造を理解しなくてはならない。
既に多くの方はborder-boxを採用しているのではないかと思いつつ、content-boxにこだわってきた。
これも、既成概念から脱却できないという老化現象のひとつか...
次回からは、javascriptでBOXモデルに絡む計算をするときはbox-sizing:border-boxを採用しようと思う。
札幌における"日の出"、"日の入り"時刻の表を掲載した。
国立天文台暦計算室のホームページからデータを抽出し、Excelで編集した。
札幌の他に根室のデータも公開されているので、各地を移動するとき、その場所と札幌、根室との位置関係から、日の出日の入り時刻を直感的に把握できるようになる。
これは今後の課題だ。
https://muhyo.sakura.ne.jp/contents/b_photo/sunriseset.html
自動生成のカレンダーをモバイル向けにカスタマイズした。
@mediaを使って760pxで切り替えているので手抜きと言えなくもないが、要はデスクトップとスマホで使い分けたいということで問題なしとした。
また、andoroidのフォントが自分の意に沿わないが、ここは仕方のないことで、実用性のみで存在価値ありと割り切った。
"ページめくりのアイコンを画面のどの位置に置くか"については、マウスの使用を前提とすればほとんど問題にならなかった。好きにデザインすればよかった。
しかし、スマホの画面をタップするとなると事情は変わる。
画面をタップする手が邪魔になって画面が見えなくなる。わずかな時間ではあるが、煩わしい。次から次へとページをめくるときは、細かく手をずらさなければならず、いよいよ看過できない問題となる。
普通に考えて、右手指で操作するなら画面の右下、左手指で操作するなら画面の左下にペーシめくりアイコンを配置するのが良いと思う。
ということで、右利きと左利きで画面のレイアウトを切り替えることにした。
そのためには、デザインを切り替える処理とともに、右利きか左利きかを選択・登録する処理が必要になる。そしてその登録を覚えておく処置も必要になる。
覚えておく手段としては、cookieを使うとより詳細な制御が出来たり、ログインするとさらにしっかりとした管理が出来たりと、選択肢は色々とあるが、複雑な仕組みは避けたいところで、sessionStorageを使うことにした。
ブラウザのページが表示されている間(タブが閉じられるまで)維持される記憶域に登録するもので、必要な最低の条件は満たされると思う。
サイトを開くたびに左利き設定するという煩わしさは残るものの、シンプルさが良いと思う。(デフォルトは右利き)
次に、画面レイアウトだが、基本的には、右利きと左利きでレイアウトを単純に左右入れ替えることで対応することにした。
しかし、左右入れ替えで済まない要素もある。
テキストを収容するボックスで、文字数が可変、行数可変、ボックスの横サイズ可変という場合、このボックスを配置するとき、左側を基点とすると比較的扱いやすいのだが、右側を基点にして配置するとなると困難なことになる。
写真の左側にタイトル文を配置するレイアウトのことだ。タイトル文は可変長、そして複数行になることもある。このタイトルと写真の間隔を一定のサイズに維持したい。写真のサイズも可変、テキストボックスのサイズも可変、しかも、テキストは左揃え各行の文字数が異なっても最も文字数の多い行がテキストボックスの横幅を決める。
力技で押し通すにはjavascriptで文字数を数え、フォントサイズから横幅を算出するというようなことになるが、どう見てもスマートな手法とは思えない。
ボックスモデルではCSSでwidthの指定が無ければautoがデフォルトとなり、その場合、親要素のwidthが適用される。なので、javascriptで要素の実態サイズを取得することはできない。
最終的に解決した手法はシンプルなもので、
■親要素
・上位に対しては通常のボックスモデルで定義
・固定幅
・子要素をGridレイアウト定義
・子要素の幅は1frで可変長
■子要素(タイトル)
・justify-self:end で右揃え配置
最終的に親要素のmargin-leftを動的に設定し、写真との位置関係を調整する。
ポイントは、
・Gridレイアウトで子要素にjustify-selfを設定すると、親要素で指定したwithの中で実態を反映したwidthが発生する。
・子要素を右揃えで配置する。(要素の配置を右揃えとするもので、その内部のテキストは左揃えのまま)
この2つの特性を組み合わせることで、複雑な処理を行うことなく、実にシンプルな定義のみで希望するレイアウトが実現できた。
ただし、条件があり、タイトルの行に自動改行(折り返し)が発生すると子要素のwidthは親要素のwidthとなってしまう。従って、折り返しが発生しないように、意図的に改行<br>を挿入するようにしなければならない。運用にあたっての注意事項となる。