Wiz テックブログ

Wizは、最新のIoTやICTサービスをお客様に届ける「ITの総合商社」です。

PHP(サーバ)上からWebSocketにアクセスする

https://koenig-media.raywenderlich.com/uploads/2020/08/Screenshot_2020-08-10_at_15.08.19.png

こんにちは、バックエンドエンジニアの米山です。

前回、WebSocketの導入・構築について書きました。

その中で、

onMessage() : クライアントのsend()時に発火するイベント。クライアントにメッセージを返すところまでここで実装する。

と書きました。

これで気づいた方がいたかもしれませんが、onMessage()はクライアントからの送信で発火するイベントであり、サーバから発火できるものではない、ということです。

「えー矛盾してるじゃん!?WebSocketはお互い任意のタイミングでやりとりできるんじゃないの?」

という声が聞こえて来そうです。

この辺りは私もまだ学習中の身でして、Google先生曰く「redisを使おう!」とか「ブロードキャストイベントが〜」

などのご教示を頂くことが多いのですが、私は「1クライアントとしてサーバ上でWebSocket接続する」という道を選択しました。

前回の記事の通りに構築すると、PHP(apache)が稼働しているポート(80)とは別にWebSocketサーバを立ててListenすることになります(8282)

ですので、PHPから8282ポートに向けて接続してやろう、という考え方です。

WebSocketクライアントソフトのインストール

方向性を決めたところで色々探していたら、先輩からこちらを紹介いただきました。

Textalk
https://github.com/Textalk/websocket-php

composer textalk/websocket

でインストール可能です。

PHPでWebSocket接続!

GitHubの例にあるように

$client = new WebSocket\Client("ws://localhost:8282/");
$client->text("Hello WebSocket.org!");
echo $client->receive();
$client->close();

WebSocketクラスをnewするタイミングでWebSocketのURLを渡してあげます。

前回構築した環境では、PHPを動かす環境とは別にサーバを立ててますので「ws://localhost:8282」とします。

将来的に、WebSocketサーバを独立して立てる場合のことを考えても、PHPからクライアント接続できることはメリットだと考えます。

おわりに

いかがだったでしょうか?

PHP(サーバ)を1クライアントとしてWebSocket接続する方法を紹介しました。

他に追加のミドルウェア(redisやfirebase等)を入れずに、シンプルな考え方で接続できるので、私はスッキリしました。

今後時間があれば、これらのミドルウェアの知見を伸ばしつつWebSocketを構成してみたいですね。


今回はここまでです。ありがとうございました。


Wizではエンジニアを募集しております。

興味のある方、ぜひご覧下さい。

careers.012grp.co.jp

LaravelでWebSocket(Ratchet)を使ってみた

https://image.slidesharecdn.com/asyncphpdrupalcampla-140908080505-phpapp02/95/asynchronous-php-and-realtime-messaging-39-638.jpg?cb=1410262331

こんにちは。バックエンドエンジニアの米山です。

今回開発案件で、WebSocketを使ったシステム開発に携わることになったので、導入時のメモや困ったことetc...を書いていこうと思います。

まず、WebSocketとは?

Socketを使った技術は、古くからJavaなどの世界で存在していましたが、WebSocketはこれをインターネット上で可能にしたものです。

【従来のWeb通信】

https://create-it-myself.com/wp-content/uploads/study-websoket-spec-image1-768x536.png

従来のWeb通信は「1回のリクエスト」に「1回のレスポンス」で処理を行なっていました。

キャッチボールをイメージしてもらえたら良いと思います。

【WebSocketによる通信】

https://create-it-myself.com/wp-content/uploads/study-websoket-spec-image7-768x535.png

これがWebSocketになると「双方向通信」となり、ソケットが開いている間は任意のタイミングでクライアント<-->サーバ間通信が行えます。

WebSocketを導入するために

今回実施した開発案件では、以下の環境・条件で構成を考えました。

  • サーバ側の開発言語はPHP(Laravel)であること
  • フロントエンド側にサーバ側の言語仕様を押し付けないこと
    • PHP(Laravel)の設計思想や概念に依存するコードをフロント側に強要しない。フロントはフロントで技術選定できる環境にする。
  • なるべく、サードパーティ製のツール(firebase等)を使わず、リアルタイム性を実現できること

以上のことから、今回は「Ratchet」というライブラリを選択しました。

LaravelでWebSocketを構築しようとすると、必ずと言っていいほど「Laravel-Echo」が検索ヒットします。

しかし上記に挙げた条件の通り、フロントエンドはフロントエンドで技術選定を行いコーディングするので、依存しないRatchetを選びました。

早速Ratchetを導入!

では、LaravelプロジェクトにRatchetを導入してみましょう。

LaravelではComposerを使ったライブラリ管理が可能ですが、Ratchetの公式ページに導入方法が記載されています。

http://socketo.me/docs

ComposerでRatchetをインストール

公式ページに書いている通り、composer.jsonを書き換えても良いですし

composer require cboden/ratchet

でも良いです。(執筆時点でのVer.はv0.4.3を使用しています)

WebSocketサーバを作る

Webサーバ内で別のサーバが動くイメージで実装します。

Webサーバ(apache)内でアプリサーバ(tomcat)が動く感覚に近いです。

Java使いはイメージしやすいかも。(厳密には異なる概念です。あくまでイメージね)

require 'vendor/autoload.php';


$app = require 'bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();

$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            new Chat()
        )
    ),
    8282
);


$server->run();

ここでは、Laravelのメソッドや環境変数等を使うために「require 'vendor/autoload.php'」したり色々やっています。

これを自作artisanコマンド等で、自動実行できるようにするとこの記述は不要になります。

Laravel上で動くようになるからですね。

コードを見ておや?と思った方がいるかもしれません。

WebSocketはHTTP技術を拡張したものなので、HttpServerクラスでListenを行います。

このHttpServerクラスはRatchetで作られたものですが、RequestオブジェクトはPSR-7 HTTP message interfacesで拾うことができます。

従って、その引数に渡しているWsServerインスタンスやChatインスタンスも同様です。

Chatクラスの中身は、公式ページにも記載がある通りMessageComponentInterfaceを実装する形にします。

これを実装することでWebSocketの各イベントが使用可能になります。

今回、私が実装したのは以下の4つです。

  • onOpen() : クライアントから初めてWebSocketに接続された時に発火するイベント
  • onMessage() : クライアントのsend()時に発火するイベント。クライアントにメッセージを返すところまでここで実装する。
  • onClose() : クライアントから切断(close()時、もしくはブラウザの×ボタン押した時)に発火するイベント
  • onError() : WebSocket通信中に何らかのエラーが発生した時に発火するイベント

まとめ

LaravelでRatchetを扱う時は

  • Composerでライブラリをインストール
  • ListenするWebSocketサーバ(クラス)を作る
  • 各イベントを理解する

をわかっていれば実装できると思います。

まだまだ資料は少なめですが、Ratchet関連の解説記事もそこそこあるので、調べたらいくつか出てきます。

今回はここまでです。良きSocketライフを!(笑)


Wizではエンジニアを募集しております。

興味のある方、ぜひご覧下さい。

careers.012grp.co.jp

Webアクセシビリティ検証フレームワーク「acot」を導入してみた。

acotのロゴ画像

はじめまして。フロントエンドエンジニアの内田です。

最近福岡では日中30℃を超える気温でぐったりです。アイスがとろけております。

さて突然ですが、この記事をご覧になっている皆様はアクセシビリティについて悩んだ事はありますでしょうか?

Wizでは残念な事にWebアクセシビリティに対して、まだまだ高水準な品質を維持出来ていないのが現状です。

アクセシビリティとは

どのような環境にいても人々が平等にアクセス可能で、全てのコンテンツや機能が利用できる状態の指標です。

また、似た言葉としてユーザビリティがあります。

ユーザビリティとは

ユーザビリティは、ユーザーにとっての使いやすさを表す概念です。

ここで言う使いやすさとは、ユーザーがストレスを感じない操作性、わかりやすい導線設計を施し、成約に至るまでに必要な労力の少なさなどを指します。


今回はアクセシビリティについてお話させていただきます。


Webアクセシビリティにおいて意識する必要のある代表的なハンディキャップ例としては下記が挙げられます。

全盲

全盲の方は画面上の文字を音声で読み上げるスクリーンリーダーや点字で表示する点字ディスプレイなどを利用して読み取っていますので画像とテキストの位置関係やどんな画像が表示されているのかが明確に把握できるような工夫をしなければいけません。

■ロービジョン

視力が低下している方や視野が狭くなっている場合(視野狭窄)、視野の真ん中が見えない場合(中心暗点)などの弱視の方を指します。

Webページを利用する際、ロービジョンのユーザーは次のような使い方をしている為、サイズ感やコントラストなどの視覚的表現、視覚以外の方法で情報取得ができる対応が必要になります。

  • 画面拡大ソフトやOSに標準で搭載されている機能を用いて画面表示を拡大する
  • 画面の色を反転する
  • OSやブラウザの設定によって、文字サイズを変更する
■色覚多様性

色の見え方は人によって異なり、その割合は日本人の男性で5%、女性で0.2%と言われています。

よく言われる例だと正常と異常の状態を赤と緑の色だけで表現しているUI等は区別が難しくなります。対応方法としては下記のような配色を目指すべきでしょう。

  • 赤と緑は見えづらいので青やオレンジを使う
  • 色に頼らない、色数を増やさない
  • コントラストを強くしすぎない
■上肢障害

手や腕に障害がある場合はマウスやトラックパッドなどが利用困難でありホバーやドラッグ&ドロップが難しかったりするのでトラックボールを利用するパターンが多いようです。 なので、クリックポイントを近くしすぎるとトラックボールのほんの僅かな動きで通り過ぎてしまったりするので、リンクやアイコンなどのクリックできる位置をある程度余白をつけて配置する等の配慮が必要です。

聴覚障害

近年では動画をコンテンツに含んでいる場合がありますが、その動画内で情報説明したりする場合には手話通訳をつけたり、字幕情報を付与したりして併用することが望ましいとされています。

例えば、動画の中で問い合わせ先などを示す場合には、問い合わせ電話番号などを音声だけで伝えず、視覚、聴覚の両方で具体的な情報を提供する必要があります。

また、最近では警告音の見える化などの対応もAppleでは配慮されています。 www.apple.com





ですが、これら全てを意識してエンジニアが対応していくのは困難です。

そこで、W3Cが標準化しているWCAGガイドラインを参照して全世界のエンジニアはこのガイドラインに準じて対応していく事になっているのですが、 このWCAGは正直何書いてるのか把握しづらく、「で?どうしたらいいの?」といった気持ちになる上、達成基準が設けられておりA (最低レベル)、AA、AAA (最高レベル)という基準があり、正直AAAに対応するにはかなりきびしい道のりです...

waic.jp

ではどうするか?

これらの問題を対応しなければいけない事はわかってはいるのですが、全ての項目を一つ一つ把握しつつDevToolsのLighthouseを実行して目視でチェックしていくのは非効率で地獄です。

そこで、弊社では一部メディアにてWebアクセシビリティー検証フレームワークであるacot-a11y/acotを導入してみました。

github.com

導入手順

acot 自体は puppeteer ではなく puppeteer-core へ依存するため、別途インストールが必要な構成となっています。

$ npm i --save-dev @acot/cli puppeteer

インストールが完了したら、以下のコマンドを実行する事で設定ファイルの構築を行うことができます。

$ npx acot init

すると下記のようにコンソール内にて対話形式で設定を進めていくと、acot.config.jsという設定ファイルが生成されます。カンタン!!!

✔ What is the origin for the audit target? · http://localhost:3000
✔ What kind of server do you want to connect to? · command
✔ What is the command to start the server? · npm run dev
✔ Do you want to use the config recommended by acot? · no / yes
✔ Which runner do you want to use? · default
✔ Which format do you prefer for the config file? · javascript
✔ Which is the npm client used to install the dependent packages? · npm

acot.config.js

module.exports = {
  extends: ['@acot'],
  connection: {
    command: 'npm run dev',
  },
  origin: 'http://localhost:3000',
  paths: ['/'],
};

では早速実行してみましょう!!

$ npx acot run

すると下記のようなサマリーが表示されました。

acotの結果キャプチャ

エラーの数が絶望的ですね。まぁこれは開発途中のものなのでご愛嬌。

さくっとErrorをPassできそうなものとしては@acot/wcag/img-has-nameあたりですかね。

ログを追うと

✖  img element or img role MUST has name.  @acot/wcag/img-has-name
   ├─ <img src="/_next/image?url=%2Fimg%xxxxxxxxxx.png&w=1920&q=75" decoding="async" style="visibility: visible;…
   ├─ at ".contentsBox--keyVisual__img > div > img"
   └─ see https://www.w3.org/WAI/WCAG21/Understanding/non-text-content.html

と表示されており、おそらく画像に対してalt属性による代替テキストの設置、またはロールを付与し忘れるといった基本的な箇所が抜け落ちていたようです。

尚、このときのLighthouseによるアクセシビリティの数値としては87でした。

f:id:romeoromen:20210629014150p:plain

では対象箇所をさくっと修正して再度実行してみます。

f:id:romeoromen:20210629021151p:plain

お!@acot/wcag/img-has-nameが見事Passになりました!🙌🏼

ちなみにLighthouseで再度計測してみたところ指し示した値としては94!!たったこれだけで爆上がり!!

f:id:romeoromen:20210629022056p:plain

今回は単体ページでのチェックとなりましたが、acotのrunnerにsitemapのパスを指定することで複数ページに渡ってチェックしてくれる事も可能です。 ですが、おそらく数百のページを対象としたメディアサイトの場合は相当処理が重くなるかと思いますので要注意です。

module.exports = {
  runner: {
    uses: '@acot/sitemap',
    with: {
      source: 'http://localhost:3000/sitemap.xml',
    },
  },
};

現段階の実行タイミングとしてはプレコミット時等のアクションを検知したオート実行ではなく任意のタイミングで実行する運用方法で対応しています。

まとめ

まだまだアクセシビリティについてはやらなければいけない事が山積みの状況ではありますがこのように一歩一歩着実にPassしていく事で本当のWebの世界というものが広がっていくような気がしてきます。

全世界のなるべく多くのユーザーに正しくわかりやすい情報を伝えていく事が自身の喜びでありWizの目標の1つです。

最後に


Wizではエンジニアとして一緒に働く仲間を絶賛募集しております。

ご興味のある方、是非ご覧下さい..!!

careers.012grp.co.jp

【エンジニア社内LT会】第6回

f:id:nakamoto03:20210628111924p:plain

第6回LT会レポ

今回のLT会の内容は

発表者: 3名

制限時間: 自由

テーマ: 自由

コメントツール:CommentScreen

で行いました。

それでは1つずつ発表を紹介していきます。

技術選定をしてみたという話

1人目の方には「技術選定をしてみたという話」という内容を発表していただきました!

新しいプロジェクトを始めるにあたって、フロントエンドの技術選定を行いその中で学んだことを発表していただきました。

実践した技術選定フローにより、今回行うプロジェクトにあった技術選定、所属しているチームにあった技術選定を行えたようです。

今回行った技術選定フローもスライドの方に記載されていますのでぜひ一読していただけますと幸いです。

React v18 alpha 発表

2人目の方には「React v18 alpha 発表」について発表していただきました!

いくつか機能があったのですが、以下の3つの項目を紹介していただきました。

  • ConcurrentRendering

  • Automatic Batching

  • StrictModeでのuseEffect

EMなった時に感じたしょぼい点

3人目の方には「EMなった時に感じたしょぼい点」について発表していただきました!

EM・・・エンジニアリングマネージャー

以下のしょぼいと感じた点とその点に対しての対応について発表していただきました。

  • 文章がしょぼい

  • スライドがしょぼい

  • 見積もりがしょぼい

  • 自分がやりたくなるのがしょぼい

すべて「うっ。。」となるような内容でした。発表を聞いた方は意識しなきゃと感じたのではないでしょうか。

今までのLT会はこちら~

tech.012grp.co.jp

最後に~

第6回はこのような内容でした。

第10回が近づいてきましたね。何か盛大にやりたいところです。

Wizではエンジニアを募集中です。

興味のある方は是非覗いてみてください!↓

careers.012grp.co.jp

 

様々なコミュニケーションについて〜営業部との違い〜

f:id:daigo2895:20210618143719p:plain はじめまして!フロントエンドの久保です。

今回は【営業部 → エンジニア】へジョブチェンジした話を実体験に基づいて書いていきたいと思います。

ジョブチェンジの経緯

単刀直入にいうと新型コロナウィルスです。
今、どういう事??と思いましたよね。笑

正確には在宅ワークになり自分の時間が増えたとき、ふと自分の人生設計について考え直したのがキッカケとなります。

営業をバリバリやっていた自分に「本当は何がやりたいの?」と聞きました。
すると「WEBサイトを作りたい」と返ってきました。

はい。すこし誇張しました。

異動して感じたすごいこと(本題)

ズバリ、『コミュニケーション』です!!!

どういうことか、大きく3つのすごいをまとめました。

心理的安全性の高さがすごい

② アウトプット力がすごい

③ 情報や技術の共有力がすごい

1つ1つ営業部との違いと共に解説させてください。

心理的安全性の高さがすごい

営業部時代は、
基本的に担当商材が決まっていて、それを日々販売するという毎日でした。 大きく商材が変わらないのと、大切なお客様を相手にしていますので、あまり挑戦的な試みというのが出来ませんでした。
また、個人的にどうしても役職が上の方には頻繁に質問をしづらく、同僚内で解決するループもありました。
今思うとまだまだ関係値(心理的安全性)が出来ていなかったのかもしれません。


対してTech事業部では、
異動した初日に上司から『上司と部下はリーダーとメンバーという風に置き換えてほしい』と言っていただきました。
違いを体感で説明すると、「上下関係」から「先輩後輩」になったみたいな感じです。(感じてください。)
※もちろん営業部が上下関係厳しいとかいう話ではないですよ!

組織内では雑談の時間もかなり大切だという共通認識があり、そこから生まれるものの価値を重視しています。
また、定期的に交流する時間も設けており、趣味や好きなことを通して色々な人と距離が縮まります! 僕もおすすめの椅子ありますか?とかプロテインはこれ飲んでますとか話しかけてます笑

現在oViceというバーチャルオフィスで働いているのですが、驚くことに出社していたときよりもコミュニケーションが密接になりました。
どんな意見も尊重して「いいねそれやってみよう!」という文化が当たり前のようにそこにあるので、新人の僕でもガンガン意見や質問が出来る安心感がありとてもいい環境だと思いました。
馴れ合いではなく、「互いにリスペクトしている仲の良さ」というのがポイントです。

② アウトプット力がすごい

営業部時代に何をアウトプットしていたか考えましたが、
びっくりすることに答えが出てきませんでした・・・。(サボってはいません笑)

どちらかといえば人それぞれのインプットをし、自分なりの成功体験を元に感覚で受注を取っていた気がします。
お客様(外部)へ情報のアウトプットをしていたということですね!


対してTech事業部では、
定期的に組織内(内部)でアウトプットタイムというものがあります。
そこでは技術的な事、マインド的な事、とにかく吸収したことを他者へ説明するというものです。

アウトプットすることで本質的に理解していない部分などが自然と見えてきます。
更に定期的に行うことによってアウトプットが習慣化されます。
結果、自主的にアウトプットをし合う文化が出来上がっています。

③ 情報や技術の共有力がすごい

これが1番文化の違いを感じ、衝撃を覚えました。
営業はある種格闘技で、もちろん全てではないですが数字に左右される毎日でした。
プレイヤーごとに自分なりの型を持っており、弱肉強食な世界でもあります。
自らアウトプットするというよりは、強者の分析をし真似をする文化のほうがあります。
この力もすごく重要なんですけどね!


Tech事業部では
面白そうな記事があれば都度slackで共有し、情報共有やアウトプットをすれば共有アプリに蓄積する。
さらには過去の話題でも簡単に検索出来るように種類分けされているので、どのタイミングで入ってきても同じ情報を取得出来ます。
これは営業部にはなかった衝撃的な文化であり、すごくありがたいものでした。

営業部時代の自分が気づけなかった、どこかもどかしい感覚はここに答えがありました!

最後に

いかがでしたでしょうか!
ご覧の通りフロントエンドチームでは互いをリスペクトし、助け合う文化が強く存在しています。
この記事を書いて、営業部とエンジニアの両方の目線を持つ自分だから出来ることが見えた気がします。
それは営業部とエンジニアを繋ぎ、お互いの文化の良いところを組織に反映させていくといった「架け橋」になっていくことです。
まだまだエンジニアとしては未熟ですが、この素晴らしい文化の中で成長し、Wiz全体を前進させていけるように頑張っていきます!

そして…

Wizではエンジニアを募集しております。
興味のある方、ぜひご覧下さい!

careers.012grp.co.jp

【新卒】インターン研修を受けて -「失敗」の捉え方-

f:id:miyabi-s0522:20210618101549j:plain

はじめまして!21新卒フロントエンドエンジニアの島田です。
今回は入社前に行っていたインターン研修について書いていきたいと思います。

インターン研修を受けて

私は今年の1月中旬から3月末までインターン研修を受けました。

「研修」と聞くと

  • 「勉強ばっかりで大変そう…」

  • 「上司や先輩から厳しく指導されるのでは…!?」

というような印象を受ける方がいらっしゃるかもしれません。(実際、私がそうでした。) 

ですが!!研修を受けている時や終わった時には、「参加して本当に良かった」と強く思えるものでした!

研修に対してマイナスなイメージを持っていた私が何故このような結果に至ったのか、理由と共にお話ししていきます( ´∀`)

理由その1 入社前までの不安を解消できた

入社前の私には、「エンジニアとして働けるのが楽しみ!」とわくわくする一方で、

  • 「会社の制度やルールはどうなっているんだろう?」

  • 「4月から会社のことと業務をいっぺんに覚えるのは大変そう…」

  • 「春からどんな人達と働くのだろうか?」 

というように、疑問や不安に思う気持ちがありました。

しかし、Wizのフロントエンドのインターン研修にはこのようなメリットがあります。

  • 12月〜3月までの間で、希望をすれば参加できる
    → 私の場合、大学の卒業制作が終わった1月中旬のタイミングで始めました。

  • 技術的な内容はもちろん、会社や組織、社会人のマナーについてもしっかり学習できるカリキュラム
    → 一足早く企業理解を深めてエンジニアとしてスタートすることができます!

  • 実際に現場で活躍している先輩方から直接教えていただく
    → 一緒に働くメンバーもここで知ることができます!

などなど…入社前に抱えていた不安を打ち消すような内容です。
インターン研修を通して、かなり早い時期から会社のことや業務について理解を深められたため、参加して本当に良かったと感じます☀️

理由その2 4月までに技術的なスキルを取得できた

現在エンジニアとして活動している私ですが、実は情報系出身ではありません。
大学でグラフィック系のデザインを勉強し、3年生から外部のスクールでWebデザインとHTML/CSS/JavaScriptを学んできたため、コーディング歴は比較的浅めです。

入社当時は、神経質な性格もあって
「いきなりプロ集団に囲まれてついていけるだろうか…!」
という不安がありました。

しかし、研修ではWebやIT業界の基礎的なところから応用まで、優しく幅広く教えていただきました。
オンライン上での研修でしたが、常に誰かがそばにいてくださったため質問しやすく、安心感がありました。

初めはCSS設計の「し」の字も理解できなかった私でしたが、3ヶ月半研修を受けた結果、4月からOJTでFLOCSSやBEMを用いてLPを作成できるまでになりました!

理由その3  「失敗」に対する気持ちが変わった

以前の私には

「失敗」=「悪いこと」だから極力失敗をしてはいけない

という認識がありました。
なので、研修中にわからないことや壁に当たると

「勉強していたのになんでできないんだろう…解決できないのしんどい…。」

と考え、解決できても

「やっとできた。でもまた問題が出てきたら(失敗したら)やだなぁ。」

と後ろ向きになり、コードを書くのが苦しくなってしまう時がありました。
そんな時、先輩方から

  • 「失敗は悪いことじゃない。失敗することは良いことだから、どんどん失敗していこう!!」

  • 「新人はできなくて当たり前。必要以上に気にしないこと!!」

という声をかけられました。
「失敗」=「悪いこと」と捉えていた私はとてもびっくりです。

それ以来、コーディングをする時はその言葉を思い出しながら行いました。
すると、次第に失敗しても前向きの状態をキープできるようになり、問題発生時も

「あれっ?上手くいかないな。よし、検索して調べてみよう!」

と行動し、解決できると

「やったね自力で解決できたぞ!この調子で進めて行こう!」

とやる気が更に湧いて、コーディングがどんどん楽しくなっていきました。
実務に携わる前に「失敗」=「良いこと」と学べて良かったです。

最後に

インターン研修を通して、会社や技術的な内容だけではなく、「失敗」に対する捉え方も学びました。
今後も失敗を恐れず、沢山挑戦していきたいと思います!!

そして…

Wizではエンジニアを募集しております。
興味のある方、ぜひご覧下さい!

careers.012grp.co.jp

CSS設計について

こんにちは!

今年新卒で入社したフロントエンドエンジニアの益田です。

研修の中で特に勉強したCSS設計についてお話させていただきます。

CSS設計とは

まず、CSS設計のポイントとして以下の4つが挙げられます。

  1. 予測しやすい
  2. 再利用しやすい
  3. 保守しやすい
  4. 拡張しやすい

つまり、後々自分や他人が見ても読みやすく

改修しやすいCSSを書きましょうと言うことです。

CSS設計が必要な理由

CSS設計が必要な理由としては、以下の3つが挙げられます。

  1. バグを抑える

  2. サイトの寿命を延ばす

  3. サイトの改善スピードを速める

HTMLでのマークアップCSSでのスタイリングは人によって書き方が違い、様々な書き方が出来る為、他人が変更しようとすると難しい部分もあると思います。そう言った部分を解消して、バグを抑えることや変更しやすいコードを書くことがCSS設計の目的です。

CSS設計手法 4つ

次に、主なCSS設計手法を紹介していきます。

OOCSS(Object-Oriented CSS

オブジェクト指向CSSと言って以下の2つの原則に基づいた設計手法の概念です。

1.構造と見た目の分離

2.コンテナとコンテンツの分離

1. 構造と見た目の分離

・まずは、構造と見た目の分離です。簡単に説明すると位置や文字の大きさなどの構造と、色や見た目に関する部分を分けて書こうと言うことです。

以下のコードでは、構造と見た目を分離していない為、ラベルの要素と背景の色が一つのクラス名に書かれています。

.label-yellow {
    display: inline-block;
    padding: 5px 20px;
    background-color: yellow;
}

次に、OOCSSを意識したコードの書き方がこちらです。

.label {
    display: inline-block;
    padding: 5px 20px;
}

.back-primary {
    background-color: yellow;
}

ラベルはラベルの要素だけを持ち、背景は別クラスで指定することでラベルが複数ある場合でも追加がしやすく、ブルーのラベルを追加したとしてもCSSの記述は背景色を追加するプロパティを書くだけで完了します。

2.コンテナとコンテンツの分離

・パーツ(モジュール)の再利用性を高める為の考え方で、ある親要素に依存せず、親要素(コンテナ)から子要素(コンテンツ)を取り出した場合でもきちんと使えるCSSを書こうと言うことです。

下のHTMLに対して良いCSSと悪いCSSを書いていきます。

<div class="parent">
    <p class="child">
        これはテキストです。
    </p>
</div>

まずは、ダメな例です。

.child {
    margin-top: 10px;
    margin-left: 20px;
    font-size: 20px;
    font-weight: bold;
}

クラスchildのCSSに余白を付けている為、divからpを取り出した際に余計な余白が付いたままになります。このままではコンテナとコンテンツの分離は出来ていません。

次に設計を意識したCSSの書き方がこちらです。

.parent {
    padding-top: 10px;
    padding-left: 20px;
}

.child {
    font-size: 20px;
    font-weight: bold;
}

この書き方だと、コンテナとコンテンツの分離ができparentに新しくコンテンツを追加したとしても余白が保たれ変更しやすいコードになっています。

分かりにくい方はcodepenでもまとめてましたので見て頂けると良いと思います。

悪い例

See the Pen コンテナとコンテンツの分離(悪い例) by daisukemasuda06 (@daisukemasuda06) on CodePen.

font-sizeやfont-weghtを持ったまま別コンテナで使用したい場合marginが付く為、その変更が必要になりCSSの記述量が増える。

良い例

See the Pen コンテナとコンテンツの分離(例) by daisukemasuda06 (@daisukemasuda06) on CodePen.

font-sizeやfont-weghtを持ったまま別コンテナで使用したい場合marginが付かない為、変更箇所が少なく別コンテナでも使いやすい。

以上、ざっくりとOOCSSの考え方について紹介していきました。

CSS設計の概念的な部分で、この2つを理解してCSSを書いていくと破綻しにくく変更しやすいコードを書いていけると思います。

BEM(MindBEMding)

  • BEMは命名ルールが特徴的な設計手法です。

BEMでは、CSSのルールを以下の3種類にカテゴライズする設計手法です。

■Block
 モジュール、セクション等

■Element
 ブロック内の子要素

■Modifier
 色の違いや別パターンのモジュール

基本的な書き方

.Block
.Block__Element
.Block--Modifier
.Block__Element--Modifier

基本的な書き方の例(HTML)

<div class="parent">
    <p class="parent__child">
        これはテキストです。
    </p>
    <p class="parent__child--primary">
        これはテキストです。
    </p>
</div>

悪い書き方の例(HTML)

<div class="parent">
    <p class="parent__child">
        これはテキストです。
    </p>
</div>
<p class="parent__child--primary">
    これはテキストです。
</p>

BEMの書き方として、エレメントはブロックに紐づいて定義される為、ブロック内であれば繰り返し使用しても問題ありません。 ですが、上のコードを見てもらうと、悪い書き方の方はエレメントがブロックの外に出てしまっているので、BEMのルールから外れてしまっています。 BEMのルールに従って基本的な書き方をすると、CSSの影響範囲が予測しやすいので可読性が高く、モジュールごとに共通化して分けやすいと言うメリットがあります。また、モディファイアでパターンを分けられるので追加や変更も楽にできます。

デメリットとしては、ブロックの中の入れ子が多い場合にクラス名が長くなってしまいがちなので、一度ペーパーコーディングやブロック構成を考え直してから書いてみるとスッキリすると思います。

SMACSS

  • SMACSSは、CSSのルールを以下の5種類にカテゴライズした設計手法です。

■Base
 要素やサイト全体で指定するデフォルトのスタイル

■Layout
 サイトのページをエリアごとに分割

■Module
 再利用可能なパーツ

■State
 状態を示す

■Theme
 サイトのデザインテーマ

SMACSSの特徴として、ベースやレイアウトの部分まで決められる為、ボタンを再利用したい場合や背景を変えたい時などにクラス名を指定するだけでスタイルを指定できます。

また、レイアウトのクラスに接頭辞をつけることでコードの質が担保されます。

接頭辞の例

l : Layout(レイアウト)
md : Module(モジュール)
is : State(状態)

書き方の例

.l-Block__Element--Modifier

FLOCSS

・FLOCSSは、以下のように3つのレイヤーと3つの子レイヤーに分けており、OOCSSやSMACSSのいいとこ取りをした設計手法です。

■Foundation
 リセットCSS・base(サイト全体で統一したいもの)等

■Layout
 ヘッダー・フッター・コンテナー

■Object
 再利用できるパターンを持つモジュール

 ・Component
    ボタンなどページ全体で使いまわしたい小さなモジュール

 ・Project
    Componentを括る・そのページしか使わないモジュール

 ・Utility
    display:noneやちょっとした変更に使用

書き方の例

.c-button
.p-Block__Element

基本的にはFoundation・Layout・Objectの3つでサイトの構成を作ることができ、Objectをさらに3つの構成で分けることができ、LayoutだけでなくCompenentやProjectにも「c-」や「p-」の接頭辞をつけることができSMACSSよりさらに細かくルールを決めることができます。

色々あるけど何が良いの?

CSSの設計手法について4つ説明してきましたが、

結局何が良いのかと言うのはサイトの規模やチームで決まってきます。

■小規模向け

 - SMACSS(ルールが適度に緩い為)

■大規模向け

 - BEM, FLOCSS(ルールが堅牢な為)

どのCSS設計も一長一短の為、BEMとFLOCSSやBEMとSMACSSなど組み合わせて使うと良いと思います!

Wizのフロントエンドチームでは、何を使っているのか?

Wizのフロントエンドチームでは、FLOCSSとBEMを使っています。

以下のようにFLOCSSのFoundation, Layout, Object,のようにファイルごとに分割し、追加や変更がしやすいよう管理されています。

f:id:daisuke_john:20210615100949j:plain

命名規則はBEMに加えてFLOCSSの接頭辞を使っているので、予測しやすいコードになっています。プロジェクトによっては多少変わりますが、Wizでは主にこの書き方を採用しています。

f:id:daisuke_john:20210614160012j:plain

まとめ

今回は、CSS設計について紹介しました。

私自身入社前はCSSは少し触っていた程度で、コードの重複が起きたり、モジュールの共通化が出来ていなかったりしていました。しかし、研修でCSS設計について理解することで記述量も大幅に減り、以前より予測しやすく変更しやすいCSSが書けるようになりました。

今回の内容が、CSS設計について知らない方や破綻しにくいCSSを書きたいと言う人の参考になれば幸いです。

Wizではエンジニアを募集しております。

興味のある方、ぜひご覧下さい。

careers.012grp.co.jp