【保存版】Webフロントエンド基礎力（初心者向け）

ブラウザで動くWebページのプログラミング実装をフロントエンドと呼びます。
最近はJSON色つけ係と呼ばれてたりしますが、
Web開発未経験・初心者向けに最低限知っておいたほうが良い基礎知識とテクニックに関して体系的にまとめておきます。
（CodePenによる動作例付き）

環境構築に関しては[（兎に角）早くプロトタイプを作る技術（初心者向け）](https://qiita.com/teradonburi/items/1d629a751ed42e923d7d)を参考にしてください。

HTML、CSS、JavaScriptはブラウザ自体の実装に依存します。
この記事では比較的汎用的に使える書き方やHTML、CSS、JSを記載したつもりですが
最新のJavaScript APIやCSS3の機能によってはブラウザによってサポートされていない機能もあります。（特にIE）
各機能に関しては[Can I use](https://caniuse.com/)で現在のブラウザの対応状況を確認することができます。

# HTML
HTML(Hyper Text Markup Language)は、ウェブページを作成するために開発された言語です。
現在、インターネット上で公開されてるウェブページのほとんどは、HTMLで作成されています。
タグと呼ばれる`<>`で囲われた命令文で記述します。
`<>子要素</>`のような階層構造を記述できる形式になっています。
ブラウザはHTML構造を解釈して内容を画面上に表示（レンダリング）します。
DOM(Document Object Model)とも呼びます。

## 基本構造

```html
<div>
 子要素
</div>
```

入れ子で階層的に書くことができます

```html
<div>
  <div>
    <div>
      要素1
    </div>
  </div>
  <div>
   要素2
  </div>
</div>
```

特に子要素がない場合は、末尾`/>`でクロージングします（セルフクロージング）

```html
 <div/>
```

## よく使うタグ

- html: HTMLページであることを示すタグ
- title: ページのタイトルを記述するためのタグ
- meta: ページのメタ情報を記述するためのタグ
- head: ページのヘッダー部分を記述するためのタグ
- body: ページのボディ（メイン）部分を記述するためのタグ
- div: ブロックの塊を示します、レイアウトを組むときに主に使います。
- ol: 順序ありリスト
- ul: 順序なしリスト
- details, summary, dl: 展開式の要素です。summaryに展開するタイトル、dlに展開する子要素を記述します。
- table, tbody, th, tr, td: テーブル要素、thに見出し、tr単位に行作成、tdに内容を記述します。
- h1, h2, h3, h4, h5, h6: 見出し要素、h1, h2...の数字が大きくなるにつれて見出しが小さくなります。
- p: パラグラフ、文章を記載します。
- span: デザイン微調整によく利用されるタグ（インライン要素）
- form: フォーム要素。ユーザに入力してもらったデータをサーバに送信する用途で使います。
- label: ラベル要素。フォーム要素の中で使われることが多いです。
- input: 入力欄要素。フォーム要素の中で使われることが多いです。
- button: ボタン要素。ユーザインタラクティブのトリガーとして使われます。
- a: ハイパーリンク要素。別ページへのリンクやページ内リンク（アンカーリンク）として使われます。
- img: イメージ要素
- audio: 音声プレイヤー要素
- video: 動画プレイヤー要素
- canvas: 2D、3Dのグラフィックを描画するための領域
- style: スタイル要素（CSS等）
- script: スクリプト要素（JavaScript等）

## ブロックレベル要素、インライン要素
タグにはブロックレベル要素のタグ、インライン要素のタグがあります。
一般的なブラウザではブロックレベルの要素のタグは改行され、インライン要素のタグは改行されません。
ブロックレベル要素の子要素にインライン要素のタグを子要素にできますが、
インライン要素のタグにブロックレベル要素のタグを子要素にしてはいけません。
（ブロック要素のタグの文章などを記載するのがインライン要素のタグの役割）

参考：[ブロックレベル要素とインライン要素](http://www.htmq.com/htmlkihon/005.shtml)

## 属性値（attribute）

タグの種別によって属性値をもつ場合があります。
次の例はinputタグのtype属性値を指定する場合です。
type属性値にtextを指定すると入力欄が作成されます。

```html
<input type='text' placeholder='入力欄' />
```

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="XWWNVQq" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="input">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/XWWNVQq">
  input</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

type属性値にbuttonを指定して、value属性値に「ボタン」という文字を指定するとボタンに変わります。

```html
<input type='button' value='ボタン' />
```

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="jOOVYRm" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="button">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/jOOVYRm">
  button</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

このように属性値を変えることでタグの振る舞いが変わります。

## id
id属性を指定することで後述のCSSやJavaScriptからタグを参照することができます。
idはそのページでユニークな値にする必要があります。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="wvvomXR" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="id">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/wvvomXR">
  id</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## class
class属性を指定することで後述のCSSやJavaScriptからタグを参照することができます。
idと違って、複数のタグに対して指定することができ、一括でスタイルを適用したい場合などに重宝します。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="WNNozKW" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="class">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/WNNozKW">
  class</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## Webページの最低限のHTML構造
最低限のhtmlは次のようになっています。(HTML5)
metaタグのviewportに関してはモバイルでは割と必須感あるので最低限のものとして入れています。
`<!-- -->`で囲われた部分はコメントと呼び、ブラウザで処理されないコードです。

```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <title>タイトル</title>
    <!-- モバイル用の表示設定 -->
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
<body>
  <!-- ここに表示したいタグを追加 -->
</body>
</html>
```

基本的に次のような階層構造になっている必要があります。

```
- html
  - head
    - title 
    - meta
  - body
```

ほとんどのタグはbody部分に追加していきます。（主にページに表示されるタグ）

## div
コンテンツの塊の親要素として使う事が多いです。レイアウトの調整にも使います。
(CSS flexboxの項にて説明)

## リスト
olタグは順序ありリスト、ulタグは順序なしリストとして表示されます。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="BaapVpK" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="list">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/BaapVpK">
  list</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 展開式リスト
details, summary, sl, dtタグを使うことで展開式のリストの作成ができます

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="dyyNKRB" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="details">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/dyyNKRB">
  details</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 表
tableタグを使うことで表を作成することができます。
表のタイトルにcaptionタグ、見出しにthead、thタグ、表内容にtbodyタグ、行にtrタグ、tdタグなどを使います

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="BaapVmL" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="table">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/BaapVmL">
  table</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 見出し、パラグラフ、span
h1~h6は見出しタグです。数字が大きくなるにつれて小さくなります。
ちなみにページ先頭のh1タグにはGoogleの検索結果に表示されるという特性があります。
pタグには文章を書きます。
h、pタグはブロックレベル要素のため、改行されます。
h、pタグともにデフォルトで余白（margin、padding）があります。
spanタグはインライン要素のため、改行されずに横に並びます。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="jOOyKpa" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="h,p,span">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/jOOyKpa">
  h,p,span</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## リンク
aタグでリンクを作成できます。href属性でリンク先を指定、_blank属性で別タブで開きます。
idとhrefに#id名を指定することでページ内リンク（アンカーリンク）に飛ぶことができます。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="KKKaeOe" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="a">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/KKKaeOe">
  a</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## フォーム
フォーム入力欄を作成するにはformタグを使用します。
action属性にはデータを送信する先のurl(サーバAPI)を指定します。
method属性にはHTTPメソッドを指定します。通常はPOSTを指定します。（HTTPメソッドでよく使うものにはGET、POST、PUT、DELETEがあります）
enctype属性にはMIMEタイプを指定します。ファイル等まで全て添付して送信する場合はmultipart/form-dataを指定します。
送信する対象のデータに関しては、inputタグもしくはselectタグ、textareaタグのいずれかに対してname属性を指定します。
入力した内容はvalueパラメータとしてサーバに送信されます。
inputタグのtype属性は色々な種別の入力欄に対応しています。
注意したいのは、ブラウザによってinputタグの表示が異なることです。
（このため、入力のUIとしてライブラリを使うことも少なくありません）

- text: １行テキスト
- email: メールアドレス
- password: パスワード
- radio: ラジオボタン
- checkbox: チェックボックス
- range: スライダー
- number: スピナー
- color: カラーパレット
- date: 日付
- time: 時間
- file: ファイル
- hidden: 隠しパラメータ（入力欄としては表示しないがサーバに送信するパラメータ。value属性と併用することが普通でCSRF対策に主に使う）
- submit: 送信ボタン

複数テキストはtextareaタグ、選択リストタグはselect+optionタグを使います。
また、inputタグ、textareaタグにrequired属性をつけることで必須項目となります。
（入力欄が空の場合にsubmitボタンが押せない）

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="qBBraXP" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="form">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/qBBraXP">
  form</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 画像、音声、動画
画像の表示にはimgタグを使います。src属性に画像のurlを指定します。
音声ファイルの再生にはaudioタグを使います。src属性もしくはsourceタグのsrc属性を使い音源のurlを指定します。
（sourceタグは複数追加することができ、mp3以外の予備の音源を用意することで、mp3が再生できないブラウザでも再生できるようになります。）
controls属性を指定することでプレイヤーコントロールを表示させることができます。（プレイヤーのUIに関してはブラウザによって表示が異なるので注意）
動画ファイルの再生にはvideoタグを使います。audioタグとほぼ同じですがwidth, height属性で動画の表示サイズを変更できます。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="eYYRBpz" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="img, audio, video">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/eYYRBpz">
  img, audio, video</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

余談ですが、音声はmp3形式、動画がmp4形式のほうが再生できるブラウザが多いです。（大体のブラウザがサポートしている）

## canvas
JavaScriptと組み合わせて描画処理することが普通なのでJavaScriptの項目で説明

## style
styleタグにはCSSと呼ばれる、タグのスタイルやレイアウトを変更するためのスクリプトを記述できます（詳細はCSSの項で説明）
headタグの子要素として記述します。
styleタグ内に囲まれた部分でCSSを記述します。

```html
<head>
 <style type="text/css">
 p {
   color: red;
 }   
 </style>
</head>
```

外部のCSSファイル（.cssファイルとして保存できる）を呼び出す場合は、linkタグを使います。
href属性に読み込むCSSファイルを指定します。
rel属性はstylesheet、type属性にはtext/cssを指定します。

```html
<head>
 <link href="main.css" rel="stylesheet" type="text/css" />
</head>
```

## script
scriptタグの内部にはスクリプトを記述できます。JavaScriptの処理を記述できます。（詳細はJavaScriptの項で説明）

```html
<script>
 window.onload = function() {
   // DOMが読み込み完了したときの処理
 }
</script>
```

外部のJavascriptファイル（.jsファイルとして保存できる）を呼び出す場合は、src属性を使います。

```html
<script src='main.js'></script>
```

# CSS
HTMLタグのレイアウトの調整、装飾、アニメーションを担当するスクリプト言語です。
HTMLがページの構造だとすれば、CSSは表示の見た目（スタイル）を修正するための言語です。
CSSファイルをlinkタグで読み込む、styleタグ内にCSSを記述する、もしくはstyle属性でタグに直接指定（インライン）することができます。

```html
<div style='color:orange;'>要素</div>
```

## セレクタ
CSSのスタイルをタグに割り当てるには、どのタグを対象にするかという適応範囲をセレクタで指定します。
よく使われるセレクタに次のようなものがあります。

参考：[セレクタ](http://www.htmq.com/css3/#selector)

|名称|セレクタの書式|セレクタの対象|使用例|備考|
|---|---|---|---|---|
|全称セレクタ|*|すべての要素|* {color:red;}|影響範囲が広すぎるのであまり使わないほうが良い|
|要素型セレクタ|要素名|要素名で指定した要素|p {color:blue;}||
|idセレクタ|要素名#id名|id名が指定された要素|div#sample {color:green;}|影響範囲が明示的なので積極的に使いたい|
|classセレクタ|要素名.class名|class名が指定された要素|div.sample {color:green;}|影響範囲が明示的なので積極的に使いたい|
|擬似クラス|要素名:link|未訪問のリンク|a:link {color:black;}|基本的にaタグのみ使える|
||要素名:visited|訪問済のリンク|a:visited {color:red;}|基本的にaタグのみ使える|
||要素名:hover|カーソルが乗っている要素|a:visited {color:red;}||
||要素名:active|クリック中の要素|a:visited {color:red;}|基本的にクリック可能な要素で使える|
||要素名:focus|フォーカスされている要素|input:focus {background:grey;}|基本的にフォーカス可能な要素で使える|
||要素名:first-child|要素内の最初の子要素|h1:first-child {color:purple;}||
||要素名:last-child|要素内の最後の子要素|h1:last-child {color:purple;}||
||要素名:nth-child(n)|要素内のn番目の子要素|h1:nth-child(2) {color:purple;}||
|疑似要素|要素名:first-line|要素の最初の行|h2:first-line {color:green;}||
||要素名:first-letter|要素の最初の文字|h2:first-letter {color:red;}||
||要素名:before|要素の直前|h3:before {content:"『";}||
||要素名:after|要素の直後|h3:after {content:"』";}||
|属性セレクタ|要素名[属性名]|特定の属性を持つ指定要素|a[target] {color:pink;}||
||要素名[属性名="属性値名"]|特定の属性値を持つ指定要素|a[target="_blank"] {color:lightgreen;}||
||要素名[属性名~="属性値名"]|属性値候補（ホワイトスペース区切り）に属性値名を持つ要素|a[class*="sample"] {color:aqua;}||
||要素名[属性名*="属性値名"]|属性値候補に属性値名を持つ要素|a[class*="sample"] {color:aqua;}||
||要素名[属性名^="属性値名"]|属性値が属性値名で始まる要素|a[class^="sam"] {color:aqua;}||
||要素名[属性名$="属性値名"]|属性値が属性値名で終わる要素|a[class$="ple"] {color:aqua;}||
|複合セレクタ|セレクタ,セレクタ|複数のセレクタのスタイルを一括で指定|h4, h5 {color:black;}||
|子孫セレクタ|セレクタ セレクタ|下の階層の子孫要素|div section {color:black;}||
|子セレクタ|セレクタ>セレクタ|直下の階層の子要素|div > article {color:grey;}||
|隣接セレクタ|セレクタ+セレクタ|直後に隣接している要素|article + p {color:orange;}||
|後ろセレクタ|セレクタ~セレクタ|要素の後ろにある同じ階層の要素|h1 ~ p {color:orange;}||

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="yLLXVXJ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="cssセレクタ">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/yLLXVXJ">
  cssセレクタ</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### スタイルの優先順位と!important
ある要素が複数のセレクタから選択された場合にどのスタイルが適応されるか優先順位が決まっています。
（特に問題になるのが、複数のセレクタから同じスタイルを当ててる場合です。）

参考：[CSSセレクタの優先順位の計算方法](https://qiita.com/oh_rusty_nail/items/e896825cd54e5c0a3666)

次の例はcolorスタイルをdivに対して指定してます。
本来であれば、last-childのほうがclassに対して優先順位が低いのですが、!importantを付与することで優先順位が逆転しています。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="dyyRRML" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="!important">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/dyyRRML">
  !important</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

以下のように優先順位を覚えておくと良いでしょう
!important > タグのstyle属性（インライン） > id > class=属性セレクタ > その他
ただし、!importantは以下の点から極力使わないほうが良いでしょう

- 表示のパフォーマンスが落ちる（重複している無駄なスタイルを削除する方を優先したほうが良い）
- そもそもidやclassで代用できるはず
- !importantで書いてしまうと後勝ちの!importantでしか上書きできなくなる（このため、優先順位がわからなくなりCSSの修正が困難になる）

## width, height, margin, padding
タグ自体の幅、高さを指定するにはwidth, heightを使います。
外側の余白を指定するにはmargin、内側の余白を指定するにはpaddingを使います。

幅、高さ、余白に関しては単位指定します。
よく使う単位にpx,%,vw(vh)などがあります。

```css
width: 100px; /* px指定 */
width: 100%; /* (親要素に対する幅)%指定 */
width: 50vw; /* ビューポート（画面幅）に対する割合指定(100vwで画面全幅) */
height: 100px; /* px指定 */
height: 100%; /* (親要素に対する高さ)%指定 */
height: 50vh; /* ビューポート（画面高さ）に対する割合指定(100vhで画面全高さ) */
margin: 10px; /* 外側余白10px */
padding: 10px; /* 内側余白10px */
```

また、
min-width, min-heightで最小の幅、高さを指定
max-width, max-heightで最大の幅、高さを指定
することができます。
(width, heightの%と組み合わせることが多いです)

margin,paddingに関しては一括で指定する方法と個別に指定する方法があります。

```css
margin: 10px; /* 上下左右10px */
margin: 10px 5px; /* 上下10px左右5px */
margin: 5px 6px 7px 8px; /* 上5px右6px下7px左8px（時計周り） */
margin-top: 10px; /* 上10px */
margin-right: 10px; /* 右10px */
margin-bottom: 10px; /* 下10px */
margin-left: 10px; /* 左10px */
padding: 10px; /* 上下左右10px */
padding: 10px 5px; /* 上下10px左右5px */
padding: 5px 6px 7px 8px; /* 上5px右6px下7px左8px（時計周り） */
padding-top: 10px; /* 上10px */
padding-right: 10px; /* 右10px */
padding-bottom: 10px; /* 下10px */
padding-left: 10px; /* 左10px */
```

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="dyyRRwo" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="dyyRRwo">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/dyyRRwo">
  dyyRRwo</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## border
枠線を指定できます。
`border: border-width border-style border-color;`を指定します。

参考：[border-style](http://www.htmq.com/style/border-style.shtml)

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="jOOwLLX" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="border">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/jOOwLLX">
  border</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## background
タグの背景を指定します。
background-colorで背景色を指定します。
background-imageでurlと組み合わせて背景画像を指定します。
background-repeatで背景画像の繰り返しするか指定します。no-repeatだと繰り返ししません。
background-sizeで背景画像のタグに対してどの形式のサイズで表示されるかを決めます。
よく使うものでcontainだと背景画像のアスペクト比を保ったままタグの幅高さに合うように内側で表示されます。
coverだと背景画像のアスペクト比を保ったままタグの外側に背景画像が見切れて表示されます。
background-positionで背景画像の表示位置を決めます。centerはタグの中央に背景画像を表示します。
`background-size:contain; background-position:center;`もしくは`background-size:cover; background-position:center;`の組み合わせはよく使います。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="PoojeVa" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="background">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/PoojeVa">
  background</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

background-sizeによく似たスタイルにimgタグ、videoタグのobject-fitスタイルがあります。
こちらもかなり便利なのですが、IEで使えないという問題点があります。
(そのためpolyfillを入れて対応するなどの手段が必要になります。)

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="MWWoGdW" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="object-fit">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/MWWoGdW">
  object-fit</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## color, font-size, font-weight, line-height, text-align, letter-spacing
文字色を変えるにはcolorで色を指定します。
`blue`などの[カラーネーム](http://www.htmq.com/color/colorname.shtml)で指定するか、
`#FF0000`のような１６進数のカラーコードで指定します。（RGB）
font-sizeで文字のサイズを指定します。
font-weightで文字の太さを指定します。boldを指定すると太文字になります。
line-heightはテキスト同士の行間を指定することができます。
text-alignはテキストの並びを指定します。centerで中央寄せになります。
letter-spacingはテキストの文字間の余白を指定します。
注意点としては上記の文字に関するスタイルは子要素全てに適応されます。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="XWWgqLd" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="color, font-size, font-weight, line-height, text-align">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/XWWgqLd">
  color, font-size, font-weight, line-height, text-align</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## font-family, webfont
font-familyで表示するフォントを変更することができます。
実はOSで使えるフォントが違うため、フォントがなかった場合に予備のフォントを複数指定しておくと良いです。
また、独自のフォントファイル（ttf,woffなど）を読み込んで使うこと（WebFont）ができます。
[Google Fonts](https://fonts.google.com/)のようにホスティングで提供されている場合は
`@import`で読み込むことができます。
ファイルから読み込む場合は`@font-face`のsrcで読み込みます。

参考：[font-familyの書き方まとめ：CSSでフォント種類を指定しよう](https://saruwakakun.com/html-css/basic/font-family-how-to)
参考：[Font-familyメーカー](https://saruwakakun.com/font-family)

<p class="codepen" data-height="158" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="abbwaeB" style="height: 158px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="webfont">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/abbwaeB">
  webfont</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## position, left, top, right, bottom
positionは何を起点にした位置関係を指定します。
よく使うパターンは親要素を`position:relative;`にして子要素に`position:absolute;`の要素を作成します。
こうすることで親要素を起点に子要素のtop, leftの位置調整をすることでタグ同士を重ねることができます。
もう一つよく使うパターンは`position:fixed`でページ全体のフッターやヘッダーを指定する場合です。
ヘッダーの場合は`top: 0px;`、フッターの場合は`bottom: 0px;`で配置できます。
position:fixedになっているタグはスクロール時でもその位置が変わることはありません（スクロールに追従して同じ位置に残り続ける）
position:stickyになっているタグはスクロール時にそのタグが見切れるタイミングになるとfixedに切り替わります。
どこに残り続けるかの位置をtopもしくはbottomで指定します。
ただし、position:stickyはIEが対応していないことに注意が必要です。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="jOOwxgj" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="position">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/jOOwxgj">
  position</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## display,visibility
displayは要素の表示形式を指定します。
よく使われるものにインライン要素をブロックレベル要素に変更したり（display: block）
display:noneで要素を非表示にしたりします。
非表示でよく似ているスタイルに`visibility:hidden`がありますが、こちらはレイアウトの状態は残っているため、
span5の上にspan4の空白が残っています。
visibility:hiddenの使いみちとしてはhtmlメールなどの開封確認やページのアクセスログを送信するために
1x1pxのimgタグ（インプレッションピクセル）をvisibility:hiddenとして埋め込むなどの利用用途があります。
他によく使うdisplay:flex、display:gridに関しては後述します。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="jOOwKaP" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="display">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/jOOwKaP">
  display</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## flexbox
flexboxを使うには親要素にdisplay:flexを指定する必要があります。子要素が指定の配置になります。
flex-directionは子要素の配置の向きを指定します。flex-direction:rowで横方向、flex-direction:columnで縦方向の配置になります。
justify-contentは並べている向きに対して子要素をどちら側に寄せるか指定します。
justify-content:flex-startを指定すると並べる向きの開始位置に寄ります。
justify-content:centerを指定すると並べる向きの中央位置に寄ります。
justify-content:flex-endを指定すると並べる向きの終了位置に寄ります。
flex-directionの向きで縦横の寄せる向きが逆転していることに注意してください。
align-itemsは並べている向きの垂直方向（flex-direction:rowの場合は縦向き、flex-direction:columnの場合は横向き）に対して子要素をどちら側に寄せるか指定します。
align-items:flex-startを指定すると開始位置に寄ります。
align-items:centerを指定すると中央位置に寄ります。
align-items:flex-endを指定すると終了位置に寄ります。
こちらもflex-directionの向きで縦横の寄せる向きが逆転していることに注意してください。
flex-grow:1は子要素のサイズの伸び率を指定します。デフォルトは0ですが、並んでいる向きの子要素の累計で伸び率が決まります。
flex-growの値がそれぞれ、0 1 0だとした場合、flex-directionの向きに中央が全余白を埋めるように伸びます。
flex-wrapで折り返しするかの指定ができます。flex-wrap:wrapを指定すること折返しされます。
ただし、justify-content:centerを指定している場合、最後の行が左寄せにならないため、dummy要素を作成して穴埋めするというテクニックを使っています。
flexboxを駆使すればどんなレイアウトも柔軟に定義できるため、必修です。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="bGGRKvb" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="flexbox">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/bGGRKvb">
  flexbox</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

他にも色々flexbox関連のスタイルがありますが、それだけで１つの記事ができてしまうので
詳細は以下の記事などを参考にしてください。

参考：[もう迷わない！CSS Flexboxの使い方を徹底解説](https://webdesign-trends.net/entry/8148)

## grid
グリッド形式でレイアウト配置ができるため、大変便利なのですがIEは対応していません。
前述のflexboxで対応するか、polyfillで対応する必要があります。
グリッドレイアウトを使うには親要素にdisplay:gridを指定する必要があります。
grid-template-columnsにfr（フレーム）という単位で横方向のトラック数を指定します。
例えば、repeat(3, 1fr)は1frを３回繰り返すという意味なので`grid-template-columns: 1fr 1fr 1fr;`と同じになります。
grid-auto-rowsはトラック当たりの高さ、grid-auto-columnsはトラック当たりの幅を指定します。
column-gapはトラック間の縦方向の余白、row-gapはトラック間の横方向の余白を指定します。
各トラックがどれくらいのフレームを使うのかを
grid-column-start、grid-column-endで幅方向のフレーム数
grid-row-start、grid-row-endで高さ方向のフレーム数
を指定します。startに関しては1から開始することに注意が必要です。
詳細は次の記事が説明わかりやすいので参考になります。

参考：[CSS Grid Layout を極める！（基礎編）](https://qiita.com/kura07/items/e633b35e33e43240d363)

<p class="codepen" data-height="217" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="RwwgBMP" style="height: 217px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="grid">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/RwwgBMP">
  grid</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## word-break,white-space
word-breakは単語の折返しを指定します。デフォルトの状態では単語単位で折り返しされるため、要素の外にテキストがはみ出る場合があります。word-break:break-all;を使うことで単語途中でも折返しされるため、テキストが要素の外にはみ出ることはなくなります。
white-spaceは空白文字や改行文字をどう扱うかを指定します。通常は空白文字などは無視されます。
white-space:pre-wrapを使うと折返ししつつ、改行文字も考慮されるため良い感じな見た目になります。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="vYYZzZx" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="white-space, word-break">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/vYYZzZx">
  white-space, word-break</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## text-overflow、line-clamp
`text-overflow: ellipsis`を使うことでテキストが要素内に入り切らなかった場合に...で省略されます。

参考：[text-overflow](https://developer.mozilla.org/ja/docs/Web/CSS/text-overflow)

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="eYYVVPX" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="text-overflow">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/eYYVVPX">
  text-overflow</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

複数行の場合はline-clamp(IE以外)を使います。

参考：[CSSで複数行3点リーダーを実現する「line-clamp」がついにIE以外に対応したよ！](https://qiita.com/longbamboo/items/476ccdcbed9e017bc79c)

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="vYYddaX" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="line-clamp">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/vYYddaX">
  line-clamp</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## shadow
shadow（影）には二種類あります。テキスト自体に影をつけるtext-shadowとタグの輪郭に影をつけるbox-shadowがあります。
文法は`水平方向の影 垂直方向の影 ぼかし具合 影の色`で指定します。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="PoojBgp" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="shadow">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/PoojBgp">
  shadow</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## opacity
opacityは透明度を意味します。0〜1で透明度を指定します。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="GRREXNE" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="opacity">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/GRREXNE">
  opacity</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## border-radius
border-radiusを指定することでタグの角を丸くすることができます。
ちなみにborder-radiusの値を大きく振り切ると円になります。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="qBBjMRO" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="border-radius">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/qBBjMRO">
  border-radius</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## gradient
背景にグラデーションをかけるにはlinear-gradient、radial-gradientを使います。
linear-gradientが線形のグラデーション、radial-gradientが円形のグラデーションをかけます。
linear-gradientの第１引数は角度を指定します。後ろの色は何色指定しても構いません。
radial-gradientの第１引数は円形グラデーションをかける位置を指定します。第２引数以降は色と半径を指定します。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="xxxraJV" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="gradient">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/xxxraJV">
  gradient</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## filter
filterの種類によっては使えないブラウザがあるので注意が必要です。

- brightness: 明度
- contrast: コントラスト
- grayscale：グレースケール
- saturate: 彩度
- sepia: セピア
- hue-rotate: 色相
- invert: 色相反転（ネガポジ）
- blur: ぼかし
- opacity: 透明度
- drop-shadow: 影

filterを複数組み合わせるときはスペースで区切って指定します。

参考：[Photoshopはもういらない？明度も彩度も超手軽に変えられるCSSフィルターがスゴい](https://www.webprofessional.jp/css-filter-effects-blur-grayscale-brightness-and-more-in-css/)

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="dyyRqQW" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="filter">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/dyyRqQW">
  filter</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

mix-blend-modeを使うとさらに複雑な表現ができますが、
mix-blend-modeに関して詳細は以下を参考にしてください。

参考：[mix-blend-mode](https://developer.mozilla.org/ja/docs/Web/CSS/mix-blend-mode)

## clip-path
clip-pathを使うと、DOMの描画領域をクリッピングすることができます。
画像や背景付きのDOMなどに使うと有効です。
`circle`は円状にくり抜きます。`ellipse`は楕円状にくり抜くことができます。
`polygon`は頂点位置を指定するとその指定位置でくり抜くことができます。

参考：[clip-path](https://developer.mozilla.org/ja/docs/Web/CSS/clip-path)

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="jOOjerO" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="clip-path">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/jOOjerO">
  clip-path</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## transform
trandformはタグの変形を行います。
scaleで拡大縮小、rotateで回転、translateで移動を行うことができます。
３次元の場合はscale3d、rotateX、rotateY、rotateZ、translate3dを使います。
奥行きを反映するためにはperspectiveを使います。
行列の掛け算となっており、並び順で計算結果が異なるので注意が必要です。
`transform: translate(10px, 100px) rotate(45deg)`と`transform: rotate(45deg) translate(10px, 100px)`は表示される結果が異なります。
他にもskewなどがありますが、詳細は次の記事が参考になります。

参考：[【CSS3】Transform（変形）関連のまとめ](https://qiita.com/7968/items/eddfeb4b424d7c2d2d34)

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="QWWgRpL" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="transform">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/QWWgRpL">
  transform</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## transition
transitionは２つのスタイル間の変化をアニメーション表現します。
アニメーションさせたいスタイルをtransitionで指定します。
一括でスタイルを変化させたい場合は１番目のパラメータにallを指定します。
２番目のパラメータにはアニメーションの時間を指定します。
３番目のパラメータにはアニメーション関数を指定します。linear、ease-in-outなどの関数を指定します。
アニメーション関数の挙動はMDNの例がわかりやすいのでこちらを参考にしてください。
参考：[transition-timing-function
](https://developer.mozilla.org/ja/docs/Web/CSS/transition-timing-function)
スタイル別でアニメーション速度を変えたい場合はスタイル名で複数指定します。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="zYYdaPo" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="transition">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/zYYdaPo">
  transition</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## animation
animationはスタイルの変化をキーフレームアニメーションで表現します。
transitionに対して、キーフレームを`@keyframes`で定義する必要がある違いがあります。
フォーマットは`animation: アニメーション名 アニメーション時間 アニメーション関数 繰り返し回数 アニメーションの方向`です。
繰り返し回数はinifiniteを指定すると無制限の繰り返しとなります。
アニメーションの方向はよく使うものにnormal,reverse,alternativeなどがあります。
キーフレームの書式は次のようになっています。

```css
@keyframes アニメーション名 {
 0% {
  /* 0%のときのスタイル */
 }
 x% {
  /* x%のときのスタイル */
 }
 100% {
  /* 100%のときのスタイル */
 }
}
```

0%、100%のみの場合はfrom, toでも指定できます。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="QWWMXMK" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="animation">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/QWWMXMK">
  animation</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## メディアクエリ
メディアクエリを使うと画面サイズによって割り当てるスタイルを変えることができます。
レスポンシブデザインなどで使います。
次のように`@media screen and (max-width: 画面サイズ)`のように使います。
例えば、PC用レイアウトとモバイル用レイアウトで文字色を変えるには次のようにします。
レスポンシブでよく使うのはflex-directionをPCではrow、モバイルでcolumnにするなどです。

```css
/* PC用スタイル */
div { 
  color: red; 
}
/* モバイル用レイアウト */
@media screen and (max-width: 768px) {
  div { 
    color: blue; 
  }
}
```

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="WNNEVvE" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="mediaquery">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/WNNEVvE">
  mediaquery</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## スクロール位置の制御
scroll-snap-typeを使うと、スクロール時に指定位置で止まるように位置を指定することができます。（IEは未対応）
使い所がランディングページやスライド専用ページなどに限定されますが、意図した位置にスクロールを誘導させることができます。
なお、スライド毎要素の高さをフルスクリーン（１００ｖｈ）にするなどの調整が必要です。

参考：[scroll-snap-type](https://developer.mozilla.org/ja/docs/Web/CSS/scroll-snap-type)

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="GRRwGmM" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="ScrollSnap">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/GRRwGmM">
  ScrollSnap</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


## フォーム制御
基本的にフォームのvalidate制御（正しい値が入力されているか）、submit制御（送信ボタンが押せるか）はJavaScriptでやることが普通なのですが、
実は簡単なものはCSSでもできちゃったりするので紹介します。

参考：[【CSS猛者への道①】CSSのみで入力フォームのチェックを行う主な3つの便利技法を記録。](https://qiita.com/t_o_d/items/afc797ba00c85b7fc470)

pointer-eventsスタイルがミソでこれをnoneに指定することでsubmitボタンが押せなくなります。
:not(:placeholder-shown)擬似クラスがplaceholderが表示されていない（＝入力されている）を示しています。
:valid擬似クラスが正しい入力がされているかを示しています。（type=emailの入力欄などは簡易的なメールチェックはされている）
:in-range擬似クラスで入力値が入力範囲内かを示しています。
:checked疑似クラスでチェックされているかを示しています。
すべての入力欄の後、~セレクタにてsubmitボタンが押せるかの判定をセレクタで行います。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="teradonburi" data-slug-hash="OJJxLyE" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="form-check-css">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/OJJxLyE">
  form-check-css</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

とはいえ、セレクタで強引にやるのには限界があるのでJavaScriptで本来やるべきです。

## ベンダープレフィックス
ベンダープレフィックス（接頭辞）とは、ブラウザベンダーが独自の拡張機能を実装したり、草案段階の仕様を先行実装する場合に、 それが拡張機能であることを明示するために付ける識別子のことです。

主要ブラウザのベンダープレフィックスは以下のようになっています。

- -moz-:Firefox
- -webkit-:Google Chrome、Safari
- -o-:Opera
- -ms-:Internet Explorer

たとえば、transformスタイルに完全対応していないブラウザはベンダープレフィックスを付ける必要があります。
(時代の変化で確定した時点で対象のスタイルのベンダープレフィックスは不要となります)

```css
transform: scale3d(1,1,1);
-weblit-transform: scale3d(1,1,1); /* Safariのtransformに対応する */
```

## CSSリセット
ブラウザ別のCSSの差異をなくすためにページ読み込み時にCSSを上書きしてスタイルを統一することをCSSリセットと呼びます。

参考：[古いCSSリセットからはもう卒業！モダンブラウザに適した新しいCSSリセット -A Modern CSS Reset](https://coliss.com/articles/build-websites/operation/css/a-modern-css-reset.html)

とはいえ、全てリセットする必要はないです。理由としてはUIライブラリを入れた場合に不要だったりするからです。
（不要なCSSはレンダリングパフォーマンスが落ちる）
ただし、html, bodyに関しては初期化しておくと便利なことが多いので、自分は以下のCSSリセットをよく使っています。

```css
html, body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  min-height: 100vh;
  scroll-behavior: smooth;
  text-rendering: optimizeSpeed;
}
```

ちなみにフォームに関してはブラウザによって差異が激しいのでCSSリセットしたほうが都合が良い場合が多いです。
もしくはUIライブラリを入れてしまうのも手です。

参考：[フォーム要素のスタイルをリセットする](http://cly7796.net/wp/css/reset-the-style-of-form-elements/)

## CSSのパフォーマンス向上
以下の手順でCSSの見直しをします。

1. CSSファイルのMinify化：CSSファイルに分離し、CSSファイル自体をMinify(圧縮＆難読化)する
2. セレクタを見直す
3. 似通ったmargin,paddingや色コードをまとめる
4. 重複しているスタイルを削除する

この過程で基本的に!importantもいらなくなるはずです。
自前でCSSを極力書かずにUIライブラリを使ってしまうのも手です。
ライブラリではテーマが用意されていてスタイルの統一性が担保できていることやMinify機能を持つものが多いです。

参考１：[＜CSS＞サイトの表示速度を意識したセレクタの書き方](https://qiita.com/mamiyan/items/778183160e9e58546824)
参考２：[CSS 最適化によるパフォーマンス改善](https://murashun.jp/blog/20180817-01.html)

## デザイン
デザインに関しては一朝一夕で身につくものではないので、日々勉強が必要です。
（特に写真、ロゴ、アイコン等の画像作成に関しては完全にクリエイティブな分野なので専門の勉強が必要です）
以前ランディングページ作成（LP）に関してまとめたものがあるのでこちらも参考にしてください。

参考：[ノンデザイナーでもイケてるLPを作成する方法](https://qiita.com/teradonburi/items/412f65147525ff34dbbd)

また錯視に関するデザインの調整をすることで、より洗練されたデザインになります。（若干高度なトピック）

参考：[UIのデザインでよく見かける、目の錯覚による違和感を取り除くデザインテクニックのまとめ](https://coliss.com/articles/build-websites/operation/design/visually-distorted-when-ui-looks-all.html)

# JavaScript
ブラウザで実行されるスクリプト（フロントエンド）は基本的にJavaScriptで書かれていることが多いです。
HTMLのDOMツリーが構築された後にDOMを動的生成したり、HTMLタグの属性値を変更したり
DOMのCSSを変更したり、サーバ（バックエンド）に通信してデータ（主にJSONや画像、音声データ等）を取得したりすることが用途として多いです。
サーバ側でもNodeJSを使えばJavaScriptでサーバの処理を書くことも可能、IoTでも使えたりと幅が広いプログラミング言語。
TypeScriptからJavaScriptに変換するというのも最近のトレンドです。（TypeScriptに関してはここでは触れない）

基礎文法に関してはそれだけで書籍になってしまうのでここでは述べません。
次のJavaScriptのモダンな基礎文法に関して一通りまとまってるサイトが参考になります。
参考：[js-primer](https://jsprimer.net/)

最近はbabel、webpack、parcelなどでES5に変換して開発するのが普通なのでES6以前の文法は全てレガシー文法です。
レガシーな文法を覚える必要は今更ないので、以下の記事でレガシーな文法かどうか参考にしてください。
（ただし、どれがレガシー文法なのか知るのは大事）

参考：[JavaScript初級者のためのコーディングガイド](https://qiita.com/raccy/items/bf590d3c10c3f1a2846b)
参考：[イマドキのJavaScriptの書き方2018](https://qiita.com/shibukawa/items/19ab5c381bbb2e09d0d9)

この記事ではJavaScriptフレームワークは使わずに書いています。
(どのブラウザでも標準で組み込まれているJavaScriptライブラリを俗にVanilla JSと呼ぶ)
ReactやVueなどのモダンJSフレームワークも裏側ではVanilla JSが使われています。
昔はjQueryなどのVanilla JSをラップしたライブラリもメジャーでしたが、
個人的に今更jQueryは使う必要ないかなと思っています。（使わなくても同等のことができる）
参考：[You Don't Need jQuery](https://qiita.com/tatesuke/items/b9548dd484b01b139b74)

## HTMLElement
HTMLElementはHTML要素をJavaScriptで操作するときに扱うオブジェクトです。
あらゆるHTML要素はHTMLElementから継承されており、操作できます。

参考：[HTMLElement](https://developer.mozilla.org/ja/docs/Web/API/HTMLElement)

`document.querySelector('CSSセレクタ')`でHTMLElementオブジェクトを取得できます。
JavaScriptでDOM操作をする場合は、正確にはページ読み込み時のDOMの取得タイミングには気をつける必要があります。
ブラウザのレンダリングの仕組みとしてDOMツリーの構築→画像などのリソース読み込み→JavaScriptでのDOM操作
(DOMツリーの構築完了を待つ必要がある)

```js
// DOMツリーの構築を待つ
document.addEventListener("DOMContentLoaded", function(){
  // ここで取得
})
```

画像などのリソースの読み込み待ち（読み込んだ画像をJavaScript側で参照）をする場合などは、loadイベントでページの読み込みまで待たないといけません。
JavaScript側で動的にHTML要素を生成してDOMツリーに挿入することができます。
HTML要素を生成するには、`document.createElement('要素名')`を指定します。
生成したHTML要素の内容を変更するにはinnerHTMLで内容を書き換えすることができます。
innerHTMLの場合、子要素などの記述などもできます。
生成したHTML要素をDOMツリーに追加するには`HTMLElement.appendChild(HTMLElement)`などを使います。

```js
// divを作成
const div = document.createElement('div')
div.innerHTML = '<span style="color: red;">赤色</span>'
main.appendChild(div)
```

CSSセレクタで該当する要素を全て取得するには
`document.querySelectorAll('CSSセレクタ')`を使います。
配列のHTMLElementオブジェクトが取得できます。
innerTextはテキストとして操作します。
（例えば、innerText内に`<span>文字列</span>`などを挿入してもタグとして扱われず文字列として扱われてそのまま表示されます）

```js
// liの要素を全て取得
const li = document.querySelectorAll('li')
let i = 0
for (const l of li) {
  i++
  const text = l.innerText
  l.innerText = text + i
}
```

JavaScriptで動的にスタイルとクラスを変更できます。
styleプロパティから任意のスタイルを文字列値を指定することで変更できます。
注意点としてはmargin-bottomのようなハイフン付きのスタイルはmarginBottomのようにハイフンを削除して後ろ先頭文字を大文字のキャメルケースで指定する必要があります。
classを追加するにはclassList.add、削除するにはclassList.removeを使います。

```js
const block = document.querySelector('.block')
block.style.fontSize = '24px'
block.classList.remove('block')
block.classList.add('blockNew')
```

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="teradonburi" data-slug-hash="PooQzrL" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="HTMLElement">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/PooQzrL">
  HTMLElement</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## HTMLImageElement
Imageオブジェクト（HTMLImageElement）はHTMLElementを継承したオブジェクトです。
`new Image()`でコンストラクタ形式で生成することもできます。(`document.createElement('img')`と同じ)
画像リソースをsrc属性指定で動的に読み込むこともできます。
ただし、onloadイベントやonerrorイベントは非同期のコールバックのため、
次のようにpromise形式でwrapしたほうが使いやすいでしょう。

```js
function loadImage(src) {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.onload = () => resolve(img)
    img.onerror = (e) => reject(e)
    img.src = src
  })
}
```

参考：[HTMLImageElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement)

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="teradonburi" data-slug-hash="pooNNeV" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="image">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/pooNNeV">
  image</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## HTMLAudioElement
Audioオブジェクト（HTMLAudioElement）はHTMLElementを継承したオブジェクトです。
`new Audio()`でコンストラクタ形式で生成することもできます。(`document.createElement('audio')`と同じ)
controls属性をtrueにするとAudioプレイヤーのコントロールが表示されます（プレイヤーのコントロール表示はブラウザ依存）

参考：[HTMLAudioElement](https://developer.mozilla.org/ja/docs/Web/API/HTMLAudioElement)

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="teradonburi" data-slug-hash="QWWGqga" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="audio">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/QWWGqga">
  audio</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

HTMLAudioElementは基本的な再生制御しかできませんが、
[WebAudio API](https://developer.mozilla.org/ja/docs/Web/API/Web_Audio_API)を使うとMIDIシーケンサみたいなものを独自に作ることができたり、音声にエフェクトかけるといった高度なことができるようになります。
和音を鳴らすのにもある程度知識が必要ですが以下が参考になります。

参考：[Web Audio APIでコインの音を作る](https://qiita.com/mohayonao/items/c506f7ddcaac63694eb9)

また、こちらはブラウザによってメモリリークを起こしたり、ユーザアクションがないAudioContextが取得できないといった罠が多かったりします。（後、概念とデバッグが難しい）

参考：[Web Audio APIの闇](https://qiita.com/zprodev/items/7fcd8335d7e8e613a01f)


## HTMLVideoElement
HTMLVideoElementはHTMLElementを継承したオブジェクトです。
videoタグに相当し、動画の制御をJavaScriptでできます。

参考：[HTMLVideoElement](https://developer.mozilla.org/ja/docs/Web/API/HTMLVideoElement)

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="teradonburi" data-slug-hash="VwwPQBY" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="video">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/VwwPQBY">
  video</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## MutationObserver
MutationObserverを使うと対象のDOM変更時に通知することができます。
attributeのオプションをつけると属性値が変わったときに通知されます。
subtreeのオプションをつけると対象のDOMの子要素まで監視対象になります。
変更後に処理を差し込むことができるので、デバッグやアドオンなどに使うことができます。

参考：[MutationObserver](https://developer.mozilla.org/ja/docs/Web/API/MutationObserver)

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="teradonburi" data-slug-hash="PoqePxW" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="MutationObserver">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/PoqePxW">
  MutationObserver</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


## LocalStorage
localStorageを使うとブラウザにデータを半永続的に保存することができます（ドメイン単位）
`localStorage.setItem(key, data)`でデータを保存することができます。
JavaScriptをオブジェクトを直接保存することができないので文字列(JSON文字列)に変換しています。
JSON形式に変換するには`JSON.stringify`を使います。
保存したデータを取得するには`localStorage.getItem(key)`を使います。
取得したデータがJSON文字列の場合、`JSON.parse`で文字列からJavaScriptオブジェクトに変換できます。
一度保存されたデータはブラウザをリロードしてもブラウザに残り続けます。
明示的にlocalStroageのデータを消すには、`localStorage.removeItem(key)`を使います。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="teradonburi" data-slug-hash="dyydXQd" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="localStorage">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/dyydXQd">
  localStorage</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## Fileオブジェクト
File APIを使うとユーザがアップロードしたファイルの操作をブラウザ上で直接取り扱うことができます。
よく使う例として、画像ファイルをinputタグからアップロードしたとき、Fileオブジェクトとして格納されて取得できます。
取得したファイルのファイル名、MIMEタイプなどを取得できます。
`URL.createObjectURL`を使うとFileオブジェクトを一時的なURLとして変換することができます。
（このURLはimgタグ、audioタグ、videoタグなどのsrcとして指定することができます。）

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="teradonburi" data-slug-hash="ZEErBam" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="File API">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/ZEErBam">
  File API</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

もうちょっと複雑な例は以下が参考になります。

参考：[JavaScript で File API を使用してファイルを読み取る](https://www.html5rocks.com/ja/tutorials/file/dndfiles/)

## FormDataオブジェクト
JavaScriptでフォームデータが正しいものが入力されているかチェック（validate）する制御を送信前に行うことができます。
FormDataオブジェクトを使うことで入力されたFormのデータを参照したり、JavaScript側で追加したりできます。

参考：[JavaScript によるフォームの送信](https://developer.mozilla.org/ja/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript)

JavaScriptでのデータ通信には[XHR(XMLHTTPRequest)](https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest)もしくは[Fetch API](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch)を使って行われることが一般的です。
または、XHRをラップしたライブラリ[axios](https://github.com/axios/axios)を使う方法などがあります。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="teradonburi" data-slug-hash="xxxYgwV" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="FormData">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/xxxYgwV">
  FormData</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

アップロードする先のサーバが必要ですが、
[glitch](https://glitch.com/)というサービスを使うことで簡易的にNodeJSのサーバを立てています。
以下、サーバ側の実装です。

```server.js
const express = require('express')
const app = express()
const multer  = require('multer')
const cors = require('cors')
const upload = multer({ dest: 'uploads/' })

// APIエラーハンドリングするためのwrapper
const wrap = (fn) => (req, res, next) => fn(req, res, next).catch(err => {
  console.error(err)
  if (!res.headersSent) {
    res.status(500).json({message: 'Internal Server Error'})
  }
})
// エラーハンドリング
process.on('uncaughtException', (err) => console.error(err))
process.on('unhandledRejection', (err) => console.error(err))
process.on('SIGINT', () => process.exit(1))

// CORS（別ドメインからの通信を許可する）
app.use(cors())
// publicフォルダ
app.use(express.static('public'))
// POSTデータを取得するためのミドルウェア
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({extended: true}))
app.use(bodyParser.json())

// アップロードAPI
app.post('/api/upload', upload.single('image'), wrap(async (req, res) => {
  console.log(req.body)
  console.log(req.file)
  res.json({image: req.file, ...req.body})
}))

// サーバ起動
app.listen(process.env.PORT, () => {
  console.log('server started')
})
```

今回はファイル送信があったため、バックエンドを実装しましたが、
JSONデータを返す、APIサーバのモックであれば、[json-server](https://github.com/typicode/json-server)を使うとさらに簡単にモックサーバの作成ができます。

## WebRTC
WebRTC(Web realTime Communication)のことでリアルタイムビデオチャットをブラウザで行うための機能です。
getUserMediaによるカメラからのリアルタイム動画取得とWebSocketによるPeerConnection通信により実現されています。
カメラからの動画取得のサンプルは[こちら](https://codepen.io/teradonburi/pen/qBBxjMX)

参考：[「MediaDevices.getUserMedia() 」について](https://qiita.com/Futo23/items/bff1ce1d2e1b219b243d)

WebSocketに関しては[Socket.io](https://socket.io/)というライブラリを使うのが一般的です。

ビデオ会議のサンプル：[Socket.io | WebRTC One-to-One Video Chat](https://www.webrtc-experiment.com/socket.io/#9780180437205065)

## Canvas, WebGL
Canvasを使うことで独自の画像処理やDOMを画像化するなどといった特殊なこともできます。

参考：[Canvasを用いた9つの画像処理フィルターとそのアルゴリズムの解説](https://kuroeveryday.blogspot.com/2017/10/image-filters-with-canvas-algorithm.html)

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="teradonburi" data-slug-hash="XWWZZNy" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="canvas">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/XWWZZNy">
  canvas</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

DOMを画像化する方法は直接実装するより[html2canvas](https://html2canvas.hertzen.com/)を使ってしまったほうが手っ取り早いです。

WebGLに関しては、本格的な３Dをウェブ上で表現するための技術です。
初期化にはCanvasの延長上でwebglのcontextを取得する必要があります。

参考：[WebGL 入門](https://developer.mozilla.org/ja/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL)

数学的な計算（ベクトル、行列）の知識が必要なのとシェーダー等やれることが多すぎるのと仕様がかなり頻繁に更新され、
直接扱うのはかなり大変なため、
[Three.js](https://threejs.org/)や[A-Frame](https://aframe.io/)などのライブラリを使うことが多いです。
頑張れば、本格的な３Dゲームもブラウザ上で実現可能です。（もちろんパソコンのスペックも必要ですが・・・）
参考までに以前作ったものを上げておきます。

参考：[Web上でちょっと本気の3Dアクションゲームを作る](https://qiita.com/teradonburi/items/785085c109cd55d92d32)

## Web Animation API
Web Animation APIを使うとCSS3のキーフレームアニメーションをJavaScriptで行うことができます。
（ただし実験的な機能なため、まだ動かないブラウザが多いので実プロダクトでは使えません。）

参考：[Element.animate()](https://developer.mozilla.org/ja/docs/Web/API/Element/animate)

<p class="codepen" data-height="183" data-theme-id="0" data-default-tab="js,result" data-user="teradonburi" data-slug-hash="YzzeYRb" style="height: 183px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Web Animation API">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/YzzeYRb">
  Web Animation API</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 要素の可視判定

[交差オブザーバーAPI](https://developer.mozilla.org/ja/docs/Web/API/Intersection_Observer_API)を使うとスクロール可視時に制御が可能です。
サンプルではスマホアプリケーションのようにスクロール時にリストの要素をアニメーションさせています。
末端の要素を可視時に要素取得するようにすると無限スクロールなども可能となります

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="WNJjeLj" data-user="teradonburi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/WNJjeLj">
  Untitled</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

注意点としてはスクロール対象の要素の高さを可視領域にする必要があります。

```css
ul {
  margin: 0;
  padding: 10px;
  /* 重要：ulのサイズをブラウザ画面の高さに合わせる */
  max-height: 100vh;
  overflow: auto;
}
```

IntersectionObserverの第一引数には、observe関数で登録した監視対象が可視化、非可視化のときにハンドリングする関数を指定し、第二引数には監視対象（スクロール対象）の要素と可視判定の閾値を指定します。

```js
const observer = new IntersectionObserver((entries, observer) => {
  for (const entry of entries) {
   
 entry.isIntersecting ?   entry.target.classList.add('show') : entry.target.classList.remove('show')
  }
}, {
  root: list,
  rootMargin: '0px',
  threshold: 0
})

tiles.forEach(tile => observer.observe(tile))
```


## スクロールアニメーション
Vanilla JSで直接実装するのが大変なものにスクロールアニメーションがあります。
クリックしたら指定のアンカーリンクまでスクロールアニメーションするといった挙動です。
[smooth-scroll](https://github.com/cferdinandi/smooth-scroll)というライブラリを使うとあっさり実装できます。

参考：[Vanilla.jsのアニメーションスクロールプラグイン「Smooth Scroll」](https://www.willstyle.co.jp/blog/1449/)

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="PooQOOB" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Smooth Scroll">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/PooQOOB">
  Smooth Scroll</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## パララックス
スクロールアニメーション同様Valilla JSで表現するのが厄介なのが、パララックスです。
これは、スクロールに連動してHTML要素がアニメーションすることです。
こちらも[rellax](https://github.com/dixonandmoe/rellax)というライブラリを使えば比較的簡単に実現できます。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="ZEErawW" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Rellax">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/ZEErawW">
  Rellax</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## カルーセル
[Swiper](https://github.com/nolimits4web/Swiper)を使えばフレームワークに依存せず。カルーセルを実装できます。（スマホのスワイプ操作にも対応しています）

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="teradonburi" data-slug-hash="KKwybPB" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Swiper">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/KKwybPB">
  Swiper</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## ドラッグ操作
リストの並び替え、アイテムのドラッグ＆ドロップは[draggable](https://github.com/Shopify/draggable)を使うとフレームワークに依存せず実装できます。

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="js,result" data-user="teradonburi" data-slug-hash="ExabGLP" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="draggable">
  <span>See the Pen <a href="https://codepen.io/teradonburi/pen/ExabGLP">
  draggable</a> by teradonburi (<a href="https://codepen.io/teradonburi">@teradonburi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


# まとめ
Webフロントエンドの基礎的な部分に関して説明しました。
さらにWebフロントエンドに対する知識と理解を深めるには次のものを勉強すると良いと思います


- ブラウザのレンダリングの仕組みに関して理解を深める
  - 参考：[実際のところ「ブラウザを立ち上げてページが表示されるまで」には何が起きるのか](https://qiita.com/tsin1rou/items/d4c781a2f25e2b92fa5e)
  - 参考：[ブラウザレンダリング入門〜知ることで見える世界〜](https://qiita.com/Leapin_JP/items/caed57ec30d638e40728)
  - 参考：[Life of a Pixel 2018](https://docs.google.com/presentation/d/1boPxbgNrTU0ddsc144rcXayGA_WF53k96imRH8Mp34Y/edit#slide=id.p)
- babel、webpack、Parcelの知識を深める（参考：[webpackとBabelの基本を理解する(1) ―webpack編―](https://qiita.com/koedamon/items/3e64612d22f3473f36a4)）
- JavaScriptフレームワークを使ってみる（個人的にはReactがおすすめ。参考：[ReactJSで作る今時のSPA入門（基本編）](https://qiita.com/teradonburi/items/fb91e5feacab5071cfef)）
- TypeScriptの勉強をする、JavaScriptフレームワークにTypeScriptを導入してみる（参考：[TypeScript練習帳（入門）](https://qiita.com/teradonburi/items/06980b8670339ea424c4)）