😊

フロントエンドの基礎知識について①(html、css、js、ts)

2020/12/21に公開

を追加しました。
ある日素晴らしいスクラップを見つけました。
yamanokuさんありがとうございます。
就活の面接で知識不足を感じる部分があったりしたので、自分の知識を再確認するために調べたのでまとめます。
だいぶ長くなってしまったので、記事を分けます、今回はHTML、CSS、Javascript、Typescript編です。

HTML

HTML Standardを参照できる

  • 入れ子関係
  • どういった用途で使われるのか
    このサイトはHTMLの歴史や書き方について細かく記されているサイトで日本語訳もあります。
    入れ子関係については例えばul olの中にはliを入れなければならないなどのことで
    ダメな例
sample.html
<div>
  <div>・hoge</div>
  <div>・fuga</div>
</div>

良い例

sample.html
<div>
  <ul>
    <li>hoge</li>
    <li>fuga</li>
  </ul>
</div>

ちゃんと役割を考えて使わないといけないという話です。
他にも山ほどありますがHTML Standardを読めばわかります。
自分自身理解が不十分なところがあり、きちんとマークアップできるようにがんばります。

<head>内のみで使用できるタグを把握している

  • <head>内で使用できるのは<meta> <title> <link>です。
    • metaタグでは文字タイプや著者などの情報の設定や、descriptionなどOGに関する設定を行うことができます。
      ただnuxtではnuxt.config.jsで設定を行ったり。
      nextではnext/headを使用したり、getStaticPropsやgetServersidePropsを使用したりして設定するため使用しているフレームワークがある場合はそれぞれのドキュメントをみましょう。
    • titleタグではブラウザのタブに表示される文字を設定できます。おそらくみなさん知っていると思います。
    • linkタグではcssファイルを読み込んだり、faviconを読み込んだりします。これもみなさん知っていると思います。
      cssの読み込みはレンダリングをブロックするのでパフォーマンスの観点ではheadタグの最後においた方がいいです。

セマンティクスに基づいた実装の利点を説明できる

セマンティクスHTMLはセマンティック・ウェブの考え方が基になっており、要するにHTMLをそれぞれの意味に基づいてマークアップしましょうということです。

利点

  • 検索エンジンがHTMLをクロールする際にその構成の意味を理解しやすくすることができる。

これがいわゆるSEOに関連することで検索エンジンがHTMLを理解できるように書くことでSEOにおいて優位になることができます。
人間だけじゃなくて機械にも読みやすいように書きましょうということです。

  • アクセシビリティの向上がはかれる
    アクセシビリティについてはwebA11ly.jpのサイトが個人的に網羅的でわかりやすかったです。
    視覚しょうがいの方などはウェブサイトを読み上げるスクリーンリーダーを使用しており、例えば構成を全てdivで行ったりすると理解ができなくなってしまいます。
    ここはWAI-ARIAなどにも関係してくるのでその時に書きます。
  • 自分以外の人がみた時にわかりやすい

構成がきちんとそれぞれのタグを理解して書いてあればコードリーディングもしやすくなります。

Nu HTML Checkerを使うことができる

Nu HTML Checker 知りませんでした。指定したURLのHTMLにエラーがないかを調べてくれるものらしいです。
とても便利そうなので使っていきたいと思います。

  • 構文エラーについてを把握できる

tableの構造とかbuttonのtypeとかですかね、構文エラーで理解しにくい例が思い浮かばなかったです。

各ブラウザで使用できるかできないかを把握している

Caniuse
ブラウザ対応で消耗するのいやですね。IEは撲滅してください

WAI-ARIA

W3Cによって定められた仕様でアクセシビリティを向上させるためのHTMLに付与するものです。
HTML自体に意味がついていますが、どうしてもセマンティクスに書けない例があると思います。
例えばボタンなのにdivで書かなければならない場合など、その時にdivがボタンだと認識してもらわなければならない場合などに使います。
この場合だと<div role="button"></div>みたいな感じです。
説明するの辛いのでMDNを参照してください

WAI Web Accessibility Tutorialsを参照できる

WAI Web Accessibility Tutorialsをみましょう、チュートリアル形式なのでみたままです。

WCAGを参照できる

WCAGをみましょう、これ全部理解するのは大変そうですね、、、

各種Roleモデルを理解している

基本的にセマンティクスに書けていれば問題ないですが例外が発生した場合に使うために覚えておいた方がいいと思います。自分自身全く覚えれていません。
丸投げしますごめんなさい
https://qiita.com/nezurika/items/eac689a97895a27b8791
https://www.dkrk-blog.net/html/aria_role01

CSS

SASS、SCSS、Stylus

  • SASS、SCSS
    ruby製のCSSメタ言語でネストや変数、mixin、関数、スタイルシートの分割ができます。
    違いは{}があるかないかです。CSSは{}を使うので理解しやすくSCSSの方が使われています。
    個人的にpugもそうですが、シンプルにはなりますがそれ以上にインデントでの位置関係表示が辛いのでSCSS使っています。
sample.sass
p
  .first
    font-size: 12px;
sample.scss
p {
  .first {
    font-size: 12px;
  }
}

変数

変数を用いることで何度も色コードやfont-sizeを書かなくて済みます

sample.scss
$text_color: red;

div {
  color: $main_color
}

mixin

mixinを使うことで何度も同じことを書かなくて済みます、media queryとかで使います。

sample.scss
$breakpoint-tablet: 1024px; /* 変数宣言 */
$breakpoint-mobile: 640px; /* 変数宣言 */

/* $break-point以下の時に@contentを適用 */
@mixin max-screen($break-point) {
  @media screen and (max-width: $break-point) {
    @content;
  }
}
/* $break-point以上の時に@contentを適用 */
@mixin min-screen($break-point) {
  @media screen and (min-width: $break-point) {
    @content;
  }
}

関数

繰り返しの時とかに使えます、if文もあります

sample.scss
@for $i from 1 through 5 {
  .hoge-#{$i} {height: 10px * $i;}
}
  • Stylus
    使ったことがないので違っている可能性があるかもしれないです。
    Nodejs製のCSSプリプロセッサです。
    SASS/SCSSと同様に変数や関数、mixinなどがあります、継承があること、SASS/SCSSのどちらの書き方もできる点が違う点だと思います。
    morishitterさんの記事がわかりやすかったです。

CSS設計についての理解

  • BEM、OOCSSなどがあります。

BEM

Block Element Modifierの頭文字をとったもので
block_element--modifierのようにクラス名を書きます。

利点

細かくクラス名を指定するため、使用している場所などを特定しやすくメンテナンスコストを少なく抑えることができます。

欠点

クラス名が長くなるので書くのが辛いです。

OOCSS

Object Oriented CSSの略でレイアウトに関するスタイルと、レイアウトに関するスタイルに分けて記述するという考え方のことで

sample.html
<div class="card large">
	<img src="...">
	<p class="title">Lorem ipsum dolor</p>
	<button class="button bg-red">Add</button>
</div>

buttonbg-redのようにレイアウトとスタイルに関連するスタイルを分けます。

利点

BEMに比べコード量が減る

欠点

影響範囲が大きくなる

ただスクラップのほうでcatnoseさんがおっしゃっていましたが、BEMについて理解があるといろんなところでやりやすそうとのことなのでBEMについてはきちんと理解しておいて損はないと思います。

詳細度

cssには優先度と詳細度があり
このようなルールがあります

  1. 優先度が高いもの
  2. 優先度が同じ場合、詳細度が高いもの
  3. 優先度と詳細度が同じ場合、最後に宣言されたもの

優先度

優先度には三つあり

  1. 製作者スタイル
    私たちが書くスタイル
  2. ユーザー定義スタイル
    ブラウザの「表示→インターネットオプション→ユーザ補助」等で開かれる画面で設定可能なスタイル
  3. ブラウザの標準スタイル
    それぞれのブラウザが実装しているスタイルで、何もスタイルを設定していない時に適用される
    buttonなどは最初からボーダーや色がついていたりしますよね?あれのことです

順番は1、2、3の順番で優先度が高いです。

自分でスタイルを書いた場合②に引っかかるので詳細度について考えなけえればなりません

使う機会の多い詳細度は
p#text > #text > p.text > .text で、基本的にidが優先されます

sample.vue
<template>
  <p class="hello" id="hello">こんにちは</p>
</template>
<style scoped>
p#hello {
  color: red;
}
p.hello {
  color: blue
}
#hello {
  font-size: 36px;
}
.hello {
  font-size: 12px;
}
</style>

この場合だとcolor:red;font-size:36pxが優先されることになります。
cssが大した量ではない場合そんなに困らないと思いますが膨大な量のstyleが定義されている場合詳細度を考えないといけない場合があります。

依存がひどくなると!importで解決してしまってさらにひどいことになるみたいな感じです。

scssなどはファイルに分割してネストして書くこと、vueはstyleにscopedをつけることなどで影響範囲を限定し、このような問題が起きにくいようにしています(もちろん起こっている場合もありますが、、、)。

計算表を作成されている方がいたので参考にしてみてください
計算表

media query

レスポンシブ対応するために書きます

sample.scss
p {
  color: red;
  @media screen and (min-width:480px) {
    color: blue;
  }
}

こんな感じで範囲を指定してその画面サイズに対応するcssを適応させることができます。

stylelintなどの静的解析ツール

stylelint
javascriptを書いたことがある方であればeslintを使ったことがあると思います、それと同様のことをcssでできます。
簡単にいうとcssを書くための規則をきめ、それに沿わない場合はlintを通した時にエラーが出るようになります。(カラーコードは全て小文字に統一するなど)

sample.css
p {
-  color: #FFFFFF;
+  color: #ffffff;
}

GridやFlexboxを用いたレイアウト調整

レイアウトを作成する時にGridやFlexboxを使うと思います。
個人的な意見ですがgridは複雑なレイアウトを作成したい時に使い、ほとんどの場合flexboxで解決できる気がします。
これらに関しては説明が大変すぎるので素晴らしい記事に任せます
Flexboxチートシート 
Grid

CSS変数

scssの変数と同じです

sample.scss
--main-color: black;

p {
  color: var(--main-color);
}

CSSフレームワーク

有名なところではbootstrapやmaterial-ui、tailwindcssなどがあると思います。
cssフレームワークを利用することでcssへの理解があまりなかったとしてもリッチなデザインのページを作成することができます。
cssフレームワークにも種類があり、

  1. bootstrap、material-uiのようにコンポーネントを提供してくれるもの
  2. tailwindcssのようにスタイルを便利に定義するためのツールだけを提供しているもの
    があると思います。

それぞれ利点、欠点があると思うので少し書きます。

bootstrap、material-uiなど

利点

  • コンポーネントを提供してくれるので、デザイナーがいなくとも簡単にリッチなデザインのページを作成することができる

欠点

  • 学習コストがかかる
  • デザインがありきたりなものになる

コンポーネントを提供してくれるのは便利ですが、カスタマイズが行えないため、使い所をよく考えた上で採用するべきだと思います。
デザインがありきたりなものになるので見た目にオリジナリティが求められる場合では使うべきではありません

コンポーネントを提供するcssフレームワークの全てについてはTAKさんの記事が本質をついていると思います。

tailwindcssなど

利点

  • デザインをカスタマイズができる
  • 学習コストがそこまで重くない

欠点

  • cssを書く必要がある
  • クラス名が長くなる

utility-firstなcssフレームワークなのでtailwindだけで使うのではなくtailwindではメインの部分(レイアウトなど)を実装し、cssで細かい部分を実装する感じになると思います。
強力なcssフレームワークでないがゆえに柔軟なスタイルを適応させることができるのが利点です。
逆にhtmlのクラスに提供されたツールを書いていく形になるのでかなりclass名が冗長になってしまいます、特にレスポンシブ対応を行ったりすると読むのが辛くなります。

css in js

Javascript

現行の仕様に追従したJavascriptを意識して書くことができる

javascriptはtc39が仕様をきめていますが、それのバージョンについて理解しているかという話です。
es2016(es6)、es2017、es2018、es2019、es2020等でなんの機能が追加されたのか、またブラウザによっては使えない場合などがあるのでbabelなどでトランスパイルを行う必要があります。

簡単にですがまとめました。

version 追加機能
es2016 アロー関数()=>{} 、import/export、class構文
es2017 async/await
es2018 冪乗の追加2**4、promiseにfinally追加
es2019 json.stringifyの改善、catchの時に関数を返さなくて良い
es2020 Optional Chaininghoge?.value、Nullish Coalescing Operator?? true:false

varではなくletやconstを使用する

es2015より前では変数や定数を定義するときはvarを使用していましたが、現行のバージョンでは変数はlet、定数はconstを使用するべきで、少なくともPRの中にあれば間違いなく修正させられると思います。

AltJSについて知っている、利用している

AltJSとはコンパイルすることでjavascriptが生成されるプログラミング言語のことです。
javascriptにある問題(動的型付けなのでチーム開発が辛いなど)を解決することができます。
有名どころはcoffee scriptやtypescriptがあると思います。

私はtypescriptしか使用したことがないのですが、javascriptでは不可能な静的型付けを行えるので一定規模以上のプロダクトではコードの保守性を保ちながら開発を行うことができます。
詳しいことはtypescriptのところで書きます。

eslintといった静的解析ツールを用いることができる

eslintはcssのstylelintと同じでコードを書く際に一定の規則を設けてlinterを通した際にエラーを出して書き方を統一することができます。(例えば全てシングルクオーテーションにするなど)
おそらくチーム開発などではeslintとprettierのどちらかは使用していると思います

pretier

prettierはフォーマッターで定めたルールに則って自動でフォーマットを行ってくれます。
CIでformatter、linterを通すことでPRを出す時にチームのルールに則ったコードに統一することができます。

併用することもできますが少し設定に手間取るかもしれないです、私はeslintだとセミコロンなしにしているのにprettierだとセミコロンありにしていてハマったことがあります。

consoleで実行内容を出力できる

consoleを用いることで簡単にデバックを行うことができます。
MDNを見れば大体理解することができると思います。
console.logconsole.errorを使ったことがある方は多いのではないでしょうか?

DOMが何かを理解している

DOMとはDocument Object Modelの略でウェブページをオブジェクト指向の表現しており、javascriptのようなスクリプト言語から変更することができます。DOMはプログラミング言語ではないですが、これをjavascriptで操作することでHTML要素に動きをつけることができます。

sample.vue
<template>
  <p>サンプル</p>
</template>
<script>
  const paragraphs = document.getElementsByTagName("p");
  alert(paragraphs[0].nodeName);
</script>

javascript、JQueryではDOMに直接アクセスして操作することで動きをつけていましたが
最近のjavascriptフレームワーク(vue、reactなど)は仮想DOMを用いて変更の差分部分だけ最描写することで実行の時間を短縮しフロントエンドの領域に新たな風を吹かせました
この辺はmizchiさんの魂の震える記事を読んでいただければと思います。

オブジェクト、配列を作成できる

オブジェクトは関連あるデータの機能の集合のことで例えばユーザー情報などをオブジェクトとして作成することができます。
配列はリストのようなオブジェクトのことで要素数も型も固定されていないです、配列は入った順にindexが振られるのでそれを指定することで呼び出します

key、valueがあるのがオブジェクトで、リストになっているのが配列です。(上手い説明が思い浮かびませんでした)

sample.js
// オブジェクト
const userData = {
  id: 1,
  name: "hoge"
};

console.log(userData.id)
// 1

// 配列
const person = [
  "hoge",
  "fuga"
]

console.log(person[0])
// hoge

配列の操作

配列の操作としては追加、削除などなどたくさんあります。

sample.js
let fruits = ["りんご","みかん"]
// 配列の末尾にバナナを追加
fruits.push("バナナ")
// ["りんご","みかん","バナナ"]
//  配列の末尾を削除
fruits.pop()
// ["りんご","みかん"]

MDNに一覧があるのでみましょう

イベントを登録できる、削除できる

javascriptを使えばイベントを登録、削除することができます、今回はclickイベントの例です。
まあこれは見ればわかると思います。DOMを指定してイベントをつけたり消したりします。

sample.html
<p id="p1" style="color: red">クリックして下さい</p>
<p id="p2">テストa</p>
<input type="button" value="削除" onclick="removeEL()" />
<input type="button" value="追加" onclick="addEL()" />
<script>
  const p1 = document.getElementById("p1");
  p1.addEventListener("click", changeName1);
  function changeName1() {
    const p2 = document.getElementById("p2");
    if (p2.textContent === "OK") {
      p2.textContent = "テストa";
    } else {
      p2.textContent = "OK";
    }
  }
  function removeEL() {
    p1.removeEventListener("click", changeName1); //イベントの削除
  }
  function addEL() {
    p1.addEventListener("click", changeName1); //イベントの登録
  }
</script>

MDNのJavascriptドキュメントを参照できる

MDNをわからなかったら読みましょう

tc39でプロポーザルが出されている機能を参照することができる

javascriptに新たな機能が追加される際にプロポーザルに詳細が書かれているのでそれを読みましょうという話です。
リンク先を見ればわかると思いますが、5つのステージに分けられており

stage 意味
0 アイデア
1 プロポーザルの目的や解決方法をデモで示す、提案
2 ドラフト
3 仕様は完成しておりフィードバック待ち
4 完成しており、取り込まれるの待ち

毎年ECMAScriptのバージョンが上がるので、その時までにstage4になったものが取り込まれます。
es2020でもOptional Chaininghoge?.valueNullish Coalescing Operator?? true:falseが追加されましたがみなさん試しましたか?
まだの方はぜひ試してみてください。

Typescript

静的型付けを理解している

世の中には動的型付言語(Python、Javascriptなど)と静的型付言語(C/C++/Goなど)があります。
静的型付とは変数や関数に型の記入を行うことで、これにより実行しなくともコンパイル時にバグやエラーを検知することができます。
また変数がどれだけメモリを使うかなどがわかるため無駄なメモリが発生しません。
一方でデメリットとしてはコードの記述量が増えてしまうことなどがあげられます。

なぜTypescriptを選ぶのか

個人的な意見ですが、例えばペライチのページなどの小規模のものであればJavascriptでいいと思います、しかし業務のコードなど規模が大きくなってくるとエラーが起こった時に型があるかないかはエラーの原因の特定などの面でとても大きいと思います。
加えてPRなどのレビューでコードを読む時にコメントを書かなくてもコードから関数の返してくる型がわかればコードを読むのが楽になります。
まとめると、チーム開発で規模の大きな開発の時にPRのレビュー、コードリーディング、新機能の追加などにおいてそれぞれのエンジニアの負担を軽減したいからだと思います。

扱える型について理解している

typescriptの型にはプリミティブ型とリテラル型、オブジェクト型があります。

種類
プリミティブ型 string, number, boolean, symbol, bigint, null, undefinedの基本型
リテラル型 その文字、数字などしか許されない型 foo 0など
void型 関数の帰り値で使われる何も返さないことを示す型、明記することはない
any型 次で説明します、簡単に説明するとなんでもありの最終兵器です
ジェネリクス 引数の型に応じて帰り値の型を決定するなど動的な型付けを行うことができます
タプル型 要するに配列の型です、ただし配列の操作を行うときは危険なので使わないほうがいいです。
オブジェクト型 intefaceやtypeを使ってオブジェクトに型をつけることができる
sample.ts
// void型
// 帰り値がないため自動的にvoid型となる
function click():void {
  alert("こんにちは")
}

// ジェネリクス
function Foo<T> (abc: T): T {
  return abc
}
// 引数の型に応じた型を帰り値の型にする
const res1 = Foo<string>('foo')
const res2 = Foo<number>(123)

// タプル型
const list = [string, number] = ["name", 18]

list.pop();
list.push('address');
// list = ["name", "address"]
const old = list[1]
// oldに入っているのは文字列だがコンパイルエラーは発生しない

// オブジェクト型
interface {
  foo: string;
  baz: number;
}

型の全体的な話についてはuhyoさんの記事がわかりやすいのでこれを読めば良いと思います。
ジェネリクスについてはYumetaroさんの記事がわかりやすいです

anyについて

こちらもuhyoさんの記事がわかりやすいのでこれを読めば良いと思います。
anyは敗北者です。

型定義できる

typescriptはかしこいので簡単な型定義であれば推測して型をつけてくれますがこのように明記もできます。

sample.ts
// 推論されるため countはnumber型になる
let count = 0
// 関数の帰り値の型を示す
increment(): number {
  this.count++;
}

場合において定義ファイルを作成できる

例えばライブラリを使用する時にtypescript対応していない場合は自分で型定義のファイルを書く必要があります。
vscodeなどでライブラリの型定義のファイルにジャンプすれば見ることができます。

index.d.ts
declare namespace JSX {
  interface IntrinsicElements {
    'group': any,
    'geometry': any,
    'lineBasicMaterial': any,
    'mesh': any,
    'octahedronGeometry': any,
    'meshBasicMaterial': any,
    'meshLine': unknown
    'meshLineMaterial': unknown
  }
}
declare module 'threejs-meshline'

これは私がreact-three-fiberというライブラリを使用した時に書いた型定義ファイルですが、このようにnamespaceとinterfaceを用いて書くことができます。(めちゃくちゃ適当です)

Nossaさんの記事がわかりやすかったです。

型ガードの理解がある

typescriptでは型ガードといってif文などを用いることで処理する変数の型を絞り込むことができます。

sample.ts
let sample: number | string = 1

if (typeof sample === "string") {7
  //sampleがstring型の時の処理
} else {
  //sampleがnumber型の時の処理
}

みたいな感じです
typeofだけでなくinstanceofinなどでも行えます。
typescriptのドキュメントがわかりやすいです。

新しいJSの機能を利用してできることを理解している

tc39のところで書いたので省略します。

最後に

WAI-ARIAの部分はもう少し頑張って書きます

参照

https://zenn.dev/yamanoku/scraps/632e570e160251839d48
https://qiita.com/oh_rusty_nail/items/e896825cd54e5c0a3666#計算式
https://qiita.com/morishitter/items/b9a2d78c79c3c07de776
https://qiita.com/Nossa/items/726cc3e67527e896ed1e
https://qiita.com/uhyo/items/aae57ba0734e36ee846a
https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a
https://qiita.com/Yametaro/items/bcd3166e5d2ad696a89e

https://developer.mozilla.org/ja/docs/Web/CSS/Using_CSS_custom_properties
https://zenn.dev/tak_dcxi/articles/a55d6c160dcb9f15605d

Discussion