はじめに
Web制作に携わるあなたは、イマドキのHTMLコーディングのトレンドについて知っていますか?
日々の業務に忙しく情報を追えていなかったり、学ぶヒマがなかったり。またトレンドを意識しなくとも案件が回ってしまうような、言い方は悪いですが生温い環境下に居ると、なかなかHTMLコーディングのトレンドを意識することがないという方もいらっしゃるかもしれません。
昨今の技術進歩と併せて、非常に高度化・複雑化してきているHTMLコーディングですが、下記のような技術を使わないコーディングは、あまり見かけなくなりました。
- HTML5
- CSS3
- CSSを使ったアニメーション
- JavaScriptによるダイナミックな動き・アニメーション
- Ajaxを使った非同期通信
そこで本日は、イマドキのHTMLコーディングのトレンドについて、最先端のコーディング環境はどういったものになっているか、技術者目線から紹介させていただきます。
今までのHTMLコーディング
HTMLコーディングというと、一昔前までは下記のようなものが標準でした。
- HTML4またはXHTML
- べた書きのCSS
- jQueryなどのライブラリを直接組み込み、べた書きのJavaScriptで制御
- IE6〜9などのレガシーブラウザに対応する
今でも上記のようなコーディング環境で作業をされている方や、未だに上記のような環境でリリースされているウェブサイトも多々あります。
今までのコーディングの問題点
上記の環境には、ざっと上げるだけでも下記のような問題があります。
- 意味を持った構造が定義できない
- CSSが膨大になるほど、CSSの記述が複雑になり、管理や修正が難しくなる
- レガシーブラウザや、多数のデバイスに対するCSSハックなどを自身で書く必要がある
- JavaScriptが増えるほど記述が煩雑になり、コードが膨大になる。
- JavaScriptのライブラリなど、依存しているファイル関係が分かりづらい上、読み込む順番によって動作しなかったりする
- JavaScriptの書き方によってグローバル変数などが大量生産されるため、予期せぬバグが起きやすくなる
- 外部JS等の読み込みが増えるほどリソースの読み込みが増え、サイトへのアクセスが遅くなる
CSSやJavaScriptをちょこっと書く程度の、簡単なコーポレートサイト程度であれば、今までと同様の方法でも問題無く対応出来るかもしれません。
ただ、昨今流行ってきているCSSアニメーションやJavaScriptによる動的な動きなどを多数利用するような、先進的なサイトを作ろうとすると、上記の技術では役不足、力不足になります。
イマドキのHTMLコーディングのトレンド
イマドキのHTMLコーディングのトレンドは、基本的に下記のような技術を組み合わせてサイトを構築していきます。
- HTML5
- CSS 3
- Webフォント
- JavaScript (ES2015)
- SCSS (SASS)
- Webpack
- タスクランナー(Gulp、Grunt等)
それぞれ、簡単に説明をしていきましょう。
HTML5
2014年に勧告されたHTMLの最新バージョンです。
今までのHTML4やXHTMLとは何が違っているかというと、
- 構造を意味づけする新しいタグ
- Flash等を利用しなくてもマルチメディア対応できるタグ・機能
- デバイスの位置情報や、カメラ・マイクといったリソースにアクセスできる機能
といった「最新のデバイス・ウェブ環境」に対応するための様々な機能が追加されています。
文章構造を表現するタグ
例えばsection
タグ、article
タグ、nav
タグといった新しいタグは、現在の文章でその箇所が「どういった意味を持つか」を明確に定義することが出来ます。
HTML4までのコーディングでは、下記のようにレイアウトを定義するのが一般的でした。
<div class="main"> <div class="header"> <h1>サイトの名前</h1> <nav class="navigation"> <ul> <li><a href="">メニュー</a></li> <li><a href="">メニュー</a></li> <li><a href="">メニュー</a></li> </ul> </div> </div> <div class="content"> <!-- コンテンツの内容 --> </div> <div class="footer"> <p>Copyright(c) 2018 Test all rights reserved.</p> </div> </div>
上記のように全てdiv
タグやspan
タグといった意味を持たないタグを使ってレイアウト構造を定義するため、そのdiv
タグが何を意味しているかは、コーディングした本人にしかわからず、意味をもった構造とは言いがたいものでした。(Class名でわかるじゃん!というのはこの問題の本質ではない、というのはわかりますよね?)
これをHTML5の「セマンティック」なタグで定義しなおしてみると、以下のようになります。
<main class="main"> <header class="header"> <h1>サイトの名前</h1> <nav class="navigation"> <ul> <li><a href="">メニュー</a></li> <li><a href="">メニュー</a></li> <li><a href="">メニュー</a></li> </ul> </nav> </header> <article class="content"> <!-- コンテンツの内容 --> </article> <footer class="footer"> <p>Copyright(c) 2018 Test all rights reserved.</p> </footer> </main>
header
タグやarticle
タグを使うことによって、その場所が「ヘッダー」だとか「本文」であるとか、「文章中でどういった意味合いを持つのか」ということを、その構造として定義することができるようになるのです。
videoタグ、audioタグ
また、video
タグやaudio
タグといったタグを利用することで、JavaScriptやYoutubeなどを使わなくても、ネイティブに動画や音声を埋め込んで再生させることもできます。
下記のように利用すると、mp4形式のビデオを直接埋め込むことが出来ます。
<video controls autoplay> <source src='sample.mp4'> </video>
その他
canvas
タグという、SVGという技術を使って図形などをコードで表現して表示するための専用のタグなども備わっています。
また、簡単なJavaScriptを使うことで、そのページを見ているユーザーのGPS情報を取得すると言ったことも可能です。
CSS3
2011年〜2012年に勧告された、最新のCSSバージョンです。
今までのCSS2と比べると、多数の内容が追加されており、非常に簡単に複雑なレイアウト等を実現することが可能になりました。
追加された機能は非常に多岐にわたるのですが、代表例でいうとFlexbox、トランジション(変化)、アニメーションという仕組みです。
Flexbox
今までのCSSでは、例えば2カラムのレイアウトを表現する場合、左カラムには float: left
というプロパティを指定し、右カラムにはfloat: right
というプロパティを指定するなど、floatの仕組みを用いてレイアウトを制御していました。
See the Pen float html by Masayuki Ietomi (@jyokyoku) on CodePen.
ただこの方法には問題点もあり、floatを使ったタグの高さが正しく取得できなくなるため、floatを含む要素を持つタグには、通称clearfixと呼ばれる回り込みを解除するためのCSSを書く必要がありました。
.container:after { display: table; clear: both; content: ""; }
また、floatしたタグ同士は高さを合わせることができないため、左カラムと右カラムで高さを合わせようとした場合には、JavaScript等を使って高さを合わせるといった必要があり、また縦の中央に揃えるといったこともできなかったので、縦中央に揃えたいと場合にはいろいろな工夫を施す必要がありました。
CSSから登場したFlexboxは上記のような不満点を全て解決出来る画期的な仕様で、Flexboxに指定したタグの中に配置したタグは、Flexboxの指定に沿って、自動的に横並びになり、またボックスの中央に揃えたり高さを合わせたりといったことが簡単に行えるようになります。
See the Pen flexbox html by Masayuki Ietomi (@jyokyoku) on CodePen.
いちいちclearfixをしなくてもレイアウトが崩れたりしないため、使いこなすだけで複雑なレイアウトが、本当に簡単に構築できるようになっています。
トランジション
CSS単体で「時間によって簡単な変化を行う」、トランジションという機能が追加されました。
transition
属性に変化させたいプロパティを指定し、hover等のタイミングでそのプロパティの値を変化させると、指定した秒数で、徐々にその要素が変化するようになります。
例えば下記のようなCSSを使うことで、指定したリンクにカーソルを合わせた場合、0.3秒掛けて徐々に透明度が下がり、フェードアウトのような効果が得られます。
See the Pen CSS Transition TEST by Masayuki Ietomi (@jyokyoku) on CodePen.
アニメーション
また、@keyframes
というアニメーションの効果を指定するためのフォーマットも用意されました。
keyframesはアニメーションでいうキーフレームと同様で、その要素のプロパティが0%〜100%までの間でどのように変化するかを指定しておき、複雑なアニメーションを実現するための仕組みです。
例えば下記のような@keyframes
を用意し、アニメーションさせたい要素に下記のような指定を行います。
See the Pen CSS Animation by Masayuki Ietomi (@jyokyoku) on CodePen.
この指定をおこなったリンク要素にマウスカーソルをhoverすると、ボタンが飛び跳ねる(バウンス)ようにアニメーションします。
組み合わせ次第では非常に複雑な効果をCSS単体で実現できるようになり、今までJavaScriptやFlashで行ってきたようなことを、CSSだけで代替できるようになりました。
Webフォント
印刷などと違い、ウェブでは利用出来る書体に制限があり、WindowsやMacに標準的に搭載されているフォントを指定する方法が一般的でした。
利用したいフォント名がわかれば、CSSに指定することで利用することはできるのですが、そのフォントが入っていないPCでその場所を見てしまうと、代替のフォントで表現されるため、制作者が意図したとおりの見た目にはなりません。
デザイン性の高い書体を使う場合には、文字を画像として作成して配置するといった方法を採るしかありませんでした。
そこで昨今普及してきた技術が「Webフォント」です。
これはフォントメーカーやGoogle等が、自社で開発したフォントなどを「Webで簡単に使える形」にして提供しているもので、指定したCSSを1つ読み込むだけで、Webで多種多様なフォントが利用出来るようになるというものです。
この技術を使うことで、制作者の意図する見た目で、デザイン性の高いWebサイトを作ることができるようになってきました。
JavaScript (ES2015)
JavaScriptにも進化が訪れています。
今までのJavaScriptは、他の言語で使える「Class」という概念が使えなかった(使えることは使えるが、特殊な定義方法が必要だった)り、変数のスコープが特殊であったりするために、書き方によってはグローバル変数が多数生み出され、複雑なJavaScriptを書いていると予期せぬバグが発生するといったことがありました。
また、ファイル自体を分割することはできるのですが、ライブラリなどの読み込みの順番がちょっとでも狂うとエラーが発生したり、そのファイルが「どのライブラリに依存しているのか」といったことが表からでは全く分からないため、管理がし辛いという問題点がありました。
そんな問題を解決するため、2015年にJavaScriptの新しい仕様「ES2015」が勧告され、利用され始めました。
ES2015では上記の問題を解決するために、いろいろな機能が実装されています。
import構文
CSSなどではおなじみのimport
という構文が使えるようになりました。
これは別のJavaScritファイルを、そのファイルの中に読み込む機能で、この機能を使うことで複雑だったライブラリとの依存関係を、ファイルの中に完結に書いておくことができます。
import jQuery from '../lib/jquery'; jQuery(function($) { // etc.. }
また、そのファイル自体がライブラリを読み込むことになるため、わざわざHTMLファイルにライブラリの読み込みを記述する必要がなくなり、読み込むファイル数が少なくなるメリットがあります。
class構文
遂に他の言語と同様の使用感で使える、Class構文が導入されました。
下記のように、Classを定義することが出来ます。
class Sample { constructor() { this.hoge = 'fuga'; } getHoge() { return this.hoge; } } class ExtendClsas extends Sample { constructor() { super(); this.hoge = 'hogehoge'; } }
constructer
等のメソッドも定義でき、またextend
キーワードにより既存のClassを拡張したサブクラスを作成することも出来るため、JavaScriptでも見通しの良いClass定義が利用出来るようになりました。
let, constによる変数宣言
従来の var による変数宣言に加えlet
とconst
いうキーワードでの変数宣言が出来るようになりました。
この変数宣言はvar
での変数宣言と違い、変数の有効なスコープが制限されています。
例えば今までのJavaScriptでは、var
で宣言した変数は関数スコープのため、ブロックスコープで囲っても下記のようなコードは変数の2重宣言になってしまい、エラーとなります。
if (true) { var test = 'hoge'; } if (true) { var test = 'fuga'; } var test = 'poyo';
しかし、新たに定義されたlet
, const
というキーワードでは、定義したブロックのスコープでしか有効になりません。
if (true) { let test = 'hoge'; } if (true) { let test = 'fuga'; } let test = 'poyo';
また、const
というキーワードで定義された変数は、あとから変数の値を差し替えることができなくなるため、変数の再定義を防ぎ、バグの混入をより押さえることが出来るようになっています。
ヒアドキュメント
念願の、文章中に変数を埋め込む方法が利用出来るようになりました。
文章をシングルクォートやダブルクォートではなく、バッククォートで埋め込むことで、文章中に直接変数を埋め込むことが出来るようになり、また改行などもそのまま反映が出来るようになりました。
これにより、いちいち改行を挟む際に+演算子で文章同士を繋げる必要がなくなり、また変数も直接展開出来るようになったため、特にHTMLコードなどを埋め込む際に可読性の高いコーディングが出来るようになりました。
const hoge = 123; const hereDocument = ` <div><span>${hoge}</span> </div> `;
ES2015の問題点
非常に便利な記述が増えたES2015ですが、残念なことにブラウザの対応が追いつかず、ブラウザでは全ての機能が利用出来ない場合があります。
2018年現在、ChromeやFirefoxの最新版などではimport構文を含めた殆どの機能が利用出来るのですが、IE11や若干古めのAndroidの標準ブラウザでは、import構文が利用できなかったり、その他の記述が利用出来ない場合があります。
なのでIE10以下の既にサポートが打ち切られたようなブラウザは論外として、IE11以上のブラウザや一般的に利用されているスマートフォンなどに対応する場合、そのままでは利用することが出来ないのです。
SCSS (SASS)
CSSは単純なものであれば大丈夫ですが、サイトの規模が大きくなってくると、CSSのカスケーディングが複雑化してくる傾向にあり、おなじClass名などを何度も繰り返し記述する必要があり、非常に煩雑になってくる傾向にあります。
.parentClass .childClass1 { font-size: 16px; } .parentClass .childClass1 .childClass2 { font-size: 14px; } .parentClass .childClass1 .childClass3 { font-size: 12px; }
上記のような記述方式のため、例えばクラス名を変更しようとした場合、複数の箇所に定義されているクラス名を全て変更しなければならず、その管理に非常に大きな手間がかかってきます。
違う親に依存する同一のクラス名などが存在すると、一括で書き換えることも出来なくなり、管理に非常に手間がかかります。
.parentClass1 .title { /* parentClass1に依存するtitleクラス */ } .parentClass2 .title { /* parentClass2に依存するtitleクラス */ }
そこで登場するのが、このSCSSという仕組みです。
これはCSSを拡張した「メタ言語」で、プログラミングの概念をSCSSに取り入れ、前述のCSSの欠点を大きく補ってくれます。
CSS構造のネスト
SCSSを利用する上でまず外せないのが、このCSS構造のネストの仕組みです。
通常のCSSでは、カスケーディングを実装するためには下記のように、セレクタを並べて記述する必要があり、親のセレクタの指定が増えれば増えるほど管理が煩雑になるというデメリットがありました。
.parentClass1 .childClass1 { /* スタイル定義 */ } .parentClass1 .childClass2 { /* スタイル定義 */ }
しかし、SCSSでは下記のように、親のスタイル定義の中に子となるスタイルの定義を「ネスト」して記述できるようになり、非常に簡潔に記述出来るようになっています。
.parentClass1 { .childClass1 { /* スタイル定義 */ } .childClass2 { /* スタイル定義 */ } }
こうすることで、例えば親のClass名が変わったとしても、1箇所を変更するだけで対応できるようになります。
変数
他の言語のように「変数」の仕組みが利用出来るようになっています。
$var: #ffffff
このように定義しておくだけで、下記のように呼び出して利用することが可能になります。
.style { color: $var; }
こうすることによって、例えばサイトに使うカラーを最初にまとめて変数に定義しておき、スタイルではその変数を個別に利用することによって、あとからサイトのカラーを簡単に変更することができるようになります。
$textColor: #ff0000; $bgColor: $333333; .style1 { color: $textColor; } .style2 { background-color: $bgColor; } .style3 { color: $textColor; background-color: $bgColor; }
上記の例では、$textColor
の値を変更することでstyle1
とstyle3
のcolor
プロパティがその値に自動で変更され、$bgColor
の値を変更することで、style2
とstyle3
のbackground-color
プロパティがその値に自動で変更されます。
それぞれのスタイルを一つ一つ変更する必要性がなくなるため、管理が非常に楽になります。
関数
他の言語のように、関数を利用することが出来るようになっています。
@function adjustTextSize(size: 12px) { @return size * 2; }
上記の関数は、与えられたフォントサイズを2倍にして返す機能を持っています。
この関数を、プロパティに利用することが出来ます。
.style1 { font-size: adjustTextSize(20px); }
SCSSでは四則演算やif/elseの仕組み、forによる繰り返しといったプログラミングの基本とも言える制御構造が利用出来るようになっているので、そういった機能を組み合わせて、もっと複雑な機能を提供する関数を利用することができるようになっています。
テンプレート
よく使うスタイルってありますよね?
SCSSではそれを定義しておき、いろいろなClassで使い回せるテンプレートの仕組みがあります。
%linkText { font-size: 16px; color: #ff0000; text-decoration: underline; } .mainColumn a { @extend %linkText; } .sidebar a { @extend %linkText; }
上記の例では、%linkText
というテンプレートにリンクのスタイルをまとめておき、複数のaタグのスタイルに、そのテンプレートを適用するようになっています。
こうすることで、同じようなスタイルを1箇所にまとめておき、それを利用したいクラスで読み込むこむことで、よく利用するスタイルを1つの場所で一括管理できます。
mixin
SCSSの醍醐味と言える機能です。
関数とテンプレートを組み合わせたような機能で、使いこなすことでCSSの管理が非常に便利になります。
例えばレスポンシブデザインのためのメディアクエリを、このmixinにまとめることで、可読性の高いCSSを記述することが出来ます。
例えばスマートフォン用のCSS記述ですが、通常のCSSでは下記のようになります。
.style { font-size: 18px; } .style2 { color: #ff0000; } @media only screen and (max-width: 768px) { .style { font-size: 12px; } .style2 { color: #000000; } }
これをSCSSで完結に記述してみましょう。
メディアクエリをmixinに記述し、スタイルで使ってみます。
@mixin sp($device) { @media only screen and (max-width: 768px) { @content; } } .style { font-size: 18px; @include sp { font-size: 12px; } } .style2 { color: #ff0000; @include sp { color: #000000; } }
通常のCSSで記述するよりも、記述する場所が直感的でわかりやすいことが理解出来ると思います。
SCSSの問題
SCSSは非常に便利なのですが、1つ大きな問題点があります。
それは、ブラウザで直接読み込むことが出来ないということです。
ブラウザはCSSのみを解釈できるようになっているため、SCSSのようなメタ言語はそのままの状態では読み込むことが出来ません。
ではどうするか、というと「コンパイル」という操作を行い、SCSSをブラウザも読み込めるCSSの形式に変換するのです。
このコンパイルという作業が意外と面倒で、SCSSを編集したら毎度コンパイルを行い、CSSに変換しないといけません。
Webpack
このWebpackはJavaScriptやCSS、HTMLといった実際にウェブサイトを構成する仕組みではではなく、JavaScriptやCSS等を変換したり、Web開発を便利に行うための「ユーティリティ」です。
簡単に紹介すると、下記のような機能を提供してくれます。
- JavaScriptの連結
- SCSSのコンパイル
- ローカルサーバー
- ファイルの変更監視
Webpackの主な役割
Webpackの主な役割は、モジュールバンドラーと呼ばれる所以にもあるように「JavaScriptの連結」です。
ES2015の記述にあるimport文などを利用することで、JavaScriptを1つのファイルにまとめて出力してくれます。
ES2015の仕様にあるimport文は、ES2015の問題点でも解説したように、まだ全てのブラウザで利用することが出来ません。
一般的なウェブ制作で利用する際には、このWebpackのようなモジュールバンドラーを用いて、実際に1つのファイルとして出力して利用する必要があるのです。
タスクランナーとしての側面
また、Webpackはモジュールバンドラーとしての役割の他に、後述するタスクランナーのような仕組みも同時に備えています。
SCSSのコンパイル等も機能提供しているため、このツールを使うことで、ES2015の問題点やSCSSの問題点を解決し、最新の技術を使ってウェブ制作を行うことができるようになります。
Webpackを使った環境構築
このWebpackを使うと、簡単に下記のような環境を構築することが出来ます。
- ES2015のJavaScriptを解析し、import構文で利用されているファイルを1つのファイルに連結して出力する
- SCSSのファイル変更を監視し、ファイルが変更されたタイミングでSCSSをCSSにコンパイル
- ローカルサーバーを起動し、HTMLファイルをプレビュー
- HTMLファイルやSCSS、JavaScriptが変更されたタイミングで、ブラウザを自動更新
ファイルを監視し、変更されたらブラウザを自動更新するといった機能は、いちいちファイルを書き換えるたびにブラウザにフォーカスを移し、更新ボタンを押すといった手間が省けるため、HTMLの開発やJavaScriptの開発では非常に利便性が高いです。
導入にはコマンドラインの利用が必須になりますし、設定ファイルが非常に複雑なため、導入のハードルは高いのですが、一度設定さえしてしまえば非常に便利な開発環境が整います。
タスクランナー
タスクランナーとはそういう名称のソフトがあるわけでは無く、いろいろな「タスク」をまとめて、コマンド1つで実行出来るようにするツールの総称です。
上述したWebpackもタスクランナーとしての側面を持ち合わせています。
このタスクランナーで有名なツールでは、一昔前に流行った「Grunt」、最近の主流である「Gulp」などがあります。
どちらも同じような機能を提供するツールですが、Gulpの方が後発でタスクの書き方がわかりやすく、最近ではこちらがメインで利用されています。
Gulpで出来ること
Gulpを使うことで、下記のようなことが簡単に実現できます。
- SCSSをコンパイル
- CSSやJavaScriptを圧縮
- CSSが古いブラウザでも利用出来るよう、ベンダープレフィクスを自動で付与する
- 画像の最適化
- ファイルの名称を自動で変更
上述のWebpackの内容をご覧いただくと、「あれ?Webpackと何が違うの?」という感じになりますが、主な目的が異なります。
WebpackがJavaScriptファイルの結合に特化し、SCSSのコンパイルやタスクランナー的な機能も補助的に行えるのに対し、Gulpは純粋なタスクランナーです。
Gulpはタスクランナーであるという仕組上、タスクやそれを実行するためのライブラリ、プラグイン等が無ければ何も出来ないのですが、それ故に組み合わせるライブラリやプラグインが非常に多数あり、おおよそ出来ないことが存在しないくらい、いろいろなタスクを実行することが出来るようになります。
Gulpによるタスク登録
GulpではJavaScriptを使ってタスクを登録することができます。
試しにSCSSをコンパイルするためのタスクは下記のように記述できます。
const gulp = require("gulp"); const sass = require(”gulp-sass"); const plumber = require("gulp-plumber"); const sourcemaps = require("gulp-sourcemaps"); gulp.task('scss', () => { gulp.src(['./src/scss/**/*.scss']) .pipe(plumber()) .pipe(sourcemaps.init()) .pipe(sass({outputStyle: 'expanded'})) .pipe(sourcemaps.write()) .pipe(replace(/url((["']?)../../assets//g, 'url($1../')) .pipe(gulp.dest('./assets/css/')); });
GulpとWebpackの使い分け
WebpackにもLoaderというプラグインのような仕組みがあり、いろいろなものが開発されていますが、その柔軟性や豊富さでは、Gulpの方が使い勝手が良いでしょう。
GulpからWebpackを実行するためのプラグインも存在するため、現状ではGulpをメインのタスクランナーとして利用し、SCSSのコンパイルやファイルの監視に利用し、WebpackをJSの結合といったピンポイントの機能として利用するというのが、モダンな開発環境になっています。
おわりに
いかがでしたでしょうか?
簡単でしたがイマドキのHTMLコーディング環境について、ざっと概要を触れさせて頂きました。
HTMLコーディングという基本の作業であっても、時代によって大きく方法が異なってきます。
古いやり方でももちろんコーディングは可能ですが、新しいやり方を取り入れることで、コーディングの時間が劇的に短縮できたり、より高度な表現が可能になります。
クライアントのためにもなり、かつ自分のためにもなる!一石二鳥の感覚でHTMLコーディングにトレンドを取り入れ、技術を学んでみてはいかがでしょうか?