新卒社員が本気でengineerを目指してみた

エンジニアリング未経験の新卒社員が本気でエンジニアを目指すための勉強記録

設計を学んでなんとなくCSSを書くのを卒業してみたい【Part1】

概要

なんとなくCSSを書いていた初心者の私がフロントエンドエンジニアとして設計から考えてCSSを書くために学んだことをまとめてみた。

CSS設計の重要性

Webは構造そのものを大きく変更したり、予想外の要素を差し込む・差し引く可能性がある。この事態は誰にも予想はできないが、どのように変化に対応しても全く手を入れる必要がないCSSを書くのは不可能。 だからいかにしてメンテナンス効率を下げずに、また少ない工数で回収ができるようにするための設計が重要。

よりよいCSSとは以下が重要

  • 予測しやすい 期待通りに振る舞うかどうか。他のルールが影響して、記述した通りにならない・追加したルールが他のルールに影響を与えることがないようにすること。

  • 再利用しやすい CSSがコピペで膨大にならないようにする。そのためには抽象的で機能ごとに分離されている必要がある。UIデザインに対してマークアップCSSを一度作れば、再度同じようなUIに遭遇したときにわざわざ書き直す必要がない。

  • 保守しやすい 追加したルールによって既存ルールを壊さないために、新しいルールを追加するときに、既存ルールのリファクタを必要としないこと。 ・拡張しやすい プロジェクトに関わる自分と自分以外がメンテ・管理しやすくする。この拡張しやすいとは、サイトの規模が大きくなるにつれて、拡張しやすいようになっているものかどうか。

コンポーネント設計

コンポーネント設計とは、CSSの再利用性や保守性を高めるための機能や振る舞いなどを明確に分離すること。 あるコンポーネントの変更が、別のコンポーネントを壊してしまうといったことを防ぎ分離が成立させる。 その結果、メンテナンス性が高まり、また他のコンポーネントとの不要な依存関係をなくすことで再利用性も高まる。

OOCSSとは

OOCSSの中でのオブジェクトは、繰り返されるビジュアルパターンを指し、1つのまとまったHTML, CSS, jsで書かれた独立したスニペットとして再利用できるもの。 OOCSSの原則は

構造と見た目の分離

コンポーネントの基本構造と、具体的なルール・機能を分離すること

f:id:shorugby14:20191016000401p:plain
(引用: https://www.kaqiita.com/entry/2019/02/11/074006)

//alert.html
<div class="alert success">成功!</div>
<div class="alert warning">警告!</div>
<div class="alert error">エラー!</div>
//alert.css
.alert {
  border: 2px solid #333;
  border-radius: 6px;
  padding: 10px;
  font-size: 16px;
  color: #333;
}

.success {
  border-color: #494;
  background-color: rgba(68, 153, 68, 0.3);
}

.warning {
  border-color: #DD0;
  background-color: rgba(221, 221, 0, 0.3);
}

.error {
  border-color: #C44;
  background-color: rgba(204, 68, 68, 0.3);
}

こうすることによる.alertで基本的な体裁・構造を作っておき、基本構造を別ルールとして分離させておく。そして、バリエーションとして存在する色を別のルールとしてまとめる。こうしてclass属性に複数の値を持たせて任意のアラートメッセージを作る。 こうすることでコードも少なくなり、基本デザインが変わっても.alertだけの微小な修正で済む。新しいバリエーションが増えた場合も、新しいルールを追加するだけで済む。

コンテナーとコンテンツを分離

場所に依存しないセレクタを書くということ。 サイトのロゴがあった場合に、ヘッダーに最初に使っていたとする。

#header .logo {
    display: inline-block;
    width: 200px;
    height: 80px;
}

しかしフッターにも同じロゴを追加したいときは

#footer .logo {
    display: inline-block;
    width: 200px;
    height: 80px;
}

を追加しないとならない。 これならば、.logoという部品として単純に定義することができ、また小さいロゴが欲しいとなったときも対応できる。

.logo {
    display: inline-block;
    width: 200px;
    height: 80px;
}
.small-logo {
    width: 140px;
    height: 56px;
}
//html
<h1 class=“logo logo-samall">CSS</h1>

場所に依存しないことで、他に置くこが必要になったとしても大きな修正は不要となる。

SMACSS

SMACSSは場所に依存したセレクタではなくコンポーネントを拡張していくアプローチの設計など、OOCSSをより実践的に扱うためのガイドラインの1つ。 SMACSSの特徴は以下。

カテゴライズ

ページに存在する多くのパターンを、CSSのルールを5種類にカテゴライズした上でそれぞれの考え方や記述ルールを取り決めている。

Base

近年のCSSの開発でreset.cssやnormalize.css, sanitize.cssなど要素のスタイルを初期化するライブラリを採用することが増えている。全体の背景やフォントファミリーなど基本的にこのカテゴリで定義した、よほどの理由がない限り書き換えることがないものなど、要素そのもののデフォルトスタイルを定義していること。

Layout

IDを用いて定義するようなヘッダーやフッター、コンテンツエリアやサイドバーなど構成の大枠やセクションを作る要素へのルール。 IDセレクタは詳細度を高めるが、レイアウトのような大きなセクションはページごとに1つしか存在しないため許容範囲といえる。しかし、場所に依存するセレクタは書かないように注意する。 またグリッドレイアウトルールのようなものもSMACSSではLayoutに含んでおり、クラス名の頭にl-*(Layoutの頭文字)をつけるような命名規則もある。

#header, #footer {
    hoge
}

#sidebar {
    hoge
}

/* 場所に依存するセレクタなのでダメ! */
#sidebar .menu {
    hoge
}

/* l-*(Layoutの頭文字)をつける命名規則 */
.l-grid {
    hoge
}
Module

Layoutパターンを除く、ページを構成するほぼ全てがこのカテゴリに属する。ボタンや見出し、リンクやアラートメッセージなど再利用できるオブジェクト単位でパーツのスタイルを定義すること。

State

jsの制御により切り替わるような、状態を表すルール。要素を隠すものや、エラー表示のものなどが一例。 クラス名の頭にls-*をつけるような命名規則もある。

.is-hidden {
    display: none;
}

.is-error {
    color: indianred;
}

見た目が変わるものは、モジュール名をつけることで汚染を防ぐ。

.tab {
    display: inline-block
    Background-color: hoge1;
    color: hoge2
}

.is-tab-active {
    Background-color: hoge3;
    color: hoge4
}

/* このような.is-active単独のルールは設けないようにする */
.is-active {
    font-weight: bold;
}

SMACSSはStateには!importantの使用を推奨している。Stateは必然的にそのスタイルに変更することが目的なので、詳細度の高い!importantを使うことは許容範囲になる。 コンポーネントの状態を制御する意味ではメディアクエリもそうなので、メンテナンスを考えるとメディアクエリのルールのコンポーネントののスタイルに置くのがメンテナンス性は高い。

.l-grid > li {
    float: left;
}

@media screen and (max-width: 400px) {
    .l-grid {
        float: none;
    }
}

メディアクエリが一箇所に集約されない分、宣言する箇所は増えるがコンポーネント単位での設計を考えた場合はこれが正といえる。

Theme

サイト全体の見た目の雰囲気を統一させるための定義をする。いわゆるテーマを切り替えるような機能が求められるCSS。 Theme-*接頭辞の命名規則がある。

/* theme/sea.css */
.theme-background {
    background-color: aqua;
}

.thema-border {
    border: 1px solid blue;
}
//html
<div class="theme-backgroud">
    <div id="header" class="theme-border"></div>
    <div id=“sidebar" class="theme-border"></div>
</div>

このような設計であれば、どの要素に対してもテーマのスタイルが定義されるのが明確になる。

BEM

命名規則での設計アプローチ。BEMはBlock, Element, Modifierの略。

Block

入力フォームやアラート、ヘッダーやフッターなどの大きなセクションのこと。

.alert {
    hoge
}
Element

Blockを構成する要素。アラートメッセージの例だと、 それを構成する.alert-titleや.alert-bodyがElement。 BEMの命名規則だとalertというBlockに対する、titleというElementということで__を使う。

.alert__title{
    hoge
}
Modifier

BlockまたはElementのバリエーション違いの要素。アラートメッセージの警告用のスタイルのバリエーションだったり、SMACCSのStateカテゴリのような状態の違いも含む。 Modifierの場合は_一つで区切る。

.alert_warning {
    hoge
}
//html.slim
.alert.alert_warning
    h2.alert__title
        | hoge

コンポーネントを構成する要素に対してそのコンポーネント名を名前空間として扱いクラス名の接頭辞にすることで、どれがコンポーネントを構成する要素であるかを明らかにでき、他スタイルへの汚染を防ぐことができる。またどのクラスがどのコンポーネントのどういった機能かもDOMからわかることができる。

MindBEMding

ElementをBlockの親子とし__で区切り、Modifierをバリエーションの違いとして対等を評価し—で区切る。 またニコラス・ギャラガーが開発した、suitCSSでは単語の区切りをアッパーキャメルケースを採用しBlockの名前の頭を大文字にしている。Elementgはアンスコではなくハイフン1つ、Stateパターンはis-命名規則を採用。 また、Utilityと呼んでいる汎用的な機能はu-を採用している。

MCSS

Multilayer CSSの略でレイヤー間の依存関係を明確にすることでスムーズなコンポーネント化を進めることができる。

基本原則

コンポーネントの持つスタイルを1つのセクションの中でまとめられる。BEMでいうBlock, Element, Modifierがまとまて同じ箇所に記述し、メンテナンス対象を絞り込むことができる。 Elementの記述方法はBEMと同じだが、ModifierはBlock名を除き__ではじまる命名で、Blockのクラスと結合したセレクタにする。

.alert {
    hoge
}
.alert.__warning {
    hoge
}

.での結合はIE6では正しく解釈されないので注意。SMACCSのStateで!importantを許容したように、Blockである.alertのルールの拡張・変更が目的であれば確実なので許容される。 __modifier単体のセレクタのルールを記述すると、いずれかのコンポーネントのスタイルを汚染する可能性があるから注意。

Foundation

SMACCSでいうBaseカテゴリと同様。プロジェクトの土台として、reset.cssなどを用いて各要素を初期化する。よって最初に読み込みをする必要がある。

Base

プロジェクトの各所で再利用でき、抽象的な要素。ボタンやフォームなどが該当し、他のレイヤーから用意に拡張・変更ができるようなものである必要がある。 Baseレイヤーからのカスケーディングルール ・BaseレイヤーコンポーネントからBaseレイヤーコンポーネントを上書きできる。 ・BaseレイヤーコンポーネントからProjectレイヤーコンポーネントを上書きできない(下層レイヤーからの上書きを禁止する)。

Project

Baseレイヤーコンポーネントよりも具体的なページを構成する要素。Projectレイヤーコンポーネント内でBaseレイヤーコンポーネントを用いる場合、上書きすることができる。

//html.slim
ul.comment-list.block-list
    li.block-list_item
        | hoge1
    li.block-list_item
        | hoge2
//BaseLayer
.block-list {hoge}
    .block-list_item {
        border-bottom: 1px
        padding: 0.3em 1em
    }

//ProjectLayer
.comment-list {hoge}
    .comment-list .block-list_item {
        padding: 0.5em 1em
    }

Projectレイヤーにおけるカスケーディングルール ・Projectレイヤーコンポーネント内でBaseレイヤーコンポーネントを上書きすることができる。 ・Projectレイヤーコンポーネント内でProjectレイヤーコンポーネントを上書きすることができる。

Cosmetic

下層のレイヤーコンポーネントには含まれないような、ちょっとしたスタイルが含まれる。リンクカラー、少数のプロパティで構成される.font-sizeXLのようなクラス、グローバルなModifierが例。 部分的に他のリンクカラーと違う色を使いたいときや、部分的にフォントサイズやマージンを与えるものや、要素を隠すためのdisplay: noneを持つクラスなども含まれる。

//html.slim
.login_submit
    Button.login_button.btn
        | ログイン
    = link_to ‘パスワード忘れましたか?’, class: ‘al’
// FoundationLayer
a {
    color: blue;
}

//Cosmetic
.al {
    color: red;
}

.font-sizeXL {
    font-size: 48px;
}
.hidden {
    display: none
}

Cosmeticレイヤーにおけるカスケーディングルール ・Cosmeticレイヤー自身を含め、例外のコンテキストレイヤー以外のレイヤーからは上書きできない Contextとは特定のブラウザやログイン中のときなど、メディアクエリによる特定条件下にある場合に例外的なスタイルを用意するためのレイヤー。

.button {hoge}
    .touch .button {
        lone-height: 44px;
    }

@media screen and (max-width: 320px) {
    .button {
        padding: 0;
        width: 100%;
    }
}

FLOCSS

OOCSSやSMACCS, BEMの命名やMCSSのレイヤー設計のアイデアを取り入れている。

基本原則

Foundation Layout Object(Component, Project, Utility) で構成されている。

Foundation

reset.cssなどを用いて各要素を初期化したり、プロジェクトの基本スタイルを定義する。

Layout

ヘッダーやメインのコンテンツエリアなどプロジェクト共通のコンテナーブロックのスタイルを定義する。基本的にページ単位で1つなのでIDセレクタ使用が推奨。

Object

FLOCCSでは基本的に全てをコンポーネントのように扱う。その中でレイヤーの概念を持ち、上書きのルールを定めている。

Component

汎用性が高く、再利用性が高いものを定義する。最低限の昨日を持ったものとして定義されるべきで、それ自体が固有の幅や色を持つことは避けるべき。

Project

いくつかのComponentとそれに該当しない要素によって定義する。MCSSのProjectと同様で記事一覧や画像ギャラリーなどコンテンツを構成する具体的な要素が該当する。 ページを構成する要素のほとんどがこのレイヤーのコンポーネントに該当する。

Utility

ComponentとProjectレイヤーのModifierで解決が難しい・わずかなスタイル調整のための便利なクラスなどを定義する。 MCSSのCosmeticレイヤーに近い。Object自体が持つべきでないmarginの代わりに.u-mbs{margin-bottom: 10px;}のようなUtilityObjectを用いて隣接するコンポーネントとの間隔を作るといった役割がある。

命名規則

役割を以下のように明確にし、クラス名から役割がわかるようにする。 Component: .c- Project: .p- Utility: .u-*

カスケーディング

後ろのレイヤーほど具体的でカスケードが強いルールじゃないといけない。 原則として、レイヤー間のカスケーディング、他のコンポーネントを親とするセレクタを用いたカスケーディングは禁止。

// Component
.c-button {
  ...
}
.c-dialog .c-button {
  ...
}
 
// Project
.p-comments {
  ...
}
.p-articles .p-comments {
  ...
}

スクラムガイドを読んでみたので流れをまとめておく。

概要

スクラムガイドを読んだのここに概要をまとめておく。

※参考 スクラムガイド アジャイル用語集

スクラム

スクラムの3本柱は透明性と検査と適応。 この3本柱を意識しながらスクラムを実践することが大事。

  • 透明性 チームの現状やプロダクトの状態、問題点を見える化(検査)する
  • 検査 進捗を頻繁に検査し、変化を見地する。
  • 適応 プロセスの不備が許容値を超えたときに調整する。

検査と適応を行うのは スプリントプランニング->デイリースクラム(朝会) ->スプリントレビュー->レトロスペクティブ を繰り返す。

スプリントプランニング

チームの共同作業であり、スプリントでの作業を計画する。 プロダクトオーナーはスプリントで達成すべき目的とバックログのアイテムについて検討する。 開発チームは開発する機能を予測しバックログから選択するアイテム数に責任をもつ。 プロダクトバックログとインクリメントとベロシティを参考に作業を見積もる。

デイリースクラム(朝会)

昨日やったこと、今日やることを発表する。前日の朝会での計画の検査と次回の朝会までに行う作業の見積もり。

昨日やったこと=>開発チームがスプリントゴールを達成するために、私が昨日やったことは何か?
今日やったこと=>開発チームがスプリントゴールを達成するために、私が今日やることは何か?
困ったこと=>私や開発チームがスプリントゴールを達成するときの障害物を目撃したか?

また、スプリントの進捗を検査する。タスクボード(アクティブなスプリント)とイテレーションバーンダウンチャート(タスクボードに残っている未完了タスクの見積もり所用時間の合計をグラフにしたもの)を見せるといい。

スプリントレビュー

インクリメントの検査。スプリントの成果とバックログの変更を参考に、価値を最適化するために次になにができるかを話し合う。 開発チームは、スプリントでうまくいったこと・直面した問題点・それをどのように解決したかを議論する。

レトロスペクティブ

チームの検査と次のスプリントの改善計画を立てる。 うまくいったこと、改善が必要な項目の整理。レトロスペクティブ内で改善項目を特定することでチームを検査し、改善実施計画を立て改善する。それによってプロダクトの品質向上方法を計画する。

開発初心者がスクラムマスターをやるために、アジャイルな開発手法を学んでみた。

概要

開発初心者の私がスクラムマスターをやるために、アジャイルな開発と見積もり作りを読んでアジャイルな開発手法を学んでみたので、ここに簡単にまとめておく。

アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~

アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~

アジャイルな開発とは

アジャイル開発は、システムやソフトウェア開発におけるプロジェクト開発手法のひとつで、大きな単位でなく小さな単位で実装とテストを繰り返し開発を進めていく手法で、決められた計画に従うよりも起きた変化に適応することに価値をおく! チームメンバーの役割は プロダクトのビジョンを考え、最も価値の高いフィーチャを開発するための優先順位付けに責任を持つプロダクトオーナー。実際に開発を行い、設計やコーディング・テストを行う開発メンバー。運用ルールや進め方をプロダクトオーナー・開発メンバーに説明して効果的な実践を促すことにより、プロジェクトを円滑に進めるための調整役のスクラムマスターがいる。

アジャイルな計画作りとは

アジャイルな計画作りは長期的な目標を達成するための適切なゴール設定と見直しのプロセスのことをいう。 リリース、イテレーション(スプリント)、デイリーの3つを基準に計画を立てる。リリースプランニングのゴールはスコープ・スケジュール・リソースを満たすことで、プロダクトオーナーのスケジュールや予算や品質などを満足のいく条件でプランニングすること。イテレーション(スプリント)プランニングは達成すべき優先度の高い作業を決定すること。デイリープランニング(朝会)は作業の調整と同期化。このようにイテレーションプランニングを何度も繰り返す。 以下ではアジャイルな計画作りに大事なポイントをまとめる!

規模の見積もり(リリースプランニング)

アジャイルな見積もりと計画作りの信条は”規模を見積もり、期間は導出すること!! ストーリーポイント(ユーザーストーリーやフィーチャ、その他の作業の大きさを表す単位)を相対的になにかを基準に見積もる。ベロシティとはチームの進むスピードのことで、1回のイテレーションで完了させたストーリーポイントに合計のこと。 プロジェクトの規模は必要な全てのストーリーポイントの見積もりの合計から、チームのベロシティがわかるとこれで割ることによりイテレーションの数、すなわち期間がわかるのでスケジュールを見積もれる。

イテレーション(スプリント)プランニング

リリース計画で扱う大きなユーザーストーリーをイテレーション計画ではタスクに分解する。 タスクの見積もりの技法としては単位をフィボナッチ数列を使って、その分野に詳しい人から意見を聞くことができるプランニングポーカーを使って、チーム全員で合意できるポイントに達するまで話し合うのがいい。

デイリープランニング(朝会)

デイリープランニング(朝会)ではJIRAのアクティブなスプリントのようなタスクボードでチームの作業を整理し可視化する。またバーンダウンチャート(タスクボードに残っている未完了タスクの見積もり所用時間の合計をグラフにしたもの)を用いて現在のイテレーション作業をトラッキングするといい。 f:id:shorugby14:20190719235958j:plain 朝会のいい進め方についての参考:朝会ガイド

総じてアジャイル開発とメリットとは

  • 規模で見積もってから期間を見積もる! まず規模(ユーザーストーリーをストーリーポイントで見積もった規模)を見積り、そこからチームの進むスピード(ベロシティ)を用いて期間を見積もる。

  • 頻繁に計画を見直す! イテレーションを繰り返しながら頻繁に計画を見直すので、完璧な計画を立てることよりも現時点で有用な計画を立てることに集中でき、開発するにつれて得た知識を計画に反映することができ、計画が有用になっていく。

などを考慮し、優先順位の高いものから開発することで短い期間で最大限の成果をあげ、チームでまわりを巻き込んで開発・見積もりを行うため自立的なチーム作りができる、日々状況をトラッキングしているので発生した問題の検知がはやい、またイテレーションごとに頻繁に計画を見直すので早めに軌道修正ができるというメリットがある!!

gulpについて考えてみた

はじめてのgulp!

gulpとは

f:id:shorugby14:20190627232803p:plain gulp.js 公式サイト gulpはNode.jsをベースとしたビルドシステムヘルパーで、こいつを使えばさまざまな作業を自動化することができます。 GruntはJSONで記述するが、glupはjsで記述し、Gruntでは基本的に同期処理であるためタスクは1つずつ実行されるがGulpでは基本的に非同期処理なのでタスクが高速に処理できる。 これを使ってTypeScriptのコンパイルCSSのminifyやconcatやファイルのコピーなどをすることができる!これを自動化することにより、作業を効率化させることができる。

導入

(1) node.jsをinstall

(2) package.jsonの作成 以下のコマンドでインストールしたパッケージを管理するできるpackage.jsonを作成

$ npm init -y

package.jsonに以下を記述しておくと"npm run gulp"などが使えて便利

{
  "private": true,
  "devDependencies": {
    "gulp": "^3.9.0"
  },
  "scripts": {
    "gulp": "gulp",
    "start": "gulp"
  }
}

(3) gulpのinstall

$ npm install --save-dev gulp

(4) 使用するプラグインをinstall

$ npm install --save-dev プラグイン名

CSSをminifyしてくれるgulp-minify-cssやファイルを1つにまとめるgulp-concatなど使用するプラグインをインストールします。 するとすると"node_modules"というフォルダのに「gulp-minify-css」や「gulp-concat」などが作成される。

実際にgulpfile.jsを記述してみる!

今回は例にgulp-minify-cssを使ってみる CSSを圧縮できる!便利だね。

const gulp = require('gulp');
const minifycss = require('gulp-minify-css');

gulp.task('minify-css', function() {
  return gulp.src("css/*.css")
    .pipe(minifycss())
    .pipe(gulp.dest("dist/css/"));
});

まずは変数にインストールしたプラグインを登録! "minify-css"というのがタスク名。srcが対象のファイル。

ここでnpm run gulpを実行すると "dist"というディレクトリが作成され、その中にminifyされたcssファイルが出力される。 gulp.dest("dist/css/")」この部分。dest("保存先フォルダ")となっています。 pipe() 1つ一つの処理をつなげることができて何個でもつなげることができる!! これでminifyができた!!

便利なことと実際に困ったこと

複数のものをコピーするとき

複数ディレクトリの構造を維持してコピーするときは以下のようになる。

var gulp = require( 'gulp' );
 
gulp.task( 'copy', function() {
    gulp.src( 'src/*.html'  ).pipe( gulp.dest( 'dest'     ) );
    gulp.src( 'src/css/**'  ).pipe( gulp.dest( 'dest/css' ) );
    gulp.src( 'src/js/*.js' ).pipe( gulp.dest( 'dest/js'  ) );
} );

これだとgulp.destが冗長。gulp.srcは配列で複数指定可能でgulp.destは単一。

var gulp = require( 'gulp' );
 
gulp.task( 'copy', function() {
    return gulp.src(
        [ 'src/*.html', 'src/css/**', 'src/js/*.js' ],
        { base: 'src' }
    )
    .pipe( gulp.dest( 'dest' ) );
} );

baseを使いベースとしたいディレクトリを指定するとgulp.dest上で構成を再現。srcでのディレクトリ構造を維持してくれる。便利だ。 こいつは実装していて、srcに複数のものを入れるのどーやるんだろーって迷った

watch機能

watch機能で使用するのがwatch()で、「監視するファイル」に変更があった場合に設定された「処理」が実行される!

gulp.watch('監視するファイル', 処理)

と記述する。

javascriptのタスクを'js', CSSのタスクを'css'などとまとめておき

gulp.watch("./*.css`, gulp.task('css')");
gulp.watch("./*.ts`, gulp.task('js')");

をgulpfile.jsに記述しておくと cssやtypescriptなどに変更があったときに、自動でそれに関するタスクを行ってくれる。 こいつも便利なので、導入しておきたいですね。

【jQuery】スライダープラグインslickを使ってみた

slickとは

jQueryスライダープラグインでNo1の評価を得ているプラグイン。 レスポンシブ対応, マウスでスライドが可能, 無限ループなど様々なオプションが用意されている。

How To

導入

公式サイトからファイルをダウンロード。

f:id:shorugby14:20190612082316p:plain
slick公式ページ
jsDelivrCDNでホストされているので、今回はこいつを利用。 以下のファイルを読み込むことで利用可能になる。

  • slick-theme.css
  • slick.css
  • slick.min.js
<link href="js/slick-theme.css" rel="stylesheet" type="text/css">
<link href="js/slick.css" rel="stylesheet" type="text/css">
<script src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
<script type="text/javascript" src="js/slick.min.js"></script>

また今回の開発ではTypescriptを使用しているので、型定義ファイル(d.tsファイル)が必要になる。

使い方
<ul class="slider">
    <div><img src="images/01.jpg" alt="image01"></div>
    <div><img src="images/02.jpg" alt="image02"></div>
    <div><img src="images/03.jpg" alt="image03"></div>
    <div><img src="images/04.jpg" alt="image04"></div>
    <div><img src="images/05.jpg" alt="image05"></div>
    <div><img src="images/06.jpg" alt="image06"></div>
</ul>

sliderクラスに写真を設定し

$('.slider').slick();

この 1行だけで基本的なスライダーは完成!!

f:id:shorugby14:20190612082839p:plain
基本的なスライダー

オプション

slickには様々なオプションが用意されていている。 オプションは以下のように記述する。

$('.slider').slick() {
    OptionName: Value
}

こいつが今回、使用したオプション。

オプション 概要 初期値
autoplay 自動再生するかどうか true
prevArrow 左の矢印ボタンのHTMLをカスタマイズ <button type=”button” class=”slick-prev”>Previous</button>
nextArrow 右の矢印ボタンのHTMLをカスタマイズ <button type=”button” class=”slick-next”>Next</button>
dots ドットインジケーターを表示するか false
infinite スライドのループを有効にするか true
initialSlide スライドの開始番号 0

困ったこと

ページをロードした際に一瞬画像が縦並びになってしまう

よし!できた!と思っていざ表示すると、少し時間が経つとちゃんとスライダーになるけど、一瞬画像が縦並びになってしまう。。。

課題はslick用のCSSが適用されるタイミングにあった!! HTMLはシンプルなこのような記述だが

<ul class="slider">
    <div><img src="images/01.jpg" alt="image01"></div>
    <div><img src="images/02.jpg" alt="image02"></div>
    <div><img src="images/03.jpg" alt="image03"></div>
</ul>

実際に出力されるHTMLは、js側の

$('.slider').slick();

の実行によって、新しい要素やCSSが割り当てられる。

<div class="slider slick-initialized slick-slider">
    <div class="slick-list draggable">
        <div class="slick-track" style="opacity: 1; width: 3000px; transform: translate3d(-2000px, 0px, 0px); transition: transform 800ms ease;">
            <div class="slick-slide" data-slick-index="0" aria-hidden="true" tabindex="-1" style="width: 1000px;">
                <img src="images/01.jpg" alt="image01" alt="slide1">
            </div>
            <div class="slick-slide" data-slick-index="1" aria-hidden="true" tabindex="0" style="width: 1000px;">
                <img src="images/02.jpg" alt="image02" alt="slide2">
            </div>
            <div class="slick-slide slick-current slick-active" data-slick-index="2" aria-hidden="false" tabindex="-1" style="width: 1000px;">
                <img src="images/03.jpg" alt="image03" alt="slide3"></div></div></div>
            </div>
以下省略

つまり、jsの実行を待たないとclassが付与されずCSSが適用されないので縦並びになってしまう!! これを解決するために、CSSを使って

  1. 最初はスライダーを非表示にする
  2. jsの実行が終わったら表示する

という方法で解決した!

.slider {
    display: none;
}
.slider.slick-initialized {
    display: block;
}

実際にjsにより新しい要素やCSSが割り当てられら出力された"skick-intialized"に注目した。

<div class="slider slick-initialized slick-slider">

こいつはスライダーが初期化した時点で付与されるclass。 slider slick-intializedが一緒に付与されないと、表示しないという方法で解決した!