###### tags: `HTML` `CSS`
# ホームページ制作 - テンプレート作成編
いよいよ大詰めです!
今まで学んだことをフル活用していきましょう!
ただ,すべて自分でコーディングできればいいですが,そうもいかないと思うので,まずは見ながら自分の手でコーディングすることをやってみましょう!
そうしていくうちに,だんだんとパターンのようなものが分かってくるものです.
今まで学んできたプロパティたちが,お互いにどう作用しあうのかを体感していきましょう!
## 目標の確認
アクセスしてみてください!
https://yosse95ai.github.io/
## もくじ
- [フォルダ構成](#フォルダ構成)
- [HTMLテンプレート](#HTMLテンプレート)
- [フォントの導入](#フォントの導入)
- [ページ全体の配色](#ページ全体の配色)
- [ヘッダーを作る](#ヘッダーを作る)
- [フッターを作る](#フッターを作る)
- [メインの枠を作る](#メインの枠を作る)
- [テンプレートファイルに退避](#テンプレートファイルに退避)
- [まとめ](#まとめ)
## フォルダ構成
自分の`github.io`を以下のフォルダ構成にします.
<div style="display:flex;
flex-wrap: wrap;">
<pre style="flex:1;height:300px;overflow:hidden;">
<code>
{yourname}.github.io/
│ index.html
│ about.html
│
├──styles/
│ index.css
│ about.css
│ style.css
│
└──img/
icon.jpg
qiita.png
</code>
</pre>
<div style="height:300px;display:flex;justify-content:center;">
<img src="https://i.imgur.com/QKfnRM3.png" >
</div>
</div>
### 役割
- `index.html`
- Index ページ (ホームページの顔)
- `about.html`
- About ページ (自己紹介)
- `style.css`
- 全体のスタイル
- `index.css`
- index.html固有のCSS
- `about.css`
- about.html固有のCSS
- `icon.png`
- 好きな画像(できれば正方形)
- `qiita.png`
- Qiitaのロゴ(後述)
## HTMLテンプレート
以下はすべてのページ (HTML) の初期テンプレートとなります.
一旦`index.html`にコピペしてください.
以降は`index.html`を編集しているものとしてとらえてください.
```htmlembedded
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="description" content="○○のHomeページです">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#333" />
<link rel="stylesheet" href="https://unpkg.com/modern-css-reset/dist/reset.min.css" />
<link rel="stylesheet" href="styles/style.css">
<title>○○</title>
</head>
<body>
<header>
<!-- header の内容を書く -->
<!-- 基本的に近い回し -->
</header>
<main>
<!-- main コンテンツの内容を書く -->
</main>
<footer>
<!-- footer の内容を書く -->
<!-- 基本的に近い回し -->
</footer>
</body>
</html>
```
CSSリセットとして,`modern.css` を今回は使っていきます.
## フォントの導入
デフォルトで適用されているフォントではなく,好きなフォントを使っていきたい.
Google Font などのCDNで簡単に導入できるものを今回紹介します.
### Google Fontにアクセス
https://fonts.google.com
### フォントをクリック
今回は以下を選択します.
- Roboto
- 英文用フォント
- https://fonts.google.com/specimen/Roboto
- M PLUS 1p
- 和文用フォント
- https://fonts.google.com/specimen/M+PLUS+1p?subset=japanese
### 各ウェイトの⊕で追加
以下は,`Roboto` での例ですが,すべての⊕をとりあえず選択しておきましょう!
`M PLUS 1p` も同様にすべて選択でOKです.

### CSSにインポート
すべての ⊕ 選択が終わったら,右上のアイコンをクリックします.

`Use on the web` の項目を `link` から `@import` に切り替えます.

スタイルタグの示してあるところがあると思うので,`@import` の内容だけコピーします.
正しく選択できていたら,以下と同じ内容になると思います.
```css
@import url('https://fonts.googleapis.com/css2?family=M+PLUS+1p:wght@100;300;400;500;700;800;900&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
```
この一文を,`style.css` の最上部にコピペします.
### フォントの設定
これで,body 要素内に含まれるすべての文書が,以下のフォントが適用されます.
```htmlembedded
body {
font-family: 'Roboto', 'M PLUS 1p', sans-serif;
}
```
`font-family` では,指定したフォントが順にWebのフォントとして採用されます.
つまり,`Roboto` フォントが使用可能な言語だった場合,`Roboto` がまず採用され,日本語のように `Roboto` が使えない場合,一つ後ろの `M PLUS 1p` が使用可能か検討し,使えるなら日本語用として採用されます.
それでも使えなかった場合は,`sans-serif` が採用されます.
## ページ全体の配色
基本的に,Webページを作るときはデザイン案を書いて,それに従ってコーディングを行っていきます.
今回はそういう時間を取れない代わりに,配色だけ決めましょう.
[ColorHunt](https://colorhunt.co)や[ColorDrop](https://colordrop.io)などのサイトで好きな配色を決めてもいいですし,構想がある方はそれでも良いです!
### 配色
配色は主に三つの要素からなるといわれています.
- ベースカラー (70%)
- 最も大きな領域を占めるカラー
- メインカラー (25%)
- サイトを印象付けるカラー
- アクセントカラー (5%)
- ユーザーの目を引くために少ない箇所に使うカラー
「たった3色とは少ない!」と思う方もいるかもしれませんが,同じ色でも,`明るめ`,`暗め`という方向に色を増やすことができます.
> WEBサイトの配色は役割別に3つあり、それぞれに、ベースカラー、メインカラー、アクセントカラーと呼びます。各々の比率をベースカラー70%、メインカラー25%、アクセントカラー5%の割合にすると、美しい配色に仕上げることができます。
> 引用:https://www.m-hand.co.jp/design/4002/
### 今回用いる配色
あとで,自分の好きな色に変えてもらっていいのですが,今回の講座では以下の通りです.
- ベースカラー
- `#333333`
- light(`#3f3f3f`)
- メインカラー
- `#dada1f`
- dark(`#9a9a1f`)
- light(`#fafa1f`)
- アクセントカラー
- `#8f8ffa`
### テキストの色
テキストの色は,背景色に伴って選ばなければいけません.
今回,背景色をベースカラーとするため,文字色は`#dddddd`あたりにします.
真っ白にすると,まぶしく感じるので,色合いを少しだけくすませます.
### カスタムプロパティ
このような色を覚えておくのはとても大変です.
なので,覚えなくていいように定義してしまいます.
`styles`フォルダに,`root.css`ファイルを作成します.
内容を以下のようにします.
```css
:root {
--base: #333;
--base_light: #3f3f3f;
--main: #dada1f;
--main_light: #fafa8f;
--main_dark: #9a9a1f;
--acc: #8f8ffa;
--text: #ddd;
}
```
#### 定義の仕方
接頭辞に`--`をつけることでカスタムプロパティを定義できます.
> `:root` は CSS の擬似クラスで,文書を表すツリーのルート要素を選択するので,実質 `<html>` 要素と同等ですが,疑似要素なのでこちらの方が詳細度が高いです.
> 参考:[CSSカスケ―ディングスタイルシート > :root](https://developer.mozilla.org/ja/docs/Web/CSS/:root)
#### カスタムプロパティの読み取り
カスタムプロパティの値を読み取るためには,CSSファイル内で`root.css`ファイルをインポートし,`var(--base)` のようにして値を指定することができます.
> CSSの`var()`関数は,他のプロパティの値の一部に代わってカスタムプロパティの値を挿入できるものです.
> 参考:https://developer.mozilla.org/ja/docs/Web/CSS/var
#### カスタムプロパティを使用
まずは,`root.css`ファイルを読み込みます.
フォントのインポートの下の行に
```css
@import url('./root.css');
```
を追加します.
`body`の色を,変えてみましょう!
```css
body {
font-family: 'Roboto', 'M PLUS 1p', sans-serif;
background-color: var(--base);
}
```
こんな感じで使います!
## ヘッダーを作る
ページヘッダーを作りこんでいきましょう!
ページヘッダーはすべてのページで共通なので,スタイルの宣言は `style.css` に書きます.
### 目標物
まずは,どんなヘッダーにするか決めます.
本来は自分でデザインするのですが,時間の都合上以下のようなものをゴールにします.黒い部分がヘッダーです.

- HTML
1. アイコンに触れると`index.html`に飛ぶ
1. `Home`に触れると`index.html`に飛ぶ
1. `About`に触れると`about.html`に飛ぶ
1. `???`は自分で好きなページを作ってもらうので一旦保留
- CSS
1. ヘッダーの最小高は`80px`
1. 左にアイコン,右にナビゲーションメニューがある
1. ナビゲーション間は`15px`
1. アイコンサイズは`50x50(px)`
1. ヘッダー内部に`上左右: 30px`のパディング
2. すべての要素が横並び
### HTML
まずは,必要なマークアップを揃えましょう!
`header` 要素内をマークアップします.
```htmlembedded
<header>
<div class="icon_wrapper">
<a href="./index.html">
<img src="img/icon.jpg" alt="icon">
</a>
</div>
<nav class="right_content">
<a href="./index.html">Home</a>
<a href="./about.html">About</a>
<a href="#">????</a>
</nav>
</header>
```
ここで,`nav`要素とは,`div`のようなブロックレベル要素で,その要素内がナビゲーションであることをブラウザに伝えます.
スタイルの扱いとしては`div`と同じとように考えればOK.
また,いい感じのアイコンがない人は,以下にアクセスしてアイコンをダウンロードし,仮置きしておいてください.
https://pictogram2.com/?p=424
後で好きな画像に置き換えればOKです.
名前は`icon`,拡張子は`jpg`のものを`img`フォルダにダウンロードすれば書き換えは必要ないですが,それ以外の名前,拡張子の人は`src="img/icon.jpg"`を書き換えてください.
:::info
ダウンロードがめんどくさい人は,`src="https://pictogram2.com/p/p0146/6.png"`でもいいです.
:::
### CSS
`style.css`に記述していきます.
#### アイコンの宣言
```css
.icon_wrapper {
width: 50px;
height: 50px;
background-color: #fff;
border: 1px solid var(--main);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
```
アイコンは円形(`border-radius: 50%;`)になります.
しかし画像自体は正方形なので,はみ出し分を見えなくする(`overflow: hidden;`)ことでいい感じになります.
`border`の色の部分で,カスタムプロパティの値(`#dada1f`)を読み取っています.
#### ヘッダー全体の宣言
```css
header {
position: sticky;
top: 0;
right: 0;
left: 0;
min-height: 80px;
padding: 30px 30px 0 30px;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
background-color: black;
}
```
::: success
`background-color: black;`は後々消しますが,CSSの適用範囲が分かりやすいようにするために,色を付けます.
:::
#### ナビゲーションメニューの宣言
右に配置するコンテンツなので,`.right_content`です.
```css
.right_content {
display: flex;
flex-wrap: wrap;
}
```
`display: flex;` と `flex-wrap: wrap;` で画面のサイズ変化にも対応しています.
#### 文字色とスペース
ナビゲーションの文字色と文字間のスペースを宣言します.
```css
a {
text-decoration: none;
}
.right_content a {
font-size: 1.2em;
font-weight: 600;
color: var(--main);
}
.right_content a:not(:nth-child(n + 3)) {
padding-right: 15px;
}
```
`text-decoration: none;` で `a` 要素にデフォルトでついている`下線`を消します.
`a:not(:nth-child(n + 3))`のセレクターの意味を説明します.
まず`:not()`で`a`要素のうち`()`内の条件を**満たさないもの**にスタイルを当てると宣言します.
そして,`:nth-child(n + 3)`の`n`には`0以上`の任意の数が入ると想像してください.
この場合,0+3=3,0+1=4,…となっていきます.
要素のうち,3番目以降のものに対してスタイルが充てられます.
以上のことから,`a:not(:nth-child(n + 3))`の意味は,
<p style="color:#daa">
「a要素のうち,3番目以降のa要素 <b>でないもの</b> にスタイルを宣言する」
</p>
つまり,
<p style="color:#9d9">
「a要素のうち,1番目と2番目にスタイルを宣言する」
</p>
となります.
なので,1番目と2番目の要素の「右側」だけに「`padding-right: 15px`」が効くということです.
3番目の`a`要素(???の部分)の右側には`padding-right: 15px`は効いていません.
少し難しいですが,いろいろと使いこなすと表現の幅が広がります!
ただ,やれる事が多すぎてこの講座では紹介はこれだけにとどめます.
:::info
さらに詳しく知りたい方は,`疑似クラス`で調べてください.
`:not()`:https://developer.mozilla.org/ja/docs/Web/CSS/:not
`:nth-child()`:https://developer.mozilla.org/ja/docs/Web/CSS/:nth-child
`疑似クラス`:https://developer.mozilla.org/ja/docs/Web/CSS/Pseudo-classes
:::
### 完成状態
最後に,`header`の`background-color: black;`を消せば完成です!
こんな感じ!
<iframe height="300" style="width: 100%;" scrolling="no" title="header" src="https://codepen.io/yosse95ai-the-decoder/embed/wvyZzqG?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/wvyZzqG">
header</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
## フッターを作る
今回作るフッターは本当にお飾り程度(けど,あると締まる)です.
内容もほとんどないですが,`footer`要素内に以下をマークアップしてください.
### HTML
```htmlembedded
<footer>
<p>© 2022. ○○. All rights reserved.</p>
</footer>
```
`○○`の部分は自分の名前やペンネームを記載してください.
これで,このページの持ち主を明示できます.
ただ,日本ではいらないみたいな話もありますので,お飾り程度と思ってもらっても構いません.
### CSS
```css=
footer {
height: 30px;
display: flex;
justify-content: center;
color: var(--main);
font-weight: 200;
font-size: 14px;
background-color: black;
}
```
::: success
`background-color: black;`は後々消しますが,CSSの適用範囲が分かりやすいようにするために,色を付けます.
:::
### 完成状態
このままだと,こんな感じになります.
<iframe height="300" style="width: 100%;margin-bottom:10px" scrolling="no" title="footer-1" src="https://codepen.io/yosse95ai-the-decoder/embed/oNEOYzX?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/oNEOYzX">
footer-1</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
これは,ヘッダーとフッターの間のコンテンツ(`main`)が空っぽだからです.
メインコンテンツの高さの最小を決めてあげることでこれに対処します.
## メイン(の枠)を作る
メインが収まるための枠を作ります.
#### HTML
変わりません.
#### CSS
最小の高さを,以下の式にします.
$$
メインの最小高=画面表示領域-(ヘッダーの最小高+フッターの高さ)
$$
つまり
$$
メインの最小高=画面表示領域-(80px+30px)
$$
こうすることで,「メイン内の最小高」と「ヘッダー」・「フッター」の高さを足すと,画面いっぱいになるように設定できます.
ただし,iOS の Safariでは,`100vh(画面の表示領域いっぱいの高さ)`を指定しても,検索バーが考慮されないため正しく表示領域の値(vh)が使えません.
そこで,`100svh(検索バーを考慮した表示領域)`という新しめの単位があります.
こちら「も」使います.
```css
main {
min-height: calc(100vh - 110px);
min-height: calc(100svh - 110px);
}
```
これは,CSSのフォールバックという仕組みを使っています.
#### calc関数
これはCSSで計算をするときに用いる関数です.
`calc()`の`()`内に式を入れます.
> 参考:https://developer.mozilla.org/ja/docs/Web/CSS/calc
#### フォールバック
`svh` という単位はSafariで定義されている単位で,PCのChrome等には定義されていない単位です.
なので,`min-height: calc(100svh - 110px);`の計算ができない(iOS Safari以外でページを開いている)時は,2行目の計算が行われず,`min-height: calc(100vh - 110px);`が適用されます.
> svhの参考:
> [CSSの新しい単位「lvh」「svh」これでiOSのSafariで100vhがビューポートの高さではない仕様に対応できる](https://coliss.com/articles/build-websites/operation/css/large-small-dynamic-viewports.html)
Devツールで見てみるとこんな感じです.(PCのChrome)

### 完成状態
`footer` の `background-color: black;`を消して完成です.
<iframe height="350" style="width: 100%;" scrolling="no" title="Untitled" src="https://codepen.io/yosse95ai-the-decoder/embed/eYVoBoO?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/yosse95ai-the-decoder/pen/eYVoBoO">
Untitled</a> by yosse95ai (<a href="https://codepen.io/yosse95ai-the-decoder">@yosse95ai-the-decoder</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
## テンプレートファイルに退避
ここまでで作ってきたHTMLファイルはすべてのページ(`index.html`,`about.html`)で共通なので,別ファイルに退避しておきます.
`index.html`と同じ階層に,`tmp.html`を作成して,作成したHTMLファイルをコピペします.

将来的にページを増やしたい時など,このテンプレートをコピペして,それをもとに作っていくことができます.
### .gitignore
`.gitignore`ファイルを同じ階層に作成してください.
そして内容を以下の通りにしてください.
```
tmp.html
```
このファイルの存在自体を知っておくのは大事なことです!
(大体のWebフレームワークの自動生成プロジェクトに含まれている)
これで,`tmp.html`ファイルがコミットに含まれなくなります.
(あまり意味の無いファイルはコミットに含めたくない)

## まとめ
ここまでで,HTMLファイルのテンプレートと`style.css`を作成してきました.
`Indexページ`と`Aboutページ`を次から編集していきます.
- [Indexページ編](https://hackmd.io/@kit-web-team/homepage-index)
- [Aboutページ編](https://hackmd.io/@kit-web-team/homepage-about)