freeeアクセシビリティー・ガイドラインVer. 202104.0を公開しました

こんにちは、freeeのアクセシビリティーおじさん、中根です。

締切が延長されたおかげで、先日余裕を持って確定申告を終わらせることができました。確定申告は概ね独力でできるのですが、紙で交付される書類やアクセシビリティーが低いPDFで交付される書類から情報を転記するところだけは相変わらず人に頼らないと突破できず、毎年残念な気持ちになっています。でも確定申告が終わると気持ちも軽くなり、気温も高くなっていよいよ春が来るなあという感じになります。

さて、それでは今回の更新内容を紹介します。 そして最後にイベントのお知らせもあります。

axe改めaxe DevToolsのルールに関する情報を追加

まず、freeeでも活用していてガイドラインの参考情報でも取り上げているアクセシビリティーのチェック・ツールaxeがいつの間にかaxe DevToolsに改名されていました。ということで各所の表記やスクリーン・ショットを修正しました。 というのはある意味どうでも良い話で、ここからが重要です。

axe DevTools(以下axe)を使っていると、表示されたアクセシビリティーに関する指摘が具体的になにを意味しているのかがよく分からないことがしばしばあります。 特にaxeを使い始めて間もない場合などは、判断に迷うことが多いと思います。

そこで、axeの各ルールがWCAG 2.1のどの達成基準に対応しているのか、さらにその達成基準が対応しているfreeeのガイドラインはどれなのかということが分かるような情報を追加しました。

ただし、この情報はaxe-coreのソースに基づいて自動的に生成しているものです。 axeのソースを見ると、各ルールとWCAG 2.1の達成基準との対応は分かるようになっています。 そしてWCAG 2.1の達成基準とfreeeのガイドラインの対応についてはガイドラインにも掲載しているものを処理しやすい形式に加工したものを用意して処理しています。 これらの情報を基に、axeの各ルールと対応するWCAG 2.1の達成基準、その達成基準に対応するfreeeのガイドラインのリストを機械的に作製し並べているだけです。 ですから、提示されている情報が不完全な可能性があることに充分に注意してください。

チェック内容をまとめたスプレッドシートの公開

各ガイドラインを満たしているかどうかを確認するために示している「チェック内容」について、これまでも全項目を掲載したページがありました。

このページですべてのチェック内容を確認することは可能なのですが、実際にチェック作業を実施する場合には必ずしも使いやすい形式ではありません。

freeeでは、チェックを実施する際にはこの情報をまとめたGoogleスプレッドシートを使っています。 先頃、ひっそりとこのスプレッドシートを一般公開しました:

そして、今回の更新でガイドラインからもこのスプレッドシートへのリンクを掲載しました:

Google Drive上でこのスプレッドシートのコピーを作成してご利用ください。スプレッドシートの1枚目のシートに、簡単な使い方や更新履歴を記載していますので参考にしてください。

そして文末でご案内するイベントで、実際にどのようにチェックを行うのかも含めて、freeeでのアクセシビリティーの取り組みについて紹介しますので、こちらも参考にしてください。

その他の変更

これ以外にもチェック内容の見直しを行っています。詳しくはリリース・ノートでご確認ください。

また、このブログではお知らせしませんでしたが、Ver. 202103.0もリリースしています。

引き続きご意見などお待ちしています

今回の変更についても、それ以外の部分についても、ご意見やお気付きの点など、GitHubリポジトリーのIssuesやPull Requestsでお知らせください。

イベント開催のお知らせ

ということで、今回公開したチェックリストを使ったアクセシビリティー・チェックの実施方法なども含めて、freeeでのアクセシビリティーの取り組みについて紹介するイベントを開催します。

  • 日時:2021年4月9日(金)19:00~21:00
  • 会場:オンライン
  • 参加費:無料

以下のページからお申し込みください:

connpass.com

Webのダークモードを実現するには

こんにちは、freeeのUXチームでデザインシステム “Vibes” を作っている id:ymrl です。

ダークモード流行ってますよね。私は最初はしっくりこないなと思っていたんですが、食わず嫌いは良くないと思って試しているうちに、いつの間にかダークモードのほうが落ち着くようになってしまいました。

そしてそうなってくると、だんだん「自分たちの作っているWebサービスもダークモードに対応するべきなのか?」という気持ちになってきてしまい、最近はずっとダークモードのことを考えています。ということで今回はダークモードをやるべきなのか、実現する方法はどうなっているのか、UIデザインで気をつけるべき点何かというのを考える記事を書いてみます。

※「ダークモード」はApple製品で使われている呼び方で、Androidでは「ダークテーマ」と呼ばれていて、Windowsでは「ダーク○○」のような呼び方をしていなさそうです。この記事では「ダークモード」で表記を統一して呼ぶことにします

Webにダークモードは必要なのか

現時点では、ダークモードはWebサイトの必須の機能というわけではなさそうです。有名なWebアプリケーションではたとえばYouTubeやGitHubはダークモードに対応していて、使用しているOSの設定に準じるようにしたり、好みの配色を選べるようになっているようです。

GitHubのスクリーンショット。Themesという項目名で Default to system / Default light / Default dark から選択することができる
GitHubの設定UI
設定方法は Managing your theme settingsで紹介されている

Web上でOSの設定に準じてスタイルを切り替えるのは、CSSのメディアクエリで prefers-color-scheme という特性を使うことで実現できるようです。つまりWebでは「ダークモードで使用しているかどうか」は「ユーザーの好み」として扱っているということなんですね。

developer.mozilla.org

YouTubeやGitHubのような毎日使うサービスでは、ユーザーの好みに寄り添うことができるよう、サービス側で配色を切り替えたり、ユーザーがどちらを使うか設定できるのは好ましそうです。会計freeeのようなビジネス向けSaaSでも同じことが言えるでしょう。

おそらく現在は、ダークモードを使用している多くのユーザーは、WebブラウザではダークでないWebページが表示されることに違和感を持っていません。そのためWebでのみ展開するアプリケーションであれば必ずしもダークモードへの対応を急ぐ必要はなさそうです。しかし、モバイルアプリもリリースしてそちらはダークモードに対応していたりすると、Webとアプリで表示の一貫性が崩れてしまったり、一部画面をwebviewで表示しているとその画面だけ明るい配色になってしまったりします。ネイティブアプリとの連続性を重視すると、ダークモードへの対応を考える必然性が生まれてきそうです。

Webでダークモードを実現する

上で述べたとおり、CSSのメディアクエリで prefers-color-scheme を使用することで、OSでの設定にあわせてダークモード/ライトモードを切り替えて表示することができます。Webアプリケーションで使用するには、各所の配色をCSSのカスタムプロパティ(変数)として定義しておき、メディアクエリによって切り替えることによって実現するのがシンプルそうです。

以下は雑に書いたダークモードを実現するコードの例で、OSの設定に従ってダークモードとライトモードを切り替えられるようになっています。

:root {
    --textColor: #333;
    --backgroundColor: #fff;
    --linkColor: #4575B4;
}
@media (prefers-color-scheme: dark) {
    :root {
        --textColor: #fff;
        --backgroundColor: #222;
        --linkColor: #6398DE;
    }
}
body {
    color: var(--textColor);
    background-color: var(--backgroundColor);
    margin: 1rem;
    padding: 0;
}
a {
    color: var(--linkColor);
}

上記のCSSをあてたページをダークモードとライトモードを切り替えながら見ているGIFアニメ

CSSのカスタムプロパティは残念ながらInternet Explorerでは使用できず、Internet Explorer向けにもスタイルを提供するためにはもっと記述量を増やす必要が出てきます(prefers-color-scheme も使用できないので、このメディアクエリ内だけはシンプルに保てるはずです)。最近は国内でも各社でInternet Explorerのサポートを終了する動きが加速しているため、Internet Explorerサポートを終了したサービスからダークモード対応のWebアプリケーションが増えてくのではと筆者は予想しています。先述のYouTubeやGitHubもInternet Explorerのサポートを終了しています。

ダークモードでのUIデザイン

技術的にWebのダークモードがどう実現されるのかはわかってきました。ではダークモードのUIデザインではどんなことに気をつける必要があるのでしょうか。

なかなか想像が難しい気がしていたので、freee社内で開発しているデザインシステム “Vibes” のStorybookから適当なサンプルを見繕って、ブラウザの開発者ツールでスタイルを書き換えてダークモードの配色にしながら考えてみました。

入力フォームと送信ボタンのあるサンプルUIと、それをダークモードにしたものを並べてある
ダークモードの配色を試した画面

領域の表現

今回は背景色としてほとんど黒に近い濃いグレーから明度をすこしずつ上げた色を、かなり適当に3色用意しました。完全な黒にしないのは最近のスマートフォンのようにOLEDを使用しているディスプレイでは、完全な黒から他の色への描画が遅延することがあるからだとか。

元々の配色 #FFFFF, #F9F7F4, #EFEDE8 と、ダークモード用の #121212, #222222, #272727 を並べている

一般的に、ライトモードのときはほかのUIにオーバーレイするUIに影をつける表現をするのに対し、ダークモードではUIの応じて背景色を明るくすることで「浮いている」ことを表現します。Vibesでは画面内の区切られた領域を表現するために背景色を変えている部分があり、「浮いている」部分だけでなく、そういった部分の背景色も用意しなければならなくなりそうです。

今回はそういった要素が無い場所で試していましたが、実際のfreeeのUIではモーダルウインドウやポップアップメニューが多用されています。シャドウ・ボーダー・背景色の組み合わせをライトモードのときとは別に考えていく必要があり、単純な色の置き換えのように一筋縄ではいかなそうなことが見えてきました。

色の調整

Vibesでは、テキストの配色のコントラスト比を 4.5:1 になるように設計しています。これは freeeアクセシビリティー・ガイドラインでの定義 やその元となった WCAG (Web Content Accessibility Guidelines) での定義に従ったものです。

ダークモードの配色を作ってみると、文字やボーダーの色選びがライトモードのときよりもしやすいと感じました。コントラスト比は「相対輝度」によって計算するのですが、相対輝度の高い白や薄いベージュに対してコントラスト比を高めるには相対輝度を低く、暗い色にしていく必要があり、しかしそうすると色どうしの識別が難しくなっていくのです。ダークモードでは比較対象が暗い色なので相対輝度の高い明い色がたくさん使えるようになり、使える色の種類が多くなったように感じられたのだと思います。

コンピューターで表現される色はR, G, Bの三原色の組み合わせで表現されるわけですが、人間の目はこれらのうちGを強く感じ、Bを最も弱く感じるため、相対輝度の計算時にはそれを調整する係数がかかるようになっています。つまりfreeeのコーポーレートカラーである青は他の色より暗めに見えるのを調整する必要があるわけですが、freeeの印象を残しつつも視認性の高い色を選べるよう、特に慎重に進める必要がありそうです。

ライトモード用の配色の #C33939, #4575B4, #6F6B62 と、ダークモード用に調節した #E46F6F, #6398DE, #9D9A92

まとめ

今回はダークモードの実装やUIデザインを試作したことで、技術的な課題やUIデザインで注意の必要そうなところが見えてきました。ただ色を置き換えるだけというわけでなく、情報の表現の仕方やユーザーの受ける印象も調整しようとすると、それなりに手間がかかりそうということも見えてきています。そのあたりも踏まえつつ、ユーザーの期待に応えられるUIデザインをしていければな、と思っています。

エンジニア未経験のプロダクトマネージャーが、エンジニア留学のために勉強したこと

こんにちは。プロダクトマネージャーのmikiです。今回はじめての投稿ですので、簡単に自己紹介をさせていただきます。

私は4年ほど前にfreeeに入社しました。最初の2年はカスタマーサクセスとして、会計事務所さん・IPOユーザーさん・API連携希望ユーザーさんなどの様々な導入支援を担当し、その後、アライアンス事業部にて、パートナープログラムの策定・パートナー企業内でのカスタマーサクセスチームの立ち上げのご支援をしてきました。そして最近プロダクトマネージャーに異動になり、公式アプリを担当しております。

そして実は、現在はプロダクトマネージャー業務はお休みしていて、エンジニア留学の1期生として1月からAPIチームに参画し、エンジニアとして働いております。

エンジニア留学とは

freee社内の留学制度でエンジニアではない人が、3ヶ月間、エンジニアチームに一時的に参画し、エンジニアとして業務を遂行し、学習を深める制度です。

エンジニア留学へのマネージャーからの期待値(ミッション)

  • プロダクトマネージャーは開発チームと技術的なコミュニケーションができる必要がある。特に公式アプリはデベロッパーと直接の技術コミュニケーションが多いので業務知識に加え、より深い技術理解が必要である。 そのために必要な技術や開発プロセスおよび開発の勘所(仕様を一つ追加することの開発的なリスク、リファクタの必要性、どこまで詳細に仕様つめる必要があるか、開発にかかる工数など)を座学に加え、実務経験を通して学習してくること。

1週間の過ごしかた

マネージャーからの受け取ったミッションを達成するべく、現在の1週間のスケジュールはこんな感じで、なるべく起きている時間のほとんどはプログラミングの勉強に当てるようにしています。

1週間のスケジュール。朝6時から9時までは勉強、土日はほとんど勉強。

社内のイベント登壇用に作成したもので、少し時間のメモリが粗いことは多めにみてやってください。

エンジニア留学に向けた準備

エンジニア留学の1期生として年明けからエンジニアになるよ!とマネージャーから話をもらったのは12月の上旬のことでした。それから留学をするにあたって、少しずつ準備をはじめました。

PCをWindowsからMacに変える

エンジニアのほとんどの人がMacを使っていて、技術の解説はMacであることが多いとのことで、環境は合わせた方がいいと思い、変更しました。

仲間を作る

留学にあたって、基礎力となるプログラミング言語は独学での習得が不可欠でした。私は、なにかを学習するときは決まって、仲間を作るとうまくいくタイプだったので、オンラインのもくもく会に参加したり、もくもく会を開催したり、2月末を目標にHTML/CSS/JavaScript/Reactまで一緒に勉強したい人を募集して学習グループを結成してみたりと、積極的に駆け出しエンジニアの仲間を作る活動を行いました。

自己育成計画書を作成し学習を進める

これは新しい部署に異動するときには必ずやっていることです。自分がなにか新しいことを吸収してる期間は目に見えるアウトプットを出しづらいため、自分は世の中の役に立ってるんだろうかという気持ちが蔓延し、必要以上に自己肯定感が下がりやすい傾向にあると自己理解しています。トップスピードのまま3ヶ月間を駆け抜けられるように、自分がどれくらい昨日より今日、進歩したのかわかるようにスプレッドシートにて計画とその進捗管理を行い、モチベーションが下がらない工夫をしました。

今回は、上記3つの中でも、自己育成計画をピックアップし、 計画を立てる上で、非常に参考になりましたフロントエンドのロードマップ に沿ってどのように学習したかをご紹介させていただきます。

フロントエンドのロードマップ

roadmap.sh

これは@kamranahmedse さんが作成されたフロントエンド開発・運用に必要なスキルや知識・ツールなどをひとまとめにしてくれているロードマップ です。 上記のサイトに定期的にバージョンアップされながら公開されているようです。

ありがたいことに@TetsuKinomuraさんによる日本語版もあるので、こちらも貼っておきます。

さらに、親切なことにYouTuberのトラハックさんがこのロードマップについて解説もしてくれていました。これにより何を勉強しなければならないかという全体像をとてもよく理解できました。

youtu.be

エンジニア留学が決まったとき、何から手をつければいいのかわからず、勉強しておくといいと言われたものを手あたり次第に学び始めていました。あとからこのロードマップや解説動画に出会い、自分のやってきていたことがそんなにずれていなさそうで、ほっとしたのを覚えています。

また初学者にとって、自分の歩み方がずれていないか?という不安は日々ついてまわるので、学習のスタート時点でこういったロードマップがあると、とても安心だなと思いました。いつかfree初学者向けに、会計freeeの使い方やfreeeのAPIを叩くために必要な最低限の知識等をロードマップ にして公開してみたいです。

ロードマップ を眺めて立てた自己育成計画

下記はロードマップ とにらめっこし、1月〜12月にかけて立てた計画の一部抜粋です。

自己育成計画の一部抜粋。スプレッドシートに基礎的な内容から並べている

以降は、フロントエンドのロードマップにそって、どのように学習したかをご紹介します。

Internetについての学習

APIチームのマネージャーから年末に冬休みの宿題として、『Real Word HTTP』を紹介され、PdMのマネージャーからは『Webを支える技術』を紹介してもらいました。 しかし、いずれも読むための知識が圧倒的に足りなくて、音読はできるが理解ができない状態に陥ってしまいました。 そのため、もう一段レベルを下げて、『Web技術の基本』という文系の人向けにわかりやすくしてくれていそうな本を見つけたので、この本からまず入って学習を進めました。

HTML,CSS,JavaScriptの学習

この領域は、ドットインストールとYouTuberのしまぶーさんの動画で学習を進めました。 各領域はドットインストールは抜け漏れなく学習できるので、ざっと1回勉強をして、実践でじゃんけんアプリなどを作って、わからないことが出た場合は2回目を2倍速で見るという感じで活用していました。 ドットインストールは受講を終えていくとどんどん緑の棒が長くなっていき進捗がわかるので楽しかったです。

ドットインストールのキャプチャ

一方でドットインストールだけでは全体像や技術の背景・現在の開発現場でどこまで使われているのかなどはわからなかったので、そのあたりはしまぶーさんによる解説動画を見て理解していきました。もはやモダンな開発ではCSSや素のJavaScirptは書かないという事実は動画を見るまで知らなかったので、出会ってなかったらひたすらCSSを特訓していたかもしれません。3ヶ月の学習時間の配分を見誤らないかったのはしまぶーさんのおかけでした。

youtu.be

バージョン管理システム(GitHub,Git)

この領域については、Udemyの「Git:はじめてのGitとGitHub」で学習しました。

freeeで使われている方法についてはAPIチームのエンジニアのまっつーさんからレクチャーを受け、会計freeeのコード修正・プルリクエスト作成の実践学習を通して理解を深めました。

www.udemy.com

パッケージマネージャーとビルドルール

この領域については、YouTuberのしまぶーさんの動画で学習を進め、パッケージマネージャー・webpackの誕生の背景をざっと理解しました。

youtu.be

フレームワーク(React,Angular,Vue)

freee公式アプリはReactを採用しているので、まずはReactに限定し、学習を進めました。 この領域はじゃけぇさんのUdemyの「モダンJavaScriptの基礎から始める挫折しないためのReact入門」を用いて、JavaScriptの基礎を復習しつつ、Todoアプリを作成しながら学習しました。

www.udemy.com

axiosについては、YouTuberあべちゃんのReact入門をもとに、JSONPlaceholderやpixabayを用いてAPI通信の学びを深めました。

youtu.be

以上、自己育成計画をベースに学習した内容のご紹介でした。

FirebaseでReactを用いてアプリを作る基礎力は徐々についてきたので、引き続きTypeScriptを学び、いつか個人としてfreeeアプリストアでアプリをリリースすることを夢見て技術力をさらに上げていきたいと思っています。

来週は自分が対応した公式アプリの不具合の修正や機能拡張が続々とリリースされるのでとても楽しみです。

エンジニア留学はあと残り2週間!最後まで駆け抜けます!

Docker image を導入して protobuf を使う

こんにちは、会計freeeの開発をしている清水です。2020年4月に新卒としてfreeeに入りもうすぐ一年が経とうとしています。

この記事では私の所属チームのプロジェクトで試している、protobuf のための開発環境について書きます。

背景

現在私たちのチームでは、会計freeeのバックエンドのアーキテクチャ移行を進めています。会計freeeは長年にわたって開発が続けられているRailsアプリケーションです。現在でも社内の多くのチームのエンジニアが開発に関わっています。そんな中で実装は複雑化し、機能ごとの依存関係が分かりづらい状態になっていました。新しいアーキテクチャの目的は、そんなアプリケーションの実装の依存関係を明確にし、より安心して開発を継続できるようにすることです。

このあたりのより詳しい話は以前id:mihyaeru21が発表した以下の資料にまとまっています。

speakerdeck.com

現在移行を行っている範囲では、アーキテクチャ移行の第一段階として API Model と呼ばれる新たなインターフェースを導入しました。これは ActiveRecord に依存しないデータ構造で、バックエンドの実装内部において、モジュール同士は基本的にこのAPI Modelを介してのみやり取りを行うような設計になります。

現在のところ API Model の実装には、protobuf を採用しています。型が定義できること、また将来的に機能をマイクロサービスとして切り出す際もインターフェースとしてgRPCでそのまま流用できることがメリットです。

自動生成のためのコンテナ

API Model には protobuf を利用するため、Rails アプリケーションで実行される Ruby コードは、proto ファイルの定義から自動生成します。また読みやすい HTML 形式のドキュメントも、protoc のプラグインである protoc-gen-doc を使って、コードと一緒に定義から自動生成します。これにより常に実際に動くコードに連動してドキュメントが更新されるようになります。

例えば入力となる proto ファイルの定義と、自動生成される Ruby のコードと HTML のドキュメントは以下のような対応関係になります。

syntax = "proto3";

// コメント1
message Hoge {
  int64  number = 1; // コメント2
  string code   = 2; // コメント3
}
...
Google::Protobuf::DescriptorPool.generated_pool.build do
  add_file("sample.proto", :syntax => :proto3) do
    add_message "Hoge" do
      optional :number, :int64, 1
      optional :code, :string, 2
    end
  end
end

Hoge = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("Hoge").msgclass

protoファイルから生成されるドキュメント
生成されるドキュメント(protoファイルのコメントも反映される)

開発にあたっては、エンジニアごとのローカル環境に依存して生成物に差が生まれないようにする仕組みを用意する必要がありました。そこで自動生成のためのツールのバージョンや、実行環境を固定するためにDocker imageを利用し、Amazon Elastic Container Registry (ECR) を介してそれを開発者間で共有するようにしています。

Dockerfile はだいたい以下のような感じになり、build 時に使用する protocと proto-gen-doc のバージョンを指定します。

FROM debian:buster-slim

ARG PROTOC_VERSION
ARG PROTOC_GEN_DOC_VERSION

ADD https://github.com/google/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip ./
ADD https://github.com/pseudomuto/protoc-gen-doc/releases/download/v${PROTOC_GEN_DOC_VERSION}/protoc-gen-doc-${PROTOC_GEN_DOC_VERSION}.linux-amd64.go1.15.2.tar.gz ./
RUN apt-get -q -y update && \
  apt-get -q -y install unzip && \
  unzip protoc-${PROTOC_VERSION}-linux-x86_64.zip -d ./usr/local && \
  tar xvzf protoc-gen-doc-${PROTOC_GEN_DOC_VERSION}.linux-amd64.go1.15.2.tar.gz && \
  cp protoc-gen-doc-${PROTOC_GEN_DOC_VERSION}.linux-amd64.go1.15.2/protoc-gen-doc ./usr/local/bin && \
  ...

# 生成物を手元に得るためのマウントポイント
VOLUME ["/ruby", "/docs", "/proto"]

ENTRYPOINT [ "protoc" ]

手元に落としてきた Docker イメージからコンテナを起動し、ローカルの proto ファイルから、コンテナ側でコードとドキュメントを生成します。最後にこの流れ実行できる Rake タスクを用意すれば開発環境の準備は完了です。

以上で開発者の環境による差分を気にすることなく、インターフェースの定義にだけに集中して開発が進められるようになりました。