3-3. main部分のCSSを書く

このチャプターでは、main要素のCSSを記述していきます。矢印アイコンの配置は、本ハンズオンでは一番難易度が高いかもしれません。


余白を調整する

とりあえずまずはmain要素の下側、footer要素との間に余白を入れます。

/* ============================ */
/*  .main
/* ============================ */

.main {
  margin-bottom: 40px;
}

margin-bottomとして、下側のみ40pxの余白を入れます。

コンテンツタイトルにスタイルをあてる

つづいてh2要素にスタイルをあてていきます。

h1と同じ「Fascinate Inline」を使用しますが、Google Fontsの読み込みはすでにできているので、ここでは同じCSSを記述するだけです。

.mainのあとに追加します。

フォントサイズはh1よりすこし小さめにしています。先のチャプターでCSS変数を利用するようにCSSを書き換えたので、colorプロパティには変数が入っていますが、CSS変数を利用していない場合は値にカラーコードを入れてください。

h2 {
  margin-bottom: 10px;
  color: var(--subColor);
  font-size: 2.25em;
  font-weight: 400;
  font-style: normal;
  font-family: 'Fascinate Inline', system-ui;
  text-align: center;
}

見出しの重複する値をまとめて記述する

header要素のh1main要素のh2のCSSを記述しましたが、font-size以外の宣言はまったく同じです。同じレイアウトのCSS(の宣言ブロック)はひとまとめにして差異だけを記述すると、コードを書く量も減りのちのちのメンテナンスもしやすくなります(同じコードを何度も書かなくて済みます)

以下はh1h2のCSSの抜粋です。

h1 {
  margin-bottom: 10px;
  color: var(--subColor);
  font-size: 2.5em;
  font-weight: 400;
  font-style: normal;
  font-family: 'Fascinate Inline', system-ui;
  text-align: center;
}

/*(略)*/

h2 {
  margin-bottom: 10px;
  color: var(--subColor);
  font-size: 2.25em;
  font-weight: 400;
  font-style: normal;
  font-family: 'Fascinate Inline', system-ui;
  text-align: center;
}

このコードを以下のようにまとめます。ひとまとめにしたコードは、body要素のCSSのあとに移動させました。

body {
  /*(略)*/
}

h1,
h2 {
  margin-bottom: 10px;
  color: var(--subColor);
  font-weight: 400;
  font-style: normal;
  font-family: 'Fascinate Inline', system-ui;
  text-align: center;
}

/*(略)*/

h1 {
  font-size: 2.5em;
}

/*(略)*/

h2 {
  font-size: 2.25em;
}

この状態でstyle.cssを保存し、index.htmlをブラウザで開くと、以下のように表示されます。

h2要素にスタイルをあてた状態のindex.htmlのキャプチャ画面

h1要素のスタイルに変更がないこと、main要素の株に余白があり、またh2要素にスタイルがあたっていることを確認します。

リンクリストにスタイルをあてる

いよいよ一番のメインであり、本ハンズオンの難所でもあるリンクリストにスタイルをあてていきます。

リストのマーカーを消す

まずはデザインから不要なリストのマーカーを消します。

.main ul li {
  margin-bottom: 15px;
  list-style: none;
}

ul要素はリセットCSSを記述した際にmarginpaddingの値を0にしており、この他のスタイルは必要ないため、ここでは記述不要です。

リスト項目(li要素)間にmargin-bottomで適切な余白を入れ、list-styleでリスト項目先頭のマーカーを非表示にします。

list-styleプロパティ

list-styleプロパティは、リストのスタイルを一括で指定するプロパティです。以下のプロパティと値を指定できます。

  • list-style-type:マーカーの種類を指定(以下は代表的な一部のみ記載)
    • none:マーカーを表示しない
    • disc:塗りつぶされた円(初期値)
    • circle:中空円
    • square:塗りつぶされた四角形
    • decimal:1からはじまる数字
    • lower-roman:小文字のローマ数字
    • upper-roman:大文字のローマ数字
    • lower-alpha:小文字のアルファベット文字(lower-latinも可)
    • upper-alpha:大文字のアルファベット文字(upper-latinも可)
  • list-style-position:マーカーの位置を指定する
    • outside:リストアイテムの外側に配置される(初期値)
    • inside:リストアイテムの最初の要素として内側に配置される
  • list-style-image:マーカーを画像で指定する(list-style-image: url(画像パス)
    • 画像パスは相対パス、絶対URL、ルートパスで指定可

一括指定は、list-style: circle inside;のように指定します。

list-style-typeのうち、数字が表示されるリストマーカーはul要素ではなくol要素を使用することが多いです。

list-style-positionは以下のようになります。insideを指定した場合のマーカーは「テキスト」のような振る舞いとなり、リスト項目の最初に1文字足されるイメージです。

list-style-positionの説明

この状態でstyle.cssを保存し、index.htmlをブラウザで開くと、以下のように表示されます。

リストマーカーを消した状態のindex.htmlのキャプチャ画面

リンク部分のスタイルを調整する

つづいて、リスト項目の中のリンク部分のスタイルを調整していきます。

各リスト項目のどこにマウスを乗せてもリンクとなるようにCSSを記述します。

.main ul li a {
  padding: 15px 50px 15px 15px;
  text-decoration: none;
  background-color: var(--whiteColor);
  border: 1px solid var(--baseColor);
  border-radius: 5px;
}

.main ul li a:hover {
  color: var(--subColor);
  border-color: var(--subColor);
}

リスト項目のリンクは、ボーダーを使用して装飾しています。リスト項目のリンクにマウスが載っている状態(a:hover)では、文字色とボーダーの色を変更しています。CSS変数を利用していない場合は、値にカラーコードを入れてください。

リンクの装飾としてはすでにtext-decoration-line: underline;で下線を入れてる状態ですが、リスト項目内のリンクではtext-decoration: none;として下線を消しています。

paddingは時計回りの順で指定します。右が50pxと他の指定値より大きい値ですが、これはのちほどこの部分に矢印アイコンを固定するため、その分多めに余白を指定しています。

borderプロパティ

borderプロパティは、要素の境界(ボーダー)を一括指定するプロパティです。以下のプロパティと値を指定できます。

  • border-width:ボーダーの幅を指定する
  • border-style:ボーダーのスタイルを指定する(以下値は一部のみ記載)
    • none:ボーダーを表示しない(初期値)
    • solid:通常の一本線
    • double:二重線
    • dotted:ドット線
    • dashed:破線
  • border-color:ボーダーの色を指定する(指定できる値はcolorプロパティと同じ)

border-widthborder-styleborder-colorもまた要素の上下左右を一括指定するプロパティです。border-widthを例にとると、以下のように指定できます。

border-width: 2px; /* 上下左右すべて2px */
border-width: 5px 10px; /* 上下5px、左右10px */
border-width: 5px 3em 20px; /* 上5px、左右3em、下20px */
border-width: 1px 4rem 5px 2px; /* 上1px、右4rem、下5px、左2px(時計回りで指定する) */

borderは上下左右を同じ値で一括指定するプロパティですが、上辺だけ、右辺だけボーダーを指定したいという場合は、以下のプロパティを使用します。

  • 上辺:border-topborder-top-widthborder-top-styleborder-top-color
  • 右辺:border-rightborder-right-widthborder-right-styleborder-right-color
  • 下辺:border-bottomborder-bottom-widthborder-bottom-styleborder-bottom-color
  • 左辺:border-leftborder-left-widthborder-left-styleborder-left-color
  • 上辺と下辺:border-blockborder-block-widthborder-block-styleborder-block-color
  • 左辺と右辺:border-inlineborder-inline-widthborder-inline-styleborder-inline-color

この状態でstyle.cssを保存し、index.htmlをブラウザで開くと、以下のように表示されます(リスト項目のみ抜粋)

a要素にスタイルをあてた状態のindex.htmlのキャプチャ画面

リスト項目のリンク部分にスタイルをあてたはずですが、見るからに崩れてしまっています。a要素の子要素にテキストやimg要素以外の要素、たとえばdiv要素やh要素、ul要素などを入れる場合は、もうひとつ指定するべきプロパティが存在します。

displayプロパティ

displayプロパティは、要素の振る舞い、「要素をどのように扱うか」を指定するプロパティです。指定できる値のうち、代表的なものは以下です。

  • none:要素を非表示にする(要素の高さもなくなる)
  • block:要素をブロックとして扱う(要素の前後に改行を生成する)
  • inline:要素をインラインとして扱う(ブロック要素をインラインとした場合、前後の改行は削除される)
  • inline-block:要素をブロックとして扱うが、インラインのような振る舞いもする
  • table:要素をテーブル(table要素)として扱う
  • flex:要素をフレックスモデル(レイアウト)として扱う
  • grid:要素をグリッドモデル(レイアウト)として扱う

このうち、table flex gridについてはここでは取り上げず、別の機会に解説します。none block inlineについては以下の図もご参考ください。

blockとinline、noneの説明

HTML要素は基本的に「ブロック要素」か「インライン要素」のどちらかに属していますが、displayプロパティによってその所属を変更することが可能です。

インライン要素のものは、今回のa要素のように、pulなどのブロック要素を内包すると、CSSを記述してスタイルをあてた際にレイアウトが崩壊してしまうことがあります。この場合は、インライン要素にdisplay: blockを宣言してブロック要素にすることで、レイアウトの崩壊を防ぐことが可能です。

前置きが長くなりましたが、先ほどのリンク部分のCSSにdisplayプロパティを追加します。

.main ul li a {
  padding: 15px 50px 15px 15px;
  text-decoration: none;
  background-color: var(--whiteColor);
  border: 1px solid var(--baseColor);
  border-radius: 5px;
  display: block; /* 追加 */
}

a要素はインライン要素なので、ブロック要素に属性を変更します。

この状態でstyle.cssを保存し、index.htmlをブラウザで開くと、以下のように表示されます。

a要素にdisplay: blockを追加した状態のindex.htmlのキャプチャ画面

レイアウト崩れが解消されました。

blockプロパティや「ブロック要素」「インライン要素」というのは最初のうちはよくわからないものだと思いますが、とりあえず、「a要素の中にh要素やp要素などが入る場合は、CSSでa要素に対してdisplay: block;と宣言する」と覚えておくとよいかと思います。

見出しとテキストのスタイルを調整する

サイト名とテキストのスタイルを調整します。といっても、ここでは見出しのスタイルを整えるのみです。

テキストの大きさはbody要素から継承したフォントサイズ(1rem=16px)のままでいったん問題ないので、CSSの記述はありません。

.main ul li h3 {
  font-size: 1.15em;
}

.main ul li h3 .ph-fill {
  margin-right: 5px;
}

本ハンズオンで使用しているアイコンはフォントなので、h3要素に指定したfont-size: 1.15em;の値(基準となる1rem=16pxをおよそ1.15倍した値)が適用されます。

サイズ感が気になるようでしたら、h3 .ph-fillに対してさらにfont-sizeプロパティで調整してください。この場合の基準となる値は、親要素であるh3要素の値(1rem=16px * 1.15 = 18.4)です。

この状態でstyle.cssを保存し、index.htmlをブラウザで開くと、以下のように表示されます。

a要素にdisplay: blockを追加した状態のindex.htmlのキャプチャ画面

矢印アイコンの位置を調整する

さて、いよいよ大詰めです。最後に残った矢印アイコンの位置を調整します。表示位置は、リスト項目の右側余白部分の中央です。

矢印アイコンの表示位置説明のキャプチャ画面

この部分に指定の要素(今回の場合は矢印アイコン)をもってくるCSSの書き方もいくつかありますが、ここではpositionプロパティを利用して配置します。

要素を任意の場所に配置するpositionプロパティ

さきほどdisplayプロパティの項目で述べたとおり、HTML要素は基本的に「ブロック要素」か「インライン要素」のどちらかに属しており、配置は縦積み(ブロック要素)か横並び(インライン要素)が基本です。

positionプロパティは要素の配置方法を定義するプロパティです。positionの値で要素の配置方法を指定し、top right left bottomといったプロパティで要素の位置を調整します。

positionプロパティで指定できる値は以下です。

  • static:要素は縦積み(ブロック要素)か横並び(インライン要素)で配置される(topなどの位置調整の値はすべて無視される / 初期値)
  • relative(相対配置):要素は縦積み(ブロック要素)か横並び(インライン要素)で配置される(topなどの値は、要素の配置位置を基点とする)
  • absolute(絶対配置):要素はstatic以外のpositionが指定された親要素(あるいはさらにその親要素)の配置位置を基点として、topなどで指定した値で配置される
  • fixed(絶対配置):要素は完全に独立して、topなどで指定した値で固定配置される(スクロールしても移動しない)
  • sticky(粘着配置):要素はstaticと同じ配置だが、スクロールが発生し要素の位置までスクロールがくると、親要素の配置位置を基点として、topなどで指定した値で固定配置される(親要素がスクロールアウトすると一緒にスクロールアウトする)

また、位置の指定はtop right bottom leftというプロパティのほか、これらをまとめて指定できるinset inset-block inset-inlineというプロパティで行います。

/* 上0、左-5pxの位置 */
top: 0;
left: -5px;

/* した5%、右2%の位置 */
bottom: 5%;
right: 2%;

/* 上下左右0の位置 */
inset: 0;

/* 上3px、下5pxの位置 */
inset: 3px 5px;

/* 上5px、左右10px、下10pxの位置 */
inset: 5px 10px 10px;

/* 上下0の位置 */
inset-block: 0;

/* 上10%、下5%の位置 */
inset-block: 10% 5%;

/* 左右0の位置 */
inset-inline: 0;

/* 左3em、右5emの位置 */
inset-inline: 3em 5em;

positionプロパティを図解してみました。

positionプロパティの説明

文章で説明されてもあまりピンとこないかもしれません。MDNの説明ページに実装サンプルがあるので、挙動をご確認ください。

(当サイトでも後日改めて詳細を解説する予定です)

アイコンの位置を調整する

それではいよいよアイコンの位置を調整します。まず位置指定以外のCSSを記述します。

アイコンはフォントなので、font-sizeで大きさを指定します。また、widthプロパティとheightプロパティに同じ値を入れておきます。

.main ul li a > .ph-fill {
  font-size: 18px;
  width: 18px;
  height: 18px;
}

CSSのセレクタのa > .ph-fillは、「a要素の直下(直属)にある(i要素の).ph-fill属性」を示しています。

HTML要素(あるいはclass属性値)同士を半角スペースで繋げて書くと、左側に書いた要素の配下にある指定要素すべてが対象になりますが、>を挟むと、左側に書いた要素の「直下(直属)にある指定要素」のみが対象になります。

直下セレクタ説明のキャプチャ画面

つづいて、リスト項目内でのアイコンの位置を指定します。先ほど書いたCSSに追加します。

.main ul li a > .ph-fill {
  font-size: 18px;
  width: 18px;
  height: 18px;
  position: absolute; /* 追加 */
  inset-block: 0; /* 追加 */
  right: 15px; /* 追加 */
}

positionプロパティの値はabsoluteとします(relativeでも調整できなくはないですが、かなり大変です)

inset-blockプロパティで上下の値を0とします。この値の説明は後述します。

rightプロパティで、右から15pxの位置を指定します。

この状態でstyle.cssを保存し、index.htmlをブラウザで開いてみます。結果は、以下のように表示されます。

矢印アイコンの位置を追加した状態のindex.htmlのキャプチャ画面

矢印アイコンがページ(表示画面)の上部、右から15pxの位置に配置されてしまっています(見た目上は1つしかありませんが、リスト項目の数(ここでは3つ)重なって配置されています)

さきほど解説したように、position: absolute;を指定した要素は、「static値以外のpositionプロパティが指定された親以上の要素」を基点として配置されます。親以上の要素にpositionプロパティの指定がない場合は、さらに遡ってhtml要素(ルート要素)が起点になります。

現時点では矢印アイコンの要素(i.ph-fill)の親以上の要素にはpositionプロパティの指定がないので、html要素が基点となり、ブラウザ表示画面の右上に配置される結果になっています。

矢印アイコンがリスト項目の枠内に配置されるよう、CSSに追記します。追加の記述は矢印アイコンの要素(i.ph-fill)の親要素であるa要素に対して行います。

.main ul li a {
  padding: 15px 50px 15px 15px;
  text-decoration: none;
  background-color: var(--whiteColor);
  border: 1px solid var(--baseColor);
  border-radius: 5px;
  position: relative; /* 追加 */
  display: block;
}

position: relative;を追加しました。このa要素自体の配置は調整する必要がないので、topなどで値を指定する必要はありません。

この状態でstyle.cssを保存し、index.htmlをブラウザで開いてみます。結果は、以下のように表示されます。

矢印アイコンの位置を追加した状態のindex.htmlのキャプチャ画面

矢印アイコンがそれぞれのリスト項目内に戻ってきました。ただし、配置は右から15pxの位置にあるものの、リストの上部にくっついてしまっています。

先のチャプターでコンテンツ幅を中央配置した際にも解説したように、横幅を指定している要素をちょうど中央に配置するには、左右の余白を「親要素の幅から中央配置する要素の幅を引いた値」をちょうど半分ずつで分ける必要があります。縦に中央配置する場合も同様で、上下の余白を「親要素の幅から中央配置する要素の幅を引いた値」をちょうど半分ずつで分けます。

今回は縦方向に中央配置なので、上下の余白を指定できるmargin-blockプロパティを指定します。値をautoとすることで、上下均等に「親要素の幅から中央配置する要素の幅を引いた値」を自動で算出してくれます。

.main ul li a > .ph-fill {
  margin-block: auto; /* 追加 */
  font-size: 18px;
  width: 18px;
  height: 18px;
  position: absolute;
  inset-block: 0;
  right: 15px;
}

この状態でstyle.cssを保存し、index.htmlをブラウザで開くと、以下のように表示されます。

矢印アイコンの位置を追加した状態のindex.htmlのキャプチャ画面

矢印アイコンが無事にリスト項目の縦方向中央に配置されました。

positionプロパティの指定でHTML要素が中央配置になるのはCSSの仕様

position: absolute;と上下あるいは左右のmargin値がautoの場合に中央配置になるのは、CSSの仕様によるものです。以下の条件が成立する場合に、要素が中央配置されます。

  1. 以下それぞれの値がauto以外であること
    1. topbottomおよびheighttopbottomはまとめてinset-blockでも可 / この条件を①)
    2. leftrightおよびwidthleftrightはまとめてinset-inlineでも可 / この条件を②)
  2. 以下それぞれの値がautoであること
    1. ①の場合においてmargin-topmargin-bottom(あるいはまとめてmargin-blockでも可)
    2. ②の場合においてmargin-leftmargin-right(あるいはまとめてmargin-inlineでも可)

上記の条件でいうと、topbottomleftrightの値は0である必要はありませんが、0とすることが多いです。

左右中央配置の場合、配置する要素がブロック要素であれば、widthmarginの指定のみで、他のプロパティの指定は必要ありません(先のチャプターで行ったコンテンツ幅の中央配置がこの例です)

上下中央配置の場合は、CSSの仕様で「margin-topまたはmargin-bottomの値がautoの場合、マージンの使用値は0となる」となるため上記2の条件を満たせず、この場合はpositinプロパティの指定が必須となります。

なお、この場合positionの値は以下の理由によりabsoluteを指定します。

  • statictop bottom left right(あるいはinsetも含む)の値は無視されるため1の条件を満たせない
  • relative:親要素を基点するのではなく自身の位置を基点とするため、親要素に対して中央配置ができない
  • fixed:中央配置は可能だが、完全に独立して表示領域に対して中央配置となるため(親要素のrelative を受け付けないため)
  • sticky:親要素を基点するのではなく自身の位置を基点とするため

ここまでに記述したコード

ここまで記述したCSSファイルの中身です。

@charset "utf-8";

/* font@google */
@import url('https://fonts.googleapis.com/css2?family=Fascinate+Inline&display=swap');


/* ============================ */
/*  reset
/* ============================ */

body, p, h1, h2, h3, ul, li, figure, small {
  margin: 0;
  padding: 0;
}

* {
  box-sizing: border-box;
}

img {
  vertical-align: middle;
  max-width: 100%;
  height: auto;
}


/* ============================ */
/*  base
/* ============================ */

:root {
  --baseColor: #143d60;
  --subColor: #eb5b00;
  --whiteColor: #fefefe;
  --bgColor: #fdfbee;
}

html {
  scroll-behavior: smooth;
}

body {
  color: var(--baseColor);
  font-size: 1rem;
  font-family: 'Hiragino Kaku Gothic ProN', 'Hiragino Sans', Meiryo, sans-serif;
  line-height: 1.8;
  background-color: var(--bgColor);
}

h1,
h2 {
  margin-bottom: 10px;
  color: var(--subColor);
  font-weight: 400;
  font-style: normal;
  font-family: 'Fascinate Inline', system-ui;
  text-align: center;
}


/* ============================ */
/*  link
/* ============================ */

a {
  transition: all 0.3s;
}

a:link,
a:visited {
  color: var(--baseColor);
  text-decoration-line: underline;
  text-decoration-color: var(--subColor);
  /* text-decoration: underline var(--subColor); /* Safari以外は一括指定でも可 */
}

a:hover,
a:active {
  color: var(--subColor);
  text-decoration: none;
}


/* ============================ */
/*  .wrapper
/* ============================ */

.wrapper {
  margin: 40px auto;
  width: 90%;
  max-width: 550px;
  /* width: min(90%, 550px); /* ←まとめてこのように書くこともできます */
}


/* ============================ */
/*  .header
/* ============================ */

.header {
  margin-bottom: 40px;
}

h1 {
  font-size: 2.5em;
}

.prof_icon {
  margin: 0 auto 20px;
  width: fit-content;
  border-radius: 50%;
  overflow: hidden;
}


/* ============================ */
/*  .main
/* ============================ */

.main {
  margin-bottom: 40px;
}

h2 {
  font-size: 2.25em;
}

.main ul li {
  margin-bottom: 15px;
  list-style: none;
}

.main ul li a {
  padding: 15px 50px 15px 15px;
  text-decoration: none;
  background-color: var(--whiteColor);
  border: 1px solid var(--baseColor);
  border-radius: 5px;
  position: relative;
  display: block;
}

.main ul li a:hover {
  color: var(--subColor);
  border-color: var(--subColor);
}

.main ul li h3 {
  font-size: 1.15em;
}

.main ul li h3 .ph-fill {
  margin-right: 5px;
}

.main ul li a > .ph-fill {
  margin-block: auto;
  font-size: 18px;
  width: 18px;
  height: 18px;
  position: absolute;
  inset-block: 0;
  right: 15px;
}

以上でmain要素のCSS記述はいったん終了です。おつかれさまでした。positionプロパティによる配置の概念は、かなり難解だったかもしれません(思った以上に長くなってしまいました…)

次はfooter要素にCSSをあてます。

参考情報など

このチャプターで解説したCSSのプロパティや値などについて、詳細を知りたい場合は、以下MDN (MDN Web Docs)のドキュメントなどもご覧ください。

また、今回説明したpositionプロパティのCSSの仕様については以下のサイトに掲載があります。

results matching ""

    No results matching ""