pubDate: 2024-06-15
author: sakakibara
CSSは普通に書いていると、どんどんと複雑になっていく。
しばらく経つと、どこを変更したらどこに影響がでるのかわからなくなり、その上、多くのセレクタが氾濫してしまう。
良いCSSを書くことは難しい。
そこで、悪いCSSを避けることを考える。
これが
になったらCSSを書き直さなければならなくなる。 対策として
のようにする。
なるべく
のようなHTMLの構造に依存しているCSSは避けるべきである。
この点から、セレクタの連なりは長くなりすぎない方が良いだろう。
次のようなスタイルがあるとする。
しばらくはこれで良かったが、そのうち、border-bottom
を消したくなったとする。
すると次のようなCSSを書くだろう。
これが取り消しルールである。例外とも言える。
対策として、例外的なルールとそれまでのルールの共通部分を抜き出して、 それまでのルールに追加するルールを作成する。
共通部分を抜き出すという点からは一つのスタイルのプロパティの数は少なく、小粒であり、しかも共通部分を抜き出すという点からスタイルそのものの数も少なくなるべきだろう。
言わずもがな、マジックナンバーは避けるべきである。
対策として, 計算と継承をする。 これが、
こうなる。
一つ目はline-heightがfont-sizeの1.5倍であることを利用して、font-sizeが変わっても見た目がline-heightの見た目が変わらないようにしている。
二つ目はline-heightが継承されるため、line-heightを指定しなくても良い。
実は、フォント系のプロパティ(font-size
, color
, line-height
)などのプロパティはこの要素に継承される。
また、
ではなく、
としてしまうと、
計算された値が適用されてしまうので注意が必要である。 まとめると
line-height
を相対値にする。line-hegiht
は継承される。line-height
は無単位(無次元)で指定することで、その要素のfont-sizeにたいする比率を指定する。レスポンシブwebデザインの考え方の一つで、モバイルファーストという考え方がある。 これはレスポンシブ対応のwebページを作る際に、まずはスマートフォンサイズのページを作り、次にタブレットサイズ、PC用とだんだんと大きな画面に対応していくという考え方である。
これはスマートフォンの利用者が増加してきたことから、モバイルサイズの画面により優先して注力すべきだという考え方である。
CSSはブラウザによってデフォルトでスタイルが異なる。 それらを一旦リセットして、すべてのブラウザで同じスタイルを適用するためにnormalize.cssを使う。 normalize.css
CSSは以下のようにセレクタとプロパティを使ってスタイルを適用する。
CSSには数百のプロパティがあるが、基本的なものを以下に示す。
特定のタグに固有の一意の識別子をつける。
のように、idセレクタは#
で指定する。
<p id="interesting">
はp
タグが適用されるが、CSSは後段の設定が優先されるため、color: blue;
が適用される。
特定のタグをクラスに振り分ける。
idセレクタと似ているがクラスは複数個所で指定できる。
importantクラスのように, クラスは.
で指定する。
<p class="important">
はp
タグが適用されるが、CSSは後段の設定が優先されるため、color: yellow;
が適用される。
ul
やol
の中にあるli
タグを指定する。
ul
やol
にはlist-style-type
プロパティがある。これはリストのマーカーの形を指定する。
ヘッダーなどで使用する場合にdisplay: flex; justify-content: space-between
を指定することが多い。
a
タグはリンクを指定する。
color: inherit;
は親要素の色を継承する。
text-decoration: none;
は下線を消す。
a: hover
はマウスが乗った時のスタイルを指定する。
:hover
は疑似クラスと呼ばれるセレクタに追加するキーワードであり、選択された要素の状態を指す。
また、<a href="#">
はnull linkと呼ばれ、何もリンク先が指定されていないリンクを指す。
:hover
以外にもかなり多くの疑似クラスがある。
それらはいくつのグループに分けられる。
:fullscreen
, :picture-in-picture
など:checked
(チェックボックスがonなら..)など:dir()
(書字方向が縦なら..), :lang()
(言語がENなら..)など:visited
(訪れたことがあるなら…), :link
(まだ訪れてないなら…):play
(メディアが再生可能なら…) :paused
(メディアが一時停止しているなら..):current
(今表示されている要素の祖先なら…)videoの字幕用:root
(root要素なら…), :nth-child()
(n番目の子要素なら…):active
(クリックされたなら…), :hover
(マウスが上にあるなら…):is()
(セレクタが指定したものなら…), :not
(セレクタが指定したものでないなら…)a
タグでかつtarget="_blank"
の属性を持つものにcolor: blue;
を適用する。
これはdiv
タグの中にあるp
タグにcolor: red;
を適用する。
これはdivの下にあるpタグにどこまでも再帰的に適用される。
これを子孫結合子という。
これはdiv
タグの直下にあるp
タグにcolor: blue;
を適用する。
これはdivの直下のみにあるpタグにのみ適用される。
これを子結合子という。
これはdiv
タグの次に並ぶp
タグにcolor: green;
を適用する。
これは入れ子ではなく、div
の次に隣接するp
タグにのみ適用される。
これを隣接兄弟結合子という。
これはdiv
タグの後ろ(直後でなくても良い)にp
タグがある場合にcolor: yellow;
が適用される。
これは後続兄弟結合子という。
webページの各要素はすべてが矩形の領域で構成されている。 この矩形の領域をboxと呼び、boxの組み合わせによってきれいなwebページが作られる。
まず、内容を格納するcontentがあり、 borderがある。 borderの内側がpaddingで外側がmarginである。
このboxにはdisplayプロパティがあり、以下のように分類される。 これには書字方向(writing-mode)が関係している。 書字方向は縦書きと横書きがある。 日本語などは横書きであるが、アラビア語などは縦書きである。 boxが積まれる方向をフロー方向と呼ぶ。 boxがblockの場合、フロー方向は書字方向と垂直になる。 また、フロー方向を主軸、垂直方向を交差軸と呼ぶ。
displayプロパティ | 説明 |
---|---|
block | 要素は書字方向いっぱいに広がる。結果、書字方向とは垂直に積まれる。 |
inline | 要素は書字方向に積まれる。 |
inline-block | 要素は書字方向に積まれるが、block要素のように幅や高さを指定できる。 |
none | 要素は非表示になる。 |
つまり、パラグラフに割り当てて考えればblockは段落を、inlineは単語に該当する。
displayプロパティ | 説明 |
---|---|
flex | その子のフロー方向を制御する。 |
grid | その子はグリッド上に割り当てられる。 |
たとえば、p
タグはFireFoxのデフォルトでは display: block;
となっている。
子を敷き詰める効果がある。 flexを指定すると、何も指定がなければフロー方向が書字方向(水平)になる。
縦積みになっている状態で flexを横積みにすると、各boxの横のスペースを検知し、それを埋めるように横に積む。
横積みになっている状態で flexを縦積みにすると、各boxの縦のスペースを検知し、それを埋めるように縦に積む。
property | values | description |
---|---|---|
flex-direction | フロー方向の指定 | row(子を列に並べる, 水平方向) |
column(子を行に並べる、垂直方向) |
property | values | description |
---|---|---|
justify-content | 主軸方向に沿って内部アイテムどうしの間隔を配分する | start |
center | ||
space-between | ||
space-around | ||
align-content | 交差軸方向に沿って内部アイテムどうしの間隔を配分する。これはflexが折り返し設定され複数行にまたがっている時にしか有効ではない。折り返された複数行におけるjustify-contentのようなもの | start |
center | ||
space-between | ||
space-around | ||
justify-items | 軸上のアイテムの"配置"を制御する | strech |
center | ||
start, end | ||
align-items | 交差軸上のアイテムの"配置"を制御する | strech |
center | ||
start, end |
property | values | description |
---|---|---|
flex-basis | flexアイテムのサイズの初期値を設定する。 大きさはcontent-boxが設定される | 30px |
flex-grow | flex-grow係数を設定する。空き領域の分だけ伸長する。flex-grow指定されていないアイテムは伸長されない。flex-grow指定されているアイテムはその合計に対する比に応じて伸長する | 0 |
flex-shurink | flex-growの反対。縮小する | 0 |
flex | flex-grow flex-shurink flex-basisの一括設定 | 1 1 50px |
gridはその名の通り、グリッド上に要素を配置することができる。 gridで囲む要素をグリッドコンテナ、その中に配置される要素をグリッドアイテムと呼ぶ。 最も簡単な方法は以下の通り
グリッドコンテナのプロパティは以下の通り。 グリッドをどのように配置するかを指定する。
個々のグリッドアイテムがどのグリッドに割り当てられるかを指定する。
個々のグリッドアイテムのレスポンシブな配置を指定する。
以上のショートハンドが以下。
boxの大きさをboxモデルのどこまで含めるか、boxモデルの何をsizingの対象とするのか、を指定するプロパティとしてbox-sizingがある。
box自体の大きさはcontent + padding + borderで構成される。
デフォルトではbox-sizingはcontent-boxである。
この場合、sizing(width: 10rem)により、div自体の幅は10rem + 1rem + 1rem = 12remとなる。
box-sizingをborder-boxにすると、 div自体の幅は10remとなる。
一般的にはborder-boxを使うことが良しとされる。
注意すべき点として、box-sizing: content-box; は親要素がbox-sizing: border-box; である場合、親要素のpaddingが子要素の幅に含まれないことがある。
width:100%
の意味は親要素のbox-sizingに対して100%となることを意味する。
親要素(div)のbox-sizingはborder-boxであり、borderのサイズは10remとなり、boxのサイズは10remとなる。
これに対して、子要素(p)のbox-sizingはcontent-boxであり、contentの大きさは親要素の100%なのでcontentの幅が10remとなる。よって, paddingを含むとboxの大きさは12remとなる。結果、子要素は親要素の幅を超えてしまう。