マルチカルチャーな職場におけるコミュニケーション

こんにちは、グローバルチームのエンジニアのFernandです。

この記事はEnigmo Advent Calendar 2023の19日目の記事です。私は、15年近くフルスタックエンジニアとして働いてきました。さまざまなプロジェクトに関わってきましたが、、新しいチームに参加するたびに、技術的なスキルだけでなく、特にソフトスキルについても新しく学ぶことが多くあります。今回は、職場のミーティングで外国人として直面した課題を共有したいと思います。

ある日、ITエンジニアの妻が彼に頼んで、「スーパーで牛乳を1パック買ってきて。もし卵があれば1ダース買ってきて」と言いました。そこでエンジニアは買い物に行き、言われた通りに行動し、帰宅しました。手には牛乳パックが12個ありました。
妻は驚愕しました。何が間違いだったのでしょうか?


プロジェクト・マネジメント協会(PMI)の報告によると、ビジネス目標を達成しないプロジェクトの半数以上は、効果的なコミュニケーションの欠如によるものとされています。実際に、不十分なコミュニケーションにより、1500億円を投じたプロジェクトの場合には約100億円がリスクとなるのです。ビジネスでは、12個の牛乳パックが大きな損害を生み出してしまうかもしれないのです。
コミュニケーションの齟齬による経済的リスク
ソース: ©2013 Project Management Institute, Inc. Pulse of the Profession In-Depth Report: The High Cost of Low Performance: The Essential Role of Communications, May 2013. PMI.org/Pulse
私が日本の企業で働き始めた当初、さまざまなチームとのコミュニケーションに苦労しました。私と同じように、日本に住む外国人の多くが直面する経験です。
外国人が日本で働くうえでぶつかる壁(言語の壁が半数以上)
ソース:NikkeiAsia
私が最初に入社したスタートアップ企業では、お客様の満足度が最も重要であり、彼らを神様のように対応すべきということを教わりました。そのため、ミーティングに参加する際、私は静かに座り、より理解するために一層耳を傾ける必要がありました。私は日本語に自信がなかったため、質問をすることや間違いを犯すことを恐れていました。自分が話すことで、クライアントから私たちの会社がネガティブに評価されるのではないかという不安がありました。
しかしそれでも、各ミーティングの後に反省点を見直して、気づいたことを改善してから自信を持って質問をするようにしました。そして、効果的なコミュニケーションを大事にする日本のチームに参加する機会を得たおかげで、私はミーティング中に質問をする勇気を持ち、プロジェクトやクライアントの要件をより理解できるようになりました。日本人の同僚は忍耐と理解力をもって複雑な概念を簡素化するために時間をかけて説明を繰り返してくれました。
しかし、言語の壁は、誤解を招く障害となることもあることも私は理解しています。それにより、会話の流れが乱れ、自分の意見を正確に表現することが難しくなります。思いを正確に表現することへの取り組みは、話す人と聞く人の双方にとっても苦悩の源となっています。できるだけこれを避けるために、事前に読み込んで準備し、質問をまとめて整理することが大事です。
外国人のメンバーがミーティングをする場合、一人だけに発言の責任が押し付けられないように、協力し合いながら取り組みます。通常、そこでは、生産的に結果を出すために、話の途中で割り込むことが歓迎され、許容されます。曖昧さを解消するために、アイデアを効果的に共有して質問をするこの戦略は時に混沌としたものになりますが、コミュニケーションの理解を促進し、より協力的で生産的な働き方を促進するのに非常に効果的だと感じています。誤解や心配事が生じた際に即座にそれらを明確化することは、コミュニケーションの質を向上させ、より協力的かつ生産的な職場環境を生み出します。参加者全員が議論に貢献することを促すことで、創造性が高まり、アイデアが高められ、より豊かでダイナミックな成果が生まれます。
しかし、文化的な習慣やエチケットにも配慮することが重要です、特に話し手が日本人の場合です。このような場合、割り込むことは失礼とされ、質問はミーティングの最後まで取っておくことが通例です。そういったミーティングでは、私はより受動的なアプローチを取る傾向があります。ただし、質問や懸念事項を早急に解決させたい場合、日本語の能力に自信がなくても話すように努めています。日本語の能力に自信がなくても、ただ聞くだけに頼るのではなく、積極的な参加こそが助けを求めて理解を深める唯一の方法であることを心に留めています。言語の壁を乗り越え、異文化間のコミュニケーションの複雑さをより効果的に乗り越えるためには、日本語の勉強を続けることが重要です。
私は現在、さまざまな国のメンバーから成るチームに所属しています。私たちの主要なコミュニケーション手段は日本語ですが、必要に応じて英語も使用しています。さまざまな時差の課題にも取り組んでおり、私たちのマネージャーはその違いがミーティングのスケジュールに影響しないよう柔軟に対応してくださいます。彼女は流暢な英語と日本語を活かし、私たちの質問や懸念事項をサポートし、チーム内の円滑かつ効果的なコミュニケーションを容易にしてくれます。私は定期的に他のチームとも交流しなければなりません。日本語を使ってのコミュニケーションは難しいですが、貴重な機会であり、コミュニケーションスキルを実践し向上させるチャンスでもあります。しかし、通常業務に追われて、学習に費やす時間の確保がなかなか難しくなっています。プライベートと仕事、そして言語学習のバランスを取ることは大変な努力を要します。まるでジャグリングをするようなもので、集中して言語の練習だけに時間を割くことはなかなか難しいものです。
言語の不完全さや課題があっても、ミーティングでの同僚たちはそれを判断することはありません。むしろ、言語の壁にとらわれず、積極的に参加して貢献する姿勢は評価されるでしょう。しかし、質問をする際には、ただ質問を投げる、自己アピールのためにするということは避けるべきです。そのような行動は、ビジネス上での評判に悪影響を及ぼすだけでなく、私たちが維持しようとしている協力的な雰囲気にも支障をきたす可能性があります。
さらに、会議を進行する際は、コミュニケーション能力や自信のレベルに関係なく、全参加者が積極的に参加できる包括的で支援的な雰囲気を育むことも重要です。間違った質問や関連性のない質問をする人がいても批判するべきではないでしょう。そのような場合に他者を批判すると、プロジェクトが始まる前から失敗したも同然です。前述したように、効果的なコミュニケーションが生産性を向上させるという認識はとても重要です。研究によれば、効果的なコミュニケーションは生産性を最大25%向上させることができます。最終的には、プロジェクトの成功は効果的かつ効率的なコミュニケーション能力にかかっています。卵と牛乳の個数を間違えることもないことでしょう。不確実な点が生じた場合には、積極的に話して明確化することが重要です。積極的なリスナーであり、共感を持って接することを心がけましょう。英語や日本語の流暢さだけに焦点を合わせるのではなく、彼らの質問やアイデアの価値がプロジェクトを前進させ成功させる上でとても重要です。

(English version)
Communication in Workplace

An IT engineer was asked by his wife to go to the store and buy a carton of milk, and if there are eggs, buy a dozen. So the engineer goes shopping, does as she says, and returns home with 12 milk cartons.

Oh boy , But what went wrong?


According to the Project Management Institute (PMI) report, over half of projects that fail to meet business goals can be attributed to ineffective communication. In fact, poor communication puts approximately $75 million at risk for every $1 billion spent on projects. Well, it seems that one dozen cartons of milk can potentially result in a substantial financial loss.

The amount at risk for every US$1 billion spent on a project.
Source: ©2013 Project Management Institute, Inc. Pulse of the Profession In-Depth Report: The High Cost of Low Performance: The Essential Role of Communications, May 2013. PMI.org/Pulse
When I first started my journey working at Japanese companies, I often struggled to communicate effectively with various teams. Unfortunately, this burden is not unique to me but a shared experience among many foreign residents in Japan.
Barriers foreigners encounter when working in Japan. Language barrier is the most prominent obstacle.
Source:NikkeiAsia
Working in startup companies, I quickly learned that client satisfaction was held in the highest regard, often considering them as king or god (o-kyaku-sama wa kamisama desu) whose every request must be fulfilled. Therefore, when I joined meetings, I had to sit quietly and listen harder to understand the discussions. I feared asking questions and making mistakes because of my Japanese language proficiency. My company might be judged by the client whenever I attempt to speak up. I was able to manage this by researching sample implementations after each meeting and creating prototypes before confidently raising a question.
Then, I had the opportunity to join a Japanese team that fostered effective communication. Encouraged by my supportive environment, I mustered the courage to ask questions during meetings, improving my comprehension of projects and clients' requirements. My Japanese colleagues displayed immense patience and understanding, taking the time to reiterate their explanations and simplify complex concepts, ensuring everyone understood the information.
But don't get me wrong, despite the positive environment, the language barrier often presents obstacles that could lead to misunderstandings and misinterpretations. It disrupts the conversation flow and makes it challenging to express oneself fully. The struggle to articulate thoughts accurately has become a source of frustration for both the speaker and the listener. In order to avoid this as much as possible, I read and prepared beforehand, collating and organizing my questions.
In situations where the speaker is a non-Japanese teammate, I collaborated, ensuring that the onus of speaking does not solely rest on one person. Usually, in meetings that consist of non-Japanese participants, interruptions are welcomed and accepted to foster a productive environment where ideas can be effectively shared, questions can be asked, and clarification can be provided. While this strategy may seem chaotic at times, I find that it is incredibly effective in facilitating comprehension and generating deeper insights. Obtaining immediate clarity on any misunderstandings or concerns enhances the quality of communication and promotes a more collaborative and productive work environment. By establishing a culture where all participants are encouraged to contribute to the discussion, creativity surges, and ideas are elevated, creating a richer and more dynamic outcome.
However, I am also mindful of cultural norms and etiquette, particularly when the speaker is Japanese. In these situations, it would be considered rude to interrupt, and it is customary to reserve questions until the end of the meeting. I tend to adopt a more passive approach during such meetings. Nevertheless, if I do have pressing clarifications or concerns, I try to speak up regardless of my lack of confidence in my Japanese proficiency. I remind myself that the only way to seek assistance and gain a better understanding is by actively participating in the conversation rather than solely relying on attentive listening. However, continuing to study Japanese remains paramount in overcoming these language barriers and navigating the intricacies of cross-cultural communication more effectively.
Currently, I am fortunate to be a part of a diverse team with members from different parts of the world. Although our primary mode of communication is Japanese, we also embrace the use of English when needed. Despite the challenges of various time zones, our manager has done an exceptional job ensuring that these differences do not impede our meeting schedules. With her fluency in English and Japanese, she adeptly accommodates our questions and concerns, facilitating smooth and effective communication within the team. I also have to interact with other teams periodically. Communicating using the Japanese language is challenging, but it also gives me valuable exposure and the chance to practice and enhance my communication skills. Though I have to admit that the demanding nature of daily life and work commitments has restricted the amount of time available for study. Balancing work, personal responsibilities and language learning can be a juggling act, making it quite challenging to allocate uninterrupted time for focused language practice.
Ultimately, the success of our projects hinges on our ability to communicate efficiently and effectively. If uncertainty arises, it is crucial to speak up and seek clarification. Rest assured that in meetings, colleagues will not judge any language imperfections or challenges you may encounter while expressing yourself in Japanese or English. Instead, your willingness to participate and contribute despite any linguistic limitations will be appreciated and acknowledged. However, it is also essential to avoid asking questions solely for the sake of asking or to showcase your skills. Engaging in such behavior may have a detrimental impact on your professional reputation and hinder the collaborative atmosphere we strive to maintain.
In addition, it is equally important for the meeting host to take accountability in fostering an inclusive and supportive meeting environment that encourages active participation from all attendees, regardless of their communication skills or confidence levels. It is critical to refrain from criticizing individuals who may ask questions that might seem incorrect or irrelevant. Criticizing others in such instances, the project had already failed even before it started. Be an active listener and practice empathy. Fluency in English or Japanese should not be the sole focus; instead, the value of their questions and ideas truly matters in moving the project forward and achieving success.

明日の記事の担当はSellチームの平井さんです。お楽しみに。


株式会社エニグモ すべての求人一覧

hrmos.co

細かいことの組み合わせで日々の開発を快適にする

こんにちは、iOSエンジニアの池田です。

この記事は Enigmo Advent Calendar 2023 の 18 日目の記事です。 この記事では担当のプロジェクトにおいて日々の開発を快適にするために実施している細々したことについて紹介します。

私はBUYMAiOSアプリ開発を担当しています。 iOSアプリ開発に限らずプロジェクトを進める中では、コアタスク(ここではiOSアプリの開発作業と定義)とノンコアタスク(コアタスク以外の作業)が発生します。

開発の効率を上げるため、開発者の開発の快適性を上げるためにノンコアタスクは極力削っていきたいものです。 ここではノンコアタスクの中でもチケット管理、Pull Requestの管理に関わる部分について触れていければと思います。

現在のプロジェクト環境


現在の担当プロジェクト内では、チケット管理にJIRA、開発用のプラットフォームにはGitHubを利用しているので、それらに関わる内容について触れていきます。

また、コミュニケーションツールとしてSlackを利用しているため、こちらとの連携も少し触れます。

JIRA


自動化

JIRAのチケット管理では、各チケットの開始日や終了日、担当者、チケットの作業状況など様々な情報の日々の更新が必要になってきます。

一つ一つの作業は作業時間も短く単純作業ではあるのですが、数が多くなると作業時間ももちろん累積されますし、何にも考えずにできるわけではないため、じわじわ地味に体力を削られます。

そういった作業を減らし、少しでも快適性を上げるためにはJIRAの「自動化」が有効です。

以下は私が担当するプロジェクトで設定している「自動化」のルール一覧です。

様々設定されていますが、この中でも「プルリクエストがマージされる → 課題を完了にする」が結構気に入っています。

Pull Request のコードレビューを受けた後自分でマージする運用をしている場合、このルールが設定されていないと、以下のような手順が必要になります。

  1. ブラウザでGitHubを開く
  2. GitHubの画面上でPull Requestの一覧を開く
  3. 該当のPull Requestを開く
  4. Pull Requestをマージする
  5. ブラウザでJIRAを開く
  6. JIRAのボード等でチケットを完了にトランジションさせる

これらの手順の中で、4.から 5.では別サービスへの切り替えが必要で、6.の作業ではドラッグ&ドロップかオプションメニューからの選択が必要だったりで、キーボードからマウスへの操作の切り替えも余分に必要になります。

4.で作業に満足して 5.以降忘れることもあり、JIRAのカンバン管理者から完了/未完了の問い合わせが来たとしたらコミュニケーションコストもかかります。

これだけでも意外と積み重ねるとコストになるので、設定することによる快適度は上がっている感じがします。

Gitブランチ作成

もう一つJIRAの機能で細かいけどよく使っている機能がチケットのブランチ作成機能です。

以下チケットの画面キャプチャです。

チケットの「開発 > ブランチを作成 > GITで新しいブランチを作成してチェックアウト」の欄で、チケットIDが入ったブランチ名を自動生成してくれます。

また、入力欄の右側のボタンでクリップボードにコピーできるため、CLIでブランチ作成の際にコピー&ペーストでブランチを作成することができます。

こちらを利用することでブランチ名を考える手間や、CLIで入力する手間を省くことができます。

名前を考えるのって決めの問題なのですが、意外と考えるコストがかかる作業だと思っているので個人的にはすごく助かっています。

GitHub


PULL_REQUEST_TEMPLATE.md

Pull Request を作成して開発されている場合、設定しているリポジトリが多いかと思います。

本プロジェクトでは、以下のようなトピックをフォーマット化して記載するようになっており、記載時の手間を少し減らしています。

  • 関連チケット
  • Pull Request でやったこと
  • 懸念点・注意点
  • 相談事項

また、JIRAとGitHubが連携されるようになっているため、チケットのURLを記載するとJIRAのチケットにGitHubのPull Requestが連動するようになっています。

Slack


SlackとJIRA、SlackとGitHubも連携されており、チケットやPull Requestの条件に応じた更新があったタイミングで通知が来るようになっています。

JIRAの通知

JIRAの通知設定は以下のようになっており、コメントやステータスの更新等通知が来るように設定されています。

GitHubの通知

GitHubの通知設定は以下のようになっており、コメントの見落としが少なくなるようにcomments:'channel'の設定をしているところが個別に設定した部分だったかと思います。

まとめ


チケット管理、Pull Requestの管理に関わる部分についてノンコアタスクを削減するため細々やっていることをご紹介しました。

プロジェクトの環境によって合う、合わない部分があったりしますが、見て頂いた方の何かのご参考になれば幸いです。

日々の変化している状況や、気づいたちょっとした不要な手間など、アンテナを高くしつつさらなる改善、日々の開発の快適度を上げていければと思います。

株式会社エニグモ すべての求人一覧

hrmos.co

enigmo(BUYMA運営企業)のコーポレートIT(社内SE・情シス)運営方法と将来像

こんにちは、コーポレートエンジニア(コーポレートIT[CO-IT]チーム) の 横川 です。 この記事は Enigmo Advent Calendar 2023 の 17 日目の記事です。

この記事では社内ITサービスを支えるチームの組織作りをテーマにどのような観点でチーム運営を行っているかをご紹介したいと思います。

コーポレートIT領域は、年々取り扱うサービスや技術が広くなり、様々なスキルセットが要求されてきていますが、本記事は特定技術の話ではなく組織運営にフォーカスした内容となります。 これから社内SEを目指される方や現在コーポレートエンジニアとして活躍されている方々に少しでも参考にしていただける内容となっていれば幸いです。

はじめに

自己紹介とCO-ITチームの紹介

私はITベンダーでネットワークエンジニアとしてキャリアをスタートし、その後セキュリティ製品の代理店にてプリセールスエンジニアを担当してきました。その後、キャリアチェンジし、デベロッパーでの社内SE(情シス)、SaaS提供企業でのコーポレートIT担当を経て、昨年10月よりenigmoにjoinしました。 コーポレートITという大きな領域全体を俯瞰して自社の最適なコーポレートITを自由に作ることができるという環境に惹かれて入社を決断しており、実際にそのミッションに日々向き合える環境で働いています。

CO-ITチームはコーポレートオペレーション本部の人事総務グループに属し、社内ITサービス全般を担当しています。 ブログ執筆時点(2023年12月)では、マネージャ[人事総務グループ部長]を除くとチームメンバーは私を含め3名で現在4人目のエンジニアを募集している状態です。 最終的な意思決定はマネージャが担いますが、当社のコーポレートIT領域の対応は現在私がリードする役割を担っています。

コーポレートエンジニア・社内SE・情シスについて

近年、コーポレートエンジニアやコーポレートITといったワードを見かけることも多くなってきており、従来の社内SEや情シスという表現との明確な違いを説明するWebページ等も増えてきているかと思います。 ざっくり両者の違いは、「見る範囲・視点の違い」とされていることが多く、コーポレートエンジニアは従来の社内SEや情シスのスコープよりも広範囲に及ぶ(企業全体を視野に入れ、ITスキルを活用して提案・企画を行う)と定義されています。*1

コーポレートエンジニアはバックオフィス部門に所属し、会社の売上に直接貢献することはできません(プロダクト部門メンバーの業務効率向上に資することで間接的に貢献する)。企業によっては、プロダクト側に強い優遇(力が強い傾向)があったり、バックオフィス側は利益を生まない部門として不遇な環境になっている場合も見聞きしますが、プロダクト側・バックオフィス側どちらかに優劣があってはならないし、どちらも(会社の成長に貢献する部門として)リスペクトし合える企業風土が醸成できていることが望ましいと感じます。*2

そして、シンプルにコーポレートIT部門が会社から求められることを表現すれば、

自社に最適なコーポレートITをいかに低コスト・最速で実現し、安定稼働を継続できるか

になります。

予算が無限であれば、何も考えず最新で優れたサービスをフルライセンスで導入し、外部の専門ベンダーに要件定義〜運用まで全て外注して、トラブル対応や今後のアップデートも含めて24h365dでフルサポートされるオプションを付帯すれば他社を圧倒するコーポレートITの運用が可能となります。*3しかしながら、自社の社内ITサービスに実プロダクト以上の予算を割ける企業がどれだけあるでしょうか?この点にコーポレートエンジニアの存在意義があるものと考えられます。コーポレートエンジニアは、しっかり自社の状況を俯瞰して会社のフェーズに合わせて、必要十分なサービス提供に日々向き合うことが求められる職種です。

1.組織運営の前提を整理する

私自身が実際に実施していることを含め、組織運営にあたりクリアすべきと考えていることについて記載していきます。

ミッションを理解する

以下にMVVを掲載します。当社のミッションは こちら の通りですが、CompanyのMVVに応じてCO-ITチームでもMVVを定義しています。

MVV(ミッション・ビジョン・バリュー)
このMVVは、私が入社前から定義されていたものですが、現時点で変更の必要性はないと判断し、そのまま継続利用しています。 近年、特にスタートアップ企業では、MVVを掲げている企業が多くなっている印象を受けますが、会社側がただ掲げているというよりは、従業員がそのMVVを自分事として意識するようにMVVに向き合う時間を業務時間の中に組み込んでいる企業も増えてきているのではないでしょうか。MVVというのは、非常に重要であり、各自の担当タスクは全てMVVに紐づいたものと考えることができます。

会社の方針と現在のフェーズをすり合わせる

ワーディングは違っても、多くの企業のコーポレートIT部門のMVVは当社のものと重なる部分が多いのではないでしょうか。 それは企業活動における基本的な役割が同じであることに起因しますが、MVVが同じでも各企業・担当者の業務内容は例えば下記のような理由によって大きく異なります。

  • 会社の規模や方針によって対応範囲やチーム構成が様々である
  • 企業規模の拡大や事業成長に伴って縦割りが進み、サービスや製品毎にチームや担当者が限定されている
  • 要件定義だけ・設計構築だけ・運用だけのようにスコープが限定されている

したがって、具体的なチームビルディングに移る前にまず現在のフェーズを整理し、組織運営方針についての合意形成が必要になります。その大前提として、社内ITサービスを外注するのか内製するのかの判断を行います。一昔前までは専門のエンジニアが担当せず総務担当者が兼務や片手間で社内システム(情シス)を担当することも多かったように感じますが、昨今では求められるスキルや要件の複雑化によってそういった体制では対応しきれなくなってきているのではないでしょうか。事業規模の比較的小さな企業やスタートアップ企業などプロダクト側にフルコミットする必要がある場合は、社内ITサービスの外注化を行う場合もあるかと思いますが、以下のようなリスクがあるため慎重な判断が求められます。

  • 顧客伴走型と謳っているサービスであっても顧客視点の小回りがきくサービスにはなりにくく、他企業共通のテンプレ利用による対応となるリスク
  • システム化や仕組み化のベースとなるプラットフォームを顧客側ではなく発注先ベンダー側環境で構築され、顧客側では関知できないリスク
  • 設計や設定、ナレッジ自体が顧客側に蓄積されず基本的にブラックボックス化してしまうリスク
  • 各種リスクを解決するような契約を試みた場合、自社で専門のエンジニアを採用するよりコストが高くなるリスク
  • 発注先都合で突然サービス終了となり、自社の社内ITサービスが停止してしまうリスク

また、社内ITサービスというのは、自社独自の要件を年々積み重ねて構築していく要素も大きいため、例えばIDaaS製品の設計だけ、社内NWの構築だけを切り出すのではなく、社内ITサービス全体のバランスや連携も視野に入れた高い視座で最適なサービス運営を行う必要があります。加えて、各種サービスの発注先ベンダー等との価格交渉や要件すり合わせについても一定の知識が必要になりますので、その意味でも自社で専門のエンジニアを採用して運営していくことは重要であると言えます。

CO-ITチームは、私が入社する直前まで暫定的にマネージャ自身がプレイヤーを兼務し、多くの実務は(ヘルプデスク業務を外注できるような)外部サービスを利用することで社内ITサービスを維持管理している状態でしたが、私は業務状況を確認した上でチーム運営を再設計するフェーズ(初期フェーズ)と判断しました。なお、マネージャとは定期的に「As is」/「To be」について大枠の目線合わせを行っています。*4

プロダクト、スコープ、役割を整理する

大枠の方針がフィックスした後は、少しずつ具体化していきます。まず、プロダクトとスコープの定義です。 一般的には、事業活動において顧客に提供するものをプロダクト(当社の場合、BUYMAというサービス)と呼び、コーポレートITがプロダクト?と違和感を感じられるかもしれませんが、顧客(従業員)に対してサービスを提供する部門である以上当然プロダクトがあって良いと思いますし、意識すべきと考えています。そして、そのプロダクトを提供するためのスコープの定義も併せて必要です。

プロダクト/Job Titleとスコープのマッピング

上記がCO-ITチームのプロダクトと大枠のスコープになります。スコープは大項目のみ表記していますが、例えば今回のような「techブログへの投稿」業務は「ブランディング貢献」の中に含まれるという感じです。 また、スコープは視座や技術的な難易度等々によってピラミッド型になるので、メンバーの役割の大雑把なプロットも行っています。*5

メンバー構成(チームの総リソース)を整理する

ここまででチームが目指す方向性が見えてきたので、次に具体的なメンバー構成や必要リソースの整理に移ります。 なお、この項目については、各企業の人員計画・予算・業績・既存のメンバー構成等々複雑な要素を踏まえた経営判断になるかと思います。 結果だけの記載となりますが、CO-ITチームは、4名体制を目指すべく現在4人目のエンジニアを募集している状態です。

まとめますと、CO-ITチームは以下のように年間の投下リソースで表現されるValue(アウトプット)が会社から求められる期待値をアウトパフォームすることを意識しなければなりません。

チーム(総リソース[年間約7,680h*6])のValue > 会社からCO-ITチームへの期待値

裁量と責任、働き方

採用業務を行っているとよく質問を受ける項目ですので、ここで触れたいと思います。 CO-ITチームは、各担当者毎にスコープを限定するようなことはなく、基本的に各自のミッションサイズ(会社が各自に期待すること)に応じてコーポレートIT領域全てに携わる方針としております。*7 ミッションサイズの中で最大限の裁量と責任を持っていただき、自由に業務時間を使うことで最大のValueを発揮いただくのが最良という考えに基づいています。

また、当社はオフィスワーク・リモートワークの選択も一定の裁量が許容されていますので、CO-ITチームでもその範囲内で自由選択としています。 基本的にオフィスワークが必要な業務(デバイスのキッティング等)を中心に行うメンバーは出社頻度が高くなりますが、リモートワークすることでオフィスワークする以上のアウトプットが出せるのであればリモートワークの頻度が高くても良いという方針です。なお、業務スコープの特性上(ITサービスデスクを担当しているため)、必ず一人以上のチームメンバーがオフィスワーク(本社に出社)することで物理的なインシデントやユーザサポート対応を可能にしています。

2.現状を俯瞰する

チーム運営の前提の整理が終わった後は、現状の把握に移ります。

課題を整理する

サービスを整理する

プロダクトを理解した上で顧客に提供するサービスの整理が必要です。近年のコーポレートIT領域はオンプレからクラウド化の流れが急速に進んでいるため、SaaSのことばかりに目が行きがちですが、従来の社内NW運用業務をはじめ、企業によってはオフィスファシリティやセキュリティ領域も含まれます。 また、SaaSによっては他のバックオフィス部門(経理等)やプロダクト側が慣例的に運用しているサービスもあり、各サービス毎で主管している部門は企業によって差異があり、正確な把握が必要です。

コストを整理する

主管するサービスが洗い出せた後は、具体的なコスト感の把握です。 自チームが提供するサービスのコスト感がパッと答えられないというのは問題外であり、そのコスト感に見合うメリットを会社にもたらしているのかを常に意識する必要があります。 また、SaaSであったとしても、単純にライセンス費用や月額利用料といった費用だけでなく、導入から日々の維持管理に必要な人的リソースのコスト(1人日の単価を具体的に設定した上で年間何人日、何人月の工数が掛かりどのような金額になるのかまで想定)を含めて該当サービスのコスト妥当性が判断される必要があります。*8

CO-ITチームでは、下記のような主管サービスを網羅した一覧を作成・運用しており、提供サービスの総合計を従業員数で割ったサービスコストの算出を行っています。 この一覧には、サービスのコストをはじめ、サポート窓口の情報や稟議・請求書対応、更新のタイミング等々を含め、サービス別に串刺しして比較でき、これだけを確認すれば運用に必要な情報が取得できるように一元管理しています。

提供サービス一覧

なお、現時点では見える化したところまでしか到達しておらず、コストの最適値はどのくらいなのか、今のコストは妥当なのかという分析や評価を実施するフェーズには至っておりません。 近い将来、このコストを一つのパラメータとして適切なサービス導入のガイドラインを策定することを見据えております。

手続き・運用を整理する

次に見積・稟議・発注・請求のような一連のサービス導入手続き、導入後の実運用について把握します。実現したいことは各企業大体同じであるにも関わらず、企業によって利用しているワークフローは様々であり、実現するまでに理解すべきことのボリュームに大きな違いがあります。

会議コストを考え、会議体を整理する

ファシリテーションや会議に関するビジネス書で数多く述べられていますが、「会議コストは非常に大きなもので意味のある会議をすべき(無駄な会議は廃止すべき)である」といった主旨のトピックが記載されています。

例えば、4人のエンジニアが1hのMTGをする場合、そのコストは超ざっくり¥25,000程度になります。*9ですので、その1hのMTGのアウトプットに会社はその金額を払うことになるので、その期待値を超えるValueが必要になります。特に会議は複数人で行うものなので、各自が単独で行うTodoよりも大きな人件費が計上されてしまうことになります。また、とりあえず参加するだけで仕事をした気になってしまうので注意が必要です(会議に参加すること自体にValueはなく、その会議でどのようなアウトプットを出したかが重要)。

ということで、CO-ITチームでは必要な会議体を整理し、チームのフェーズに合わせた会議運営を行っています。

情報共有・ナレッジ化を意識する

まだまだ続きますが、続いてはチームレベルのナレッジマネジメントです。一人情シスのような状態でなければ、基本的に業務を進めていくとチームメンバーへの具体的な手順共有は当然として、各種設計指針やそもそもの要件定義内容等々、チーム独自のナレッジを複数人で共有するシーンが多々あるかと思います。ナレッジ共有を全く行わない(何もかも属人化)のような組織はないと思いますが、共有の仕方に課題感が残っている組織は少なくないかと思います。CO-ITチームでは以下のポイントを実行し運用しています。

  • 共有の仕方を定義する
  • 共有すべき粒度を定義する
  • ナレッジ化に惜しみなくリソースを投下する

タスクを整理する、バックログ化する

そして、最後にタスクの整理です。PJ管理やタスク管理を実施するためのツールや方法は様々なので省略しますが、当社では私が入社前の段階からAsanaを利用していたため一旦そのまま継続利用しています。タスク整理にあたり、ポイントとしたことは、以下の通りです。

  • 必ず各タスクの目的を明確化する
    • 不明瞭な(誰も自分事としていない)タスクが管理ツール上に表示されていない状態
    • マネージャは意思決定のみを担当(タスク担当者にマネージャをプロットしない)
  • 全体を同じ箱の中に含め他メンバーの業務状況も見える化する*10
    • スポット、割り込みタスクが入ってもチーム全体のタスク一覧に起票する
    • 個人のローカルTodoで処理しない、オープンにする
    • 基本的に起票する(よほど数分でクローズするようなタスクは例外)

本来であれば、アジャイルの考え方に沿って、チーム全体でスクラムを用いてスプリント毎に同じMissionに向かって組織運営(バックログ消化)を行いたいのですが、CO-ITチームではまだまだそういったフェーズにないと判断し、現状はバックログ化することまでに留まっています。

CO-ITチームの課題

以上の課題整理を行った結果、CO-ITチームでは以下のような課題が見えてきました。 既にある程度クリアできてきているものもありますが、日々最適化すべく現在も業務推進中です。 何をどのように解決したかの話は、また機会があればご紹介させていただきます。

  • 資産管理の精度が低い、管理できていないものが存在する
  • サービスのスコープ、責任分界点が不明瞭
  • ナレッジが点在している、不足している、陳腐化している
  • ブラックボックス化(実務の外注サービス依存にも起因)、属人化している
  • 業務分析できる基盤が整っていない(定量化できていない)
  • 意思決定した背景・経緯・ポイントが体系化されていない
  • 中長期的な視点で要件定義・設計・設定が行われていない
  • 暫定対応でタスククローズした内容のまま形骸化している
  • ユーザ要望を単純に解決することにフォーカスされている

3.将来を想像する

前項の通り、課題は山積みであったため、各課題に対してできる範囲(新規サービスの導入やシステム化・インテグレーションは後回し)で将来を見据えた改善を行う方針としました。

見える化定量化に向けた(KPI・KGI策定を見据えた)足固め

冒頭で記載したようにコーポレートIT領域というのは取り扱うサービスや技術が広く、様々なスキルセットが求められると言えますが、個々のPJやタスクサイズは小さいことが多々あります。 しかしながら、タスクサイズが小さいからと言って、個々のタスクを全て点で捉えて個別にクローズし続けるといつまで経っても組織運営が最適化されません。 この観点において、CO-ITチームでは将来の対応リソースの削減も見据え、タスクを定量化することに注力しています。

見える化定量化は多くの企業で実施されているかと思いますが、その粒度や精度については様々かと思います。 CO-ITチームも私が入社する前から全くできていないということではなく、粒度や精度に課題があったという話になります。

私が特に重要視しているのは提供サービス全体での体系化と最小限のリソースを目指す運用サイクルの構築になります。 この観点で言えば、CO-ITチームではまだまだ足固めが必要な状態であり、新規サービスの導入やSaaS間のインテグレーションを考えるフェーズにないと判断しました。 ですので、CO-ITチームではこの一年立ち止まって当たり前のことを実現できる最低限の準備を進めてきました(導入済みサービスはリプレース検討フェーズに移らず基本的に一旦継続利用して精査する)。その中のほんの一例が下記になります。

  • 資産管理の精緻化
  • 問い合わせ対応のワークフロー改善、見える化定量
  • 提供デバイスのラインナップ整理とユーザへのガイドライン提供
  • キッティング業務のワークフロー化
  • 備品貸与ガイドラインの策定
  • バイス提供スピードの向上、提供コストの削減
  • 入退社復職休職のような人事イベントに伴うアカウントフローの整理
  • 社内手続き・稟議の整理
  • サービスの保守期限の統一、サポート窓口の整理
  • ナレッジ共有方法の統一、ナレッジの質・量の向上

業務改善の話(SaaSのインテグレーションだけが全てじゃない!)

採用業務で様々なエンジニアの方とお話する機会があるのですが、コーポレートエンジニアを目指されている方には「業務改善」にやりがいや面白さを強く感じられていて、プログラミングを行って自動化処理の仕組みを作ることが全て(若干誇張していますが・・・)という志向をお持ちである方(そういった印象を受ける方)にお会いすることがあります。確かにコーポレートエンジニアの業務の中でSaaSのインテグレーションというのは、より技術的な要素が強く自身の満足につながる、かつ他の方(特に非エンジニア職の方)からの評価が高くなる傾向がありますので合理的ではあります。

しかしながら、一度立ち止まって以下の質問に向き合うことも必要ではないでしょうか。

  • 本当にシステム化、自動化することだけが正なのでしょうか?
  • 本当に自動化することでコストは下がっていますでしょうか?

参考:運用自動化、不都合な真実

CO-ITチームでは、SaaS運用だけでなく全てのコーポレートIT領域に含まれるサービスにおいて業務改善を行うことが必要であり、実現する方法(コードを書くことが全てではない)に優劣はなく、アウトプットに対する評価は常にフラットでありたいと考えています。例えば、CO-ITチーム内の一例を紹介させていただきますが、以下のような対応も十分一つの業務改善であり、同等に評価されるものと考えています。

業務改善の一例

  • 左側の写真:会議室のモニタスタンドを壁寄せモニタで可動式に変更
    • レイアウト変更を容易にするという要件の充足と机上スペースの拡張を実現
  • 右側の写真:管理するサーバルーム内の棚に共通の収納ボックスを導入
    • 備品管理を最適化(必要な備品に最短でアクセスできる導線の確保とコストの最適化)

サービス導入・施策を開始することについて考える

CO-ITチームではこの一年立ち止まって足固めをしているため主だった新規サービスの導入は見送っている(他にもっとやるべきことが多い)のですが、新規サービスの導入(リプレース含む)業務に魅力を感じるエンジニアの方は多いのではないでしょうか。逆に既存のブラックボックス・複雑化した環境を考慮して体系的に再整理するような業務は(やりたくないとは口には出さないものの)敬遠される傾向が多いように感じます。

この傾向は、自身の直接的なスキルアップや評価へのつながりやすさに起因するものと思います。加えて、ゼロベースでの設計難易度に比べ、複雑な既存環境の再設計は難易度が非常に高く、ボリュームが大きくなる割にはアウトプットが(新規サービス導入に比較すれば)地味になります。また、実際に稼働しているサービスの場合が多く、放置してもスポットでは課題感が多少あるかもしれないが何とかやり過ごせることが多いことも要因の一つにあるように感じます。

ビジネス書(amazonのすごい会議)の中にもまさに同じような視点のコラムが掲載されていましたのでご紹介させていただきます。 PDCAサイクルにおいてAmazon社ではPDだけの人(立ち上げ屋[企画業務])は重視されないが、日本企業ではPDが重視されがちというものです。まさにコーポレートIT領域でも同じように感じます(下記のような状態です)。

  • サービス導入することにだけ大きなコスト・アテンションが払われる*11
  • 導入担当者の主観・感覚のままローンチされることがある
  • 肝心の設計・設定・運用はレビューが薄い*12
  • 問題が顕在化した後に再設計を検討する(再設計の中心人物がヒーローになる。。。) *13

CO-ITチームでは、近い将来新規サービスの導入を必要に応じて行いますが、上記のような課題が残らないようなPJ運営を行うつもりですし、一部の声の大きなメンバー*14だけが新規サービス導入に携わるような組織にならないよう最適な仕組みづくりを日々模索していきます。

チームの安定した運営を考える

チーム運営を安定化するポイントとしては、システム化(人に依存しない運用を構築する)やリソースの安定化(メンバーの頻繁な入れ替わりを防ぐ)といったことが挙げられます。前者については各所で述べられているように感じますが、後者はそれに比較すると情報量が少ない印象です。ここでは後者について深掘りします。

各種サービスのシステム化・自動化が非常に重要であることは自明ですが、それ以上にリソースの安定化は非常に重要です。以下にチームメンバー入れ替わりに関するデメリットを整理してみます。

  • 一時的にリソース不足に陥る
  • 新規メンバーの採用コストが必要となる
  • 新メンバーの立ち上がりに1ヶ月〜半年程度を見込む必要がある

では、逆にメリットがないかと言えばそうではなく、以下のようなチームに新陳代謝が起こるメリットはあります。

  • 旧メンバーより更に良い人材がチームに加入するかもしれない
  • これまで慢性化や形骸化していた業務に良い影響を与えるかもしれない

しかしながら、安定したリソースでの運用を目指す方がチームとしての総合戦闘力は高いと感じますし、各自のスキルアップやチームの新陳代謝はチーム運営方法によりカバーできるものと考えますので、メンバーの不要な入れ替わりは避けたいものです。メンバーが離脱する理由を考えると、

  1. 待遇面(給与やワークライフバランス[会社の規定])の問題
  2. 会社や部署方針との根本的な価値観の不一致
  3. 会社の業績、業種の市場動向
  4. ジョブチェンジを目指す、またはプライベートな問題
  5. 部署内でのコミュニケーションの問題
  6. 志向の問題(自社ではスキルアップが見込めないと感じる)
  7. 足元の担当業務の問題(同じ業務ばかり、丸投げばかりされる、不公平感を感じる)

といったところでしょうか。 この中で1-4まではチーム運営ではどうすることもできないものになりますが、5-7を理由にメンバーの入れ替わりが発生するというのは、当該チームのマネージャやリード担当者に責任があると感じますし、こういった理由が発生しないよう常に改善を続ける必要があります。CO-ITチームでは、将来的なチームの安定運営を目指すために日々 カイゼン に向き合っています(具体的な話は機会があれば・・・)。

終わりに

今回は具体的なサービスの設計や設定内容、サンプルコード等のご紹介にフォーカスできませんでしたが、CO-ITチームの将来に向けた足固めは着々と進みつつあります。 来年以降ようやく新規サービス導入や施策などのコーポレートITサービス拡充をスコープとしていくフェーズを見込んでおりますので、(個人的には)ようやく楽しい業務にリソースを大幅に割けるタイミングとなります。

2023年12月現在、一緒にコーポレートITを推進いただける方を募集中です。 上記チーム運営に共感いただける方や同じような視座で物事を捉えられる方とともに一緒に当社のコーポレートITを作っていけることを楽しみにしています♪

今回の記事は以上になります。 最後まで読んでいただき、ありがとうございました。


株式会社エニグモ すべての求人一覧

hrmos.co

*1:当社でも数年前まで「情シス」というワードが各所で用いられていましたが、少なくとも私が入社後は意図的に情シスというワードは使用せず、コーポレートITという表現を使用するようにしています。

*2:私個人の視点ですが当社はフラットな環境に感じます。

*3:当然ベンダーには自社の独自要件を踏まえたオーダーメイドの最適な設計でチューニングを行うように追加コストを支払う

*4:CO-ITチームの場合、マネージャと私の方向性が元々大枠で一致していたことと、経営陣とマネージャが既に同様のコミュニケーションを行っていたことで非常にスムーズにすり合わせが完了しています。企業によっては、このすり合わせが非常に難航し、そもそもすり合わせせずに実務に移ることがありますが、後々重大な課題につながるのでオススメできません。

*5:あくまで目安であり、ピラミッドのベースにある項目が頂点にある項目に劣るというような優劣は全くありません。全ての項目がコーポレートIT領域には重要です。また、これは一般的に定義されたものではなく、私自身の経験その他から表現したものとなりますので一意見としてご理解ください。

*6:8時間 × 20営業日 × 12ヶ月 × 4名

*7:ミッションサイズは、全社共通の指標があり、入社時を含め半期毎に行われる評価によって適宜決定されます

*8:あくまで私の個人的な意見ですが、業務として責任を負っている(報酬(給与)を獲得している)以上は合理的な説明責任があります(定量化することは必要です)。

*9:SE費¥50,000/人日 × 0.5人日[0.125人日 × 4名]

*10:チームは同じMissionに向き合っているため、各タスクを項目分けすることはあってもブラックボックス化しない(隠さない)。各メンバーのValueをそれぞれが参考にしたり、評価するために必須。

*11:導入すること自体にバリューはなく、そのサービスで何を実現するかにバリューがある。

*12:マネージャやリードエンジニアは、実担当でなくても高い視座でシステムの重要トピックや仕様を明確化してレビューを行う必要がある

*13:そもそも新規導入時の考慮不足・レビュー不足に起因して問題が発生する場合が多い。問題が発生する前にチームで再設計が議論され、バックログ化されているのが正しい運営であり、ヒーロー(救世主)のような特定個人のスキルセット頼みになるのは問題です。

*14:誤解を恐れずに記載すると、いいとこ取りだけして面倒事は他メンバーにぶん投げるような自分本位のようなメンバーのことを指しますが、業務への慣れ等によって知らず知らずの内に意図せずそのような振る舞いになることもあるかもしれません。お互いリスペクトし合える組織を目指したいものです。

Rails7でHotwireのTurboを使う

こんにちは、エンジニアの太田です。

この記事は Enigmo Advent Calendar 2023 の16日目の記事です。

はじめに

TurboはRails7からデフォルトで搭載されており、VueやReactなどjavascriptの記述が必要だったDOMの更新をjavascriptを(あまり)書かずに実現させてくれます。 フロントエンドにあまり触れない方にとっては、SPA風のwebアプリへのとっつきやすさが出たと思います。
本記事では、私が初めてTurboに触れて使い方を覚える際に作成したサンプルの一部と使った感想を備忘録的にまとめたものになります。
各公式ドキュメントでも使い方を確認できます。
Rails で JavaScript を利用する - Railsガイド *1
Turbo Handbook *2

サンプルコード

以下は私が主に使用した形です。 ransack*3とkaminari*4を使ったリストの更新と追加・編集・削除をしてみます。

controllers

class CountriesController < ApplicationController
  def index
    @q = Country.ransack(params[:q])
    @q.sorts = 'name asc'
    @countries = @q.result.page(params[:page])

    # Request HeadersにTurbo-Frameが設定されているとpartialがreturnされて、
    # 対象の要素がpartialに置換される
    if turbo_frame_request?
      render partial: 'list', locals: { countries: @countries }
    end
  end

  def show
    @country = Country.find(params[:id])
  end

  def edit
    @country = Country.find(params[:id])
  end

  def create
    @country = Country.create!(country_params)
  end

  def update
    @country = Country.find(params[:id])
    @country.update!(country_params)
  end

  def destroy
    @country = Country.find(params[:id])
    @country.destroy!
  end

  private
    def country_params
      params.require(:country).permit(:code, :name)
    end
end

models

class Country < ApplicationRecord
  # ransackで検索項目にしたカラムを記載したのみ
  def self.ransackable_attributes(_auth_object = nil)
    %w[name]
  end
end

views

index.html.erb

# このフォーム内からのリクエストはヘッダーにTurbo-Frameを設定する
# レスポンスのpartialによってid属性がlistのturbo-frame要素が置換される
<%= search_form_for @q, html: { data: { turbo_frame: 'list' } } do |f| %>
  <div>
    <%= f.label :name_cont, 'name' %>
    <%= f.text_field :name_cont %>
  </div>
  <div>
    <%= f.submit '検索' %>
    <%= link_to 'リセット', countries_path, data: { turbo_frame: "_top" } %>
  </div>
<% end %>

<%= render 'list', countries: @countries %>

<%= render 'form' %>


_list.html.erb

# id属性がlistのturbo-frame要素
<%= turbo_frame_tag :list, autoscroll: true, data: { autoscroll_block: 'start' } do %>
  <ul id="countries">
    <li>
      <div>国コード</div>
      <div>国名</div>
      <div></div>
      <div></div>
    </li>
    <%= render countries %>
  </ul>
  <div>

    # turbo_frame_tag内は自動的に直近の親を対象としたTurbo-Frameのリクエストになる
    # なのでkaminariにTurbo用の設定は不要
    <%= paginate countries %>

  </div>
<% end %>


_country.html.erb

# id属性がcountry_{country.id}のturbo-frame要素
<%= turbo_frame_tag country do %>
  <div><%= country.code %></div>
  <div><%= country.name %></div>

  # 直近の親 (id属性がcountry_{country.id}のturbo-frame要素)が対象のTurbo-Frameのリクエストになる
  # edit.html.erbに置換される
  <div><%= button_to '編集', edit_country_path(country), method: :get %></div>

  # GET以外のメソッドではTurbo-Streamのリクエストになる
  # destroy.turbo_stream.erbの処理を実行
  <div><%= button_to '削除', country_path(country), method: :delete %></div>
<% end %>


edit.html.erb

# id属性がcountry_{@country.id}のturbo-frame要素
<%= turbo_frame_tag @country do %>
  <div>
    <%= form_with model: @country do |form| %>
      <%= form.text_field :code %>
      <%= form.text_field :name %>

      # 直近の親 (id属性がcountry_{@country.id}のturbo-frame要素)が対象のTurbo-Streamのリクエストになる
      # destroy.turbo_stream.erbの処理を実行
      <div><%= button_to '保存', action: :update %></div>
    <% end %>

    # GETメソッドなのでTurbo-Frameのリクエストになる
    # show.html.erbに置換される
    <div><%= button_to '中止', country_path(@country), method: :get %></div>
  </div>
<% end %>


show.html.erb

<%= render 'country', country: @country %>


update.turbo_stream.erb

# id属性がcountry_{@country.id}のturbo-frame要素をupdate後に置き換える
<%= turbo_stream.replace @country %>


create.turbo_stream.erb

# id属性がcountriesの要素の末尾に_country.html.erbを追加
<%= turbo_stream.append 'countries', @country %>

# 登録フォームを入力をリセット
<%= turbo_stream.replace 'register' do %>
  <%= render 'form' %>
<% end %>


_form.html.erb

# 登録フォームのid属性registerを設定しておく
<%= form_with model: Country.new, id: 'register' do |form| %>
  <div><%= form.label :code %><%= form.text_field :code %></div>
  <div><%= form.label :name %><%= form.text_field :name %></div>
  <div><%= form.submit %></div>
<% end %>


destroy.turbo_stream.erb

# id属性がcountry_{@country.id}のturbo-frame要素を削除
<%= turbo_stream.remove @country %>

turbo-frame

turbo-frameは画面内のturbo-frameタグを一つだけを対象として置換することができます。id属性必須です。
リストの更新が主な使用ケースでした。

turbo-stream

turbo-streamは画面内の複数要素をid属性で指定して対象とすることができ、それぞれに対して下記の7つの処理*5を実行できます。

  • 先頭追加
  • 末尾追加
  • 直前追加
  • 直後追加
  • 置換(対象要素含む)
  • 更新(対象要素含まず中身だけ)
  • 削除

この時、対象とする要素はturbo-frameタグではなくて普通のdivタグなども指定可能です。注意点はGET以外のリクエストにする必要があることです。
登録時にリストへ要素を追加すると同時にフォームをリセットするなどが主な使用ケースでした。フラッシュを表示したりで複数箇所の更新が必要になりがちなDB操作が絡むリクエストでの使用機会が多いと思います。

動きのイメージ

リストを更新
検索をリセットして初期化
編集フォームに置換
編集を保存して反映
編集をやめる
データを削除
データを登録

細かい話

Hotwireとは、Turboとは

下記の公式の説明やimport文からHotwireという開発アプローチがあって、それを実現させるためのパッケージにTurboというパッケージがあるという感じのようです。

Hotwire is an alternative approach to building modern web applications without using much JavaScript by sending HTML instead of JSON over the wire. *6

import * as Turbo from "@hotwired/turbo"

HotwireにはTurbo以外にもStimulusとStradaがあり、この三つの要素から成ります。 Rails7以降ではデフォルトでTurboとStimulusが使えるようになっています。

# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
gem "turbo-rails"

# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
gem "stimulus-rails"

ReactやVueとの違い

前述の公式説明には「without using much JavaScript by sending HTML instead of JSON over the wire.」とありますが、これがHotwireがReactやVueと異なるポイントです。
RailsでReactやVueを使う場合は、サーバサイドのrailsがcontrollerでデータをreturnし、そのデータを取得するようにクライアントサイドのReactやVueの実装をするかと思います。
一方でHotwireでは、上に挙げたサンプルコードのようにリクエストに対してcontrollerがHTML(render partial)をreturnするだけになります。
確かに、JavaScriptを使わずにJSONではなくてHTMLを送信するようになっています。

Turboを使った感想

ransackやkaminariといったviewsを構成するファイルに対するgemをそのまま使えて、わざわざフロントエンド用にnpm installとかしなくて済むのがとてもよかったです。
DOM更新はほとんどJavaScriptを記述しなくてもよかったのもあり、作業工数もそこそこ少なく済むのではないかと思います。
使いづらいところとしては、turbo-frameタグで全体を囲わなければならないのでスタイルの当て方が少し面倒になる場面がありました。cssフレームワークを使う場合は結構気を使う必要があるかもしれません。
また、各アクションでhtmlを返す必要があるので、必然的にviewsディレクトリのファイルが多くります。jsの記述が必要無くなった分という感じです
。 一般公開する大きなサービスではちょっと頼りなさそうな感じはしましたが、他の業務もしながら開発する社内ツールくらいの規模であれば十分なものだと思いました。


最後までご覧いただきありがとうございました。

明日の記事の担当は、コーポレートエンジニア(コーポレートIT[CO-IT]チーム) の横川さんです。お楽しみに!


株式会社エニグモ すべての求人一覧

hrmos.co

「心理的安全性」とソフトウエア開発

はじめに

こんにちは、株式会社エニグモの開発を担当しているグループでエンジニアリングマネージャーをしている後藤です。

この記事は Enigmo Advent Calendar 2023の15日目の記事です。

私は、開発グループでエンジニアリングマネージャーという役割をしています。この記事では、チームメンバーとの関わりの中で大切にしている「心理的安全性」についてポエムを書かせていただきます。

この記事の対象者

この記事の対象は、「心理的安全性」という言葉は聞いたことあるけどモヤッとしかわからないが大切そうだ、みんなが「心理的安全性」といっているから上っ面だけでも理解してドヤ顔をしたいという人を対象にしています。

この記事を通して、読者の方に「心理的安全性」がどうソフトウエア開発に影響を与えていると感じているのか、どうしたらソフトウエア開発チームにとって良い「心理的安全性」のある環境を作れるのかを自分で解釈する手助けになればと思っております。

あくまで、私の解釈ですのでこの記事を参考に自分の考え、理解を勧めていく手助けになれば幸いです。

因みに、私が思っている「心理的安全」なチームは以下のイラストのイメージです。

安心できるチーム

心理的安全性の定義とソフトウエア開発現場における私の理解

まずはじめに、「心理的安全性」という言葉ですが、Googleが発表した「成果を出すチーム」の条件に出てきて有名になったと理解しています。私もこの記事で知りました。それからずっとこの「心理的安全性」が引っかかっていました。

なぜならマネージャーと名のつく役割を担っている以上、「成果」を出すことを期待されています。それに、最も影響を与えるとなれば理解しないわけにはいきません。

ところがです、「心理的安全性(psychological safety)」について調べると、組織の中で自分の考えや気持ちを誰に対してでも安心して発言できる状態のこと、と出てきます。また、そのような環境を作るために、自分の病気のことを話したり、プライベートなことも話せる関係を作っていくと良いと結ばれていました。

そうなのかー、私には無理じゃん、というのが正直な感想でした。エンジニア上がりでエンジニア仕事大好きなどちらかというとコミュ障寄りの私にとって、プライベートな話をしたり雑談をしながらチームを作って行くなんてできっこないと思ったわけです。

それでも、この「心理的安全性」を放置しておくわけにもいかないですし、別にプライベートな事が話せる事が必須条件ではないだろうという思いもあり私なりに噛み砕いてみました。

心理的安全性」が低いとどんな問題があるのか

心理的安全性」を理解するにあたり、「心理的安全性」が低いとどんな問題があるのかを考えてみました。

いろいろあるのですが、私が考えている一番の弊害は、開発をしていて「この部分少し不安だ」、「あの部分、実は問題がある気がする」といった「もやっと」した気持ちを他のメンバーに伝えることができない、伝えることに抵抗がある、ということではないかと考えました。

なぜなら、「この部分少し不安だ」、「あの部分、実は問題がある気がする」という部分は、なぜだか本番にリリースするとかなりの確率でエラーが起きたりします。そして、分かっていた本人は心のなかで「やっぱりか!」と思いながら修正に追われるわけです。

この「もやっと」を事前に伝えられていれば、トラブル対応に追われるという状況を回避できたはずです。

この、少し不安だが確信が持てない、間違っているかもしれないけど、みたいな事を伝えられるチームである事が生産性に影響を与えるのではないかと考えたのです。

「もやっと」を伝えられるチームにするために何をしているのか

私達のチームでは、毎週金曜日にKPTフレームワークをつかって振り返りをしています。この場でこの「もやっと」を伝えられる雰囲気を作る事を心がけました。

そうはいっても、「もやっと」を伝えてくださいね、と言ってみたところで意見が出てくるわけではありません。

そのため、1on1で出てきた、困ったことや解決した事を、些細なことでも良いので週次の振り返りに上げてもらうよう伝えることを根気よく繰り返しています。また、私自身が見つけた問題や、解決した事も話すようにしています。

このような事を繰り返していくことで、小さな事でも伝えて良いんだ、という空気ができてくる。また他の人が伝えてくれた小さな事が役に立った!という経験の積み重で、「もやっと」を伝えていこうという空気が出てくるのではないかと思っています。

まとめ

ソフトウエア開発の現場で「心理的安全性」は、小さな「もやっと」を伝えられるか、に影響すると考えています。

この小さな「もやっと」を意識的に引き出していくことで、ソフトウエア開発で発生する問題の芽を早いうちに摘む事ができ、開発生産性を改善できるのではないかと考えています。

そのために、小さな発見を伝えられる場作りを大切にしています。

おまけ

週末に BIBLIOTHECA というラジオ番組を聞いていたら、この「もやっと」が伝えられないチームの状況を適切に表す言葉に出会いました。この状況は、「集団浅慮(しゅうだんせんりょ)」と呼ばれる状況と一致しているのではないかと思います。

「集団浅慮(しゅうだんせんりょ)」とは、優秀な人達が集まって議論した結果、とても残念な結論を出して大失敗するという状況です。

そのラジオ番組によると、過去にケネディ大統領がこの失敗に陥り、そこからどう改善していったのかという事が以下の本に書いてある、と紹介されていました。この本の中に、マネージャーとして気をつけるべきことが潜んでいるのではないかと思っています。もっとも、集団浅慮に陥りやすいのは強いカリスマ的なリーダーがいるとき、というのがあったのでその部分は当てはまらない気がしますが、今度読んでみたいと思っています。

一緒に働く仲間を募集しています!

株式会社エニグモでは一緒に働く仲間を募集しています。興味のある方は以下の求人をご参照ください。

株式会社エニグモ すべての求人一覧

hrmos.co

【コンバージョン数3倍増!!】HTMLメルマガの改修事例をご紹介します

こんにちは、デザイナーの細田です。
この記事はEnigmo Advent Calendar 2023 の 15日目の記事です。

日頃の業務ではBUYMAの様々なコンテンツのデザインを担当しています。
中でもHTMLメルマガのデザインに関しては、数年前から改修に携わるようになり、ABテストによるデザイン検証に取り組んできました。

今回はその中でも、改修によって、お問い合わせフォームへの流入数が前月比で140%増加し、本施策のコンバージョンとなるお問い合わせ数も約3倍に増えた成功事例をご紹介します。

改修前のデザイン

まずは、今回改修依頼を受けたメルマガの概要をご紹介します。

対象者

高額な商品を複数回閲覧しているユーザー

内容

BUYMAコンシェルジュ*1というサービスを紹介し、お問合せフォームへ誘導する

デザイン

このメールを見て、皆さんはどう感じましたか?

私は、「なんだか唐突だな」と感じました。

例えるなら、お店で洋服を見ていたら突然声をかけられ、 「なにかお探しですか?コンシェルジュへご相談ください」と名刺を渡され去っていく・・
そのような唐突さを感じました。この内容では、お問合せしてみようと思う人は少ないかもしれません。

それでは、どうすれば唐突な印象を解消し、BUYMAコンシェルジュというサービスに興味をもってもらえるのでしょうか。

改修後のデザイン

改修後のデザインは以下のようになりました。順番に解説していきたいと思います。

【💡POINT 1 】ヘッダーに送信理由を記載する

私が、メルマガにおいて1番重要だと感じていることは、受信者に“自分宛” と思わせることです。

メルマガは “チラシ” と ”手紙” の両方の役割を担っています。
サッと見てゴミ箱行きのチラシとなるか、じっくり読んで返事を書きたくなる手紙になるか。
それにはそのメルマガが無作為に送られたものではなく、“自分に宛てて送られたものである” と感じてもらえるかどうかが重要となります。

そのために有効な手段として、上記のようにヘッダーに “どういう理由でこのメールを送信したのか” を記載する、という方法があります。
今回であれば、「高額な商品をご検討中の方へ特別なご案内です。」と記載することで、受信者がなぜこのメルマガが自分へ届いたかを理解し、「自分宛だから見てみよう」と感じる可能性を高めることができます。

【💡POINT 2 】タイトルは1番伝えたいことを簡潔に

メルマガ内で1番目を引くタイトルには、そのメルマガで1番伝えたいことを簡潔に記載します。

改修前のタイトルでは、「お探しの商品は見つかりましたか?」とありますが、このメルマガで1番に伝えたい事はBUYMAコンシェルジュの紹介です。
そこで、改修後のデザインでは「BUYMAコンシェルジュがバイマ太郎様のお買い物をサポートいたします。」と変更しました。
そうすることで、「BUYMAコンシェルジュって何だろう?」と興味を抱いてもらうことができます。

また、タイトルに受信者の名前を挿入し強調することで(例ではバイマ太郎となっています)
【 POINT 1 】で取り上げた“自分宛である” ことの演出を、より一層強めることができます。

【💡POINT 3 】分かりやすい見出しで離脱を防ぐ

改修前のメルマガにはBUYMAコンシェルジュについての説明がなく、「そもそもBUYMAコンシェルジュってなに?」と受信者を戸惑わせてしまう可能性がありました。

そこで改修後のデザインでは、BUYMAコンシェルジュについての説明エリアを追加したのですが、重要となるのが見出しです。
今回は、「BUYMAコンシェルジュとは?」という見出しをかなり目立つ形で挿入しています。
こうすることで、BUYMAコンシェルジュの説明エリアであることを明示し、タイトルを見て「BUYMAコンシェルジュって何だろう?」と興味を示したユーザーの目線をそのまま説明へと誘導する役割を担っています。

これが見出しのない、ただの文章としてそこに配置されていた場合、
特にスマートフォンの小さい画面で見た時に、反射的に読み飛ばされてしまったり、「読むのが面倒だ」とメルマガ自体から離脱されてしまう恐れもあります。

しっかり読んでもらいたい文章を配置する時こそ、目立つ見出しで分かりやすく区切ったり、文章自体も極力簡潔にまとめるなどの、細かい気配りが必要となります。

【💡POINT 4 】ボタンはベタ塗りで視認性を高める

改修前はボーダーであったボタンを、改修後はベタ塗りに変更しました。

その理由は、BUYMA全体のデザインルールに合わせるという目的もあったのですが、
スマートフォンの小さな画面で見た時の視認性の高さが、やはりベタ塗りの方が圧倒的に高いからです。

また、最近ではメルマガをダークモードで閲覧しているケースも増えており、
ダークモードで見ると特に、ベタ塗りボタンの視認性の高さが顕著になります。

まとめ

以上のような改善を行った結果、BUYMAコンシェルジュのお問い合わせフォームへの流入数が前月比で140%増加し、本施策のコンバージョンとなるお問い合わせ数も約3倍に増えました。

弊社ではデザイン改修に加え、MAツールの導入により、コンテンツ内容のパーソナライズ化や、配信対象の最適化など、よりユーザー1人1人に寄り添ったメルマガ作成を行なっており、確実に成果を生み出しています。

今後も地道なABテストを積み重ねながら、このような成功例を蓄積し、発信していければと考えています。


株式会社エニグモ すべての求人一覧

hrmos.co

*1:BUYMAコンシェルジュとは、特別なお客様限定の招待型プライベートサービスです。ご希望商品のお探しからお取引の相談まで、BUYMAのご利用に関するあらゆるサポートを専任のコンシェルジュが行なっています。

自社サービスで必ず達成しておきたいウェブアクセシビリティ対応についてまとめました

こんにちは。株式会社エニグモにてフロントエンドエンジニアを務めています新井です。

こちらは Enigmo Advent Calendar 2023 および アクセシビリティ Advent Calendar 2023 の 14 日目の記事です。

はじめに:ウェブアクセシビリティとは?

X(旧 Twitter)や各種テック記事などを見ていると、多くの人がウェブアクセシビリティを、障がいを持つ人々、特に視覚障がいのある人々への配慮として認識しています。

これは正しい認識の一部ではありますが、ウェブアクセシビリティの範囲はもっと広いです。実際には、全ての年齢層や様々な身体的、精神的条件を持つ人々が、多種多様な環境下でウェブサイトやアプリケーションを利用可能にすることを目指しています。

障がいがない人も、健康問題、マウスやトラックパッドの故障、音声再生の不可能な環境など、様々な状況に直面することがあります。ウェブアクセシビリティとは、これら多様なユーザーがウェブサイトやアプリケーションを容易に利用できるように設計することを意味します。

この記事では、ウェブアクセシビリティを向上させるための重要な10の項目を紹介します。私たちが運営するショッピングサイト「BUYMA」も今年からアクセシビリティへの取り組みを進めており、これらの項目を今後達成することを目指しています。

1. ページ内の見出しの最適化

具体的にはページ内で使用されている h1〜h6 タグを、階層構造の深さに応じて最適化します。

多くの方が見出しの最適化と聞いて SEO の改善を連想するのではないでしょうか?実際に、見出しの整理が SEO に好影響を及ぼすことはあるかもしれません。しかし、もっと注目すべきなのは、この最適化が SEO のみならずアクセシビリティにも大きく貢献するということです。

スクリーンリーダーなどの支援技術を利用するユーザーは、見出しを通してページ全体の構造を理解します。また、見出しジャンプ機能を使って必要な情報に素早くアクセスすることもあります。WebAIM のアンケートによると、約 7 割のユーザーが見出しジャンプ機能を使用しているとのことです。

webaim.org

見出しを用いてウェブサイトの情報構造を適切に整理することで、ユーザーが情報を迅速に理解できるようになります。

Google Chrome拡張機能Web Developer」を使用することでページの見出しのアウトラインを可視化することができます。見出しレベルを視覚化して検証することで、ページの構造が明確になり、改善点を見つけやすくなります。見出しの正確さや一貫性を確認するために、見出しレベルは可視化して検証することをおすすめします。

参考:達成基準 2.4.6: 見出し及びラベルを理解する

2. リンクや状態の判別を色の変化だけで行わないようにする

リンクや状態(フォーカスやホバーなど)の判別を色のみでデザインしてしまうと、色覚異常を持つユーザーにとって判別が困難になる可能性があります。 この問題に対処するためには、色だけでなく形状やその他のビジュアル変化を用いて区別ができるようにすると良いでしょう。

具体的な対策としては次のようなものがあります。

  • テキストリンクは色の変更に加えて、下線を表示する
  • 状態が変化する際に、アイコンを変更する
  • ボタンがホバーされた時は、背景色を変えるだけでなく枠線も表示する

特にホバーの状態は、透明度の変更のみでデザインされることが多いので、デザイナーと協力して状態の変化が明確に分かるデザインを作成することが望ましいです。

また、以下の CSS コードをデベロッパーツールで適用することで、ウェブサイトをグレースケールに変換し、色に頼った UI がないかどうかを検証するのに役立ちます。

body {
  filter: grayscale(1);
}

BUYMAのトップページをデベロッパーツールでグレースケールにしたサンプルです

ただし、濃い赤のような色はグレースケールへの変換では確認しにくい場合があるため、検証のコストとのバランスを考慮しながら、色覚特性のタイプごとに見え方をシミュレーションすることも有効かもしれません。

参考: 達成基準 1.4.11: 非テキストのコントラストを理解する

3. キーボード操作時のフォーカスインジケーターは非表示にしない

リンクやボタンがクリックされた際に表示されるフォーカスインジケーターは、しばしばデザイン上の理由で非表示にされがちです。しかし、フォーカスインジケーターを非表示にしてしまうと、キーボードでウェブサイトを操作するユーザーはコンテンツの利用が困難になってしまいます。

クリック時のフォーカスインジケーターを非表示にしつつ、キーボード操作時のフォーカスインジケーターを維持するには、以下のような CSS をベースで指定しておくと良いでしょう。

:focus:not(:focus-visible) {
  outline: none;
}

:focus-visible 擬似クラスはキーボード操作によりフォーカスされた場合に適用され、マウス操作によりフォーカスした場合には適用されません。

もしサイト内に複数の CSS が読み込まれ、各要素に outline:none が適用されているような場合、以下のような CSS を指定することでキーボード操作時のフォーカスインジケーターを復活させることができます。

@layer focus {
  :focus-visible {
    outline: revert;
  }
}

この方法では、Cascade Layers という機能を用いて優先度を高めています。 このスタイルは ID セレクタで定義されたスタイルよりも優先されますが、インラインスタイル( style 属性)や !important 指定されたスタイルよりは優先度が低いため、 !important を使用するよりも安全です。 ただし、 outline プロパティを上書きする場合は新たに @layer を設けて上書きする手間があるので、あくまで応急処置として扱うのが賢明です。 Cascade Layers は、現在すべてのモダンブラウザで使用可能です。

さらに、フォーカス時の状態をより分かりやすくするために、インジケーターに加えてホバー時のスタイルも適用しておくとフォーカスの判別がよりわかりやすくなります。

.button:focus-visible {
  /* ホバー時のスタイル */
}

@media (hover: hover) and (pointer: fine) {
  .button:where(:any-link, :enabled, summary):hover {
    /* ホバー時のスタイル */
  }
}

タッチデバイスでのホバーは動作に支障が出る場合があるため、hover メディアクエリを利用してタッチデバイスでのホバーは無効化しておくと良いでしょう。

参考:達成基準 2.4.7: フォーカスの可視化を理解する

4. クリッカブルな要素の実装には a タグまたは button タグを使用する

クリッカブルな要素を div タグや span タグを用いて実装すると、支援技術を使用するユーザーやキーボード操作に依存するユーザーがその要素を選択できなくなることがあり、結果としてコンテンツのアクセシビリティが損なわれる可能性があります。

リンクは a タグを、ボタンは button タグを使用して、適切にマークアップしましょう。支援技術は a 要素を「リンク」、button 要素を「ボタン」と読み上げます。

既存のコードで a タグや button タグに変更するのが難しい場合、tabindex 属性と keydown イベントを使ってクリッカブルな振る舞いを実装することができます。以下は、BUYMA で使用されている React のコードの一例です。

<tr
  key={item.id}
  className="catalogs-table__row"
  onClick={() => handleSelectItem(item)}
  onKeyDown={(e) => {
    if (e.key === "Enter" || e.key === " ") {
      // Enter or Space で実行
      handleSelectItem(item);
    }
  }}
  tabIndex={0}
>
  ...
</tr>

このコードでは、tr要素に onClick イベントと onKeyDown イベントが設定されており、tabIndex={0}によってキーボード操作で選択可能になっています。

5. 画像の代替テキストの指定と装飾的な画像の取り扱い

原則的にコンテンツ上意味のある画像には必ず代替テキストを指定し、装飾的な画像は読み上げしないようにします。

img 要素の代替テキストは alt 属性で指定します。

<img alt="BUYMA" src="logo.png" width="130" height="25" decoding="async" />

アイコンフォントや SVG 要素に代替テキストを指定する際には、role="img" と aria-label 属性を併用して指定します。span や div、svgaria-label を指定すると、支援技術によっては適切に読み上げられない場合があります。また、 span や div の暗黙のロールが WAI-ARIA 1.2 より generic となったことで aria-label を付与するのは仕様違反となっています。安定した読み上げを確保するためにも、必ず role="img" を指定しましょう。

<span role="img" class="fab-icon fab-icon-facebook" aria-label="Facebook"></span>
<svg role="img" aria-label="X" viewBox="0 0 20 20"></svg>

装飾的な画像として img 要素を使用する場合は、alt 属性を空にします。alt 属性を省略すると、支援技術は URL を読み上げる可能性があります。

<img alt="" src="crown.svg" width="20" height="20" decoding="async" loading="lazy" />

装飾的なアイコンフォントや SVG 要素は、読み上げから除外するために aria-hidden="true" を指定します。

<span class="fab-icon fab-icon-information" aria-hidden="true"></span>
<svg aria-hidden="true" viewBox="0 0 20 20"></svg>

代替テキストの作成時には、画像が伝える情報を正確かつ適切にユーザーに届けることを心掛けるようにします。また、画像に関連しない情報をSEOのために加える行為はNGです。代替テキストはコンテンツの重要部分であり、他のテキストと同様、コンテンツ設計の初期段階で検討すると良いでしょう。

さらに、意味を持つ画像は CSS の background-image を使って背景として設定しないようにします。背景画像として設定してしまうと、支援技術を使用するユーザーが画像を認識できなくなります。また、background-image は loading 属性や decoding 属性を指定できないため、ウェブサイトのパフォーマンスに影響を及ぼす可能性があります。

参考:達成基準 1.1.1: 非テキストコンテンツを理解する

6. フォームコントロールには必ずラベルを付与する

フォーム内の入力欄やテキストエリア、セレクトボックス、チェックボックスラジオボタンなどのフォームコントロールには、label 要素を使って明確にラベルを付けるようにします。

label 要素の使用にはアクセシビリティの観点から大きな利点があります。フォームコントロールにフォーカスが合わされた際に要素の名前を読み上げることが可能になり、またクリックやタップの範囲が広がり、利用しやすくなります。

フォームコントロールとラベルを関連付ける方法としては、ラベルとフォームコントロールを label 要素で包むか、フォームコントロールの id 属性を label 要素の for 属性に紐付ける方法があります。

<label>
  ニックネーム
  <input type="text" name="nickname" />
</label>
<label for="nickname">ニックネーム</label>
<input id="nickname" type="text" name="nickname" />

デザイン上、フォームコントロールのラベルが UI 上に表示されていない場合でも、支援技術利用者のために aria-labelledby 属性や aria-label 属性を使用してラベル付けを行うことが望ましいです。

aria-labelledby 属性を使用した例

<form>
  <p id="keyword_label" style="display: none">検索キーワード</p>
  <input type="search" name="keyword" aria-labelledby="keyword_label" />
  <button>検索</button>
</form>

aria-label 属性を使用した例

<form>
  <input type="search" name="keyword" aria-label="検索キーワード" />
  <button>検索</button>
</form>

また、ラジオボタンチェックボックスなど、複数のフォームコントロールが意味的に一つのグループを形成する場合、fieldset 要素を使用してこれらをグループ化するようにします。この方法を採用すると、支援技術を使用してフォームコントロールを操作する際に、そのコントロールが属するグループの名前も読み上げられるようになります。

以下は、fieldset 要素を使用してラジオボタンをグループ化した例です。性別のコードは ISO 5218 で定められたものに従っています。

<fieldset>
  <legend>性別</legend>
  <ul>
    <li><label><input type="radio" name="gender" value="1" /></label></li>
    <li><label><input type="radio" name="gender" value="2" /></label></li>
    <li><label><input type="radio" name="gender" value="9" />その他</label></li>
    <li><label><input type="radio" name="gender" value="0" />不明・回答しない</label></li>
  </ul>
</fieldset>

また、ラベルをプレースホルダーで代用するUIも時折見かけますが、以下の観点から避けたほうがいいでしょう。

  • 記入時にラベルが消えてしまうためユーザーの短期記憶に負荷をかけることとなる
  • フォームの送信前にユーザーがどの項目に何を書いたのか判別できなくなる可能性がある
  • キーボード操作でフォーカスが当たるとラベルが消えることによる利便性の低下

参考:達成基準 2.4.6: 見出し及びラベルを理解する

7. フォームの入力欄のオートコンプリートを有効にする

オートコンプリートを有効にすることにより、ブラウザに保存された補完機能を利用できるようになり、結果としてユーザーは素早くフォームの入力を完了することができます。

<label>
  電話番号
  <input type="tel" name="tel" placeholder="(例) 090-0000-0000" autocomplete="tel" pattern="\d{2,4}-?\d{2,4}-?\d{3,4}" title="電話番号は正しく記入してください" />
</label>

サービス内でよく使用する autocomplete 属性の値は以下の通りです。

補完する要素
on autocompleteを許可する
off autocompleteを許可しない
name 氏名
given-name ファーストネーム(名前)
additional-name ミドルネーム
family-name ラストネーム(名字)
tel 電話番号
email メールアドレス
username ユーザー名orアカウント名
postal-code 郵便番号
address-level1 都道府県
address-level2 市区町村
address-level3 町域
address-level4 番地など
organization 企業・団体・組織名
cc-name クレジットカード登録名
cc-number カード番号
cc-exp カードの有効期限

多くのサービスでは、電話番号やクレジットカード番号などでオートコンプリート属性を活用します。一部の UI デザインでは、電話番号やクレジット番号の各部分を別々の入力欄で要求することがありますが、これは単に使いにくいだけでなく、オートコンプリートの利用を妨げる可能性があるため、デザイナーはこれらの情報を一つの入力欄で収めるよう配慮すると良いでしょう。

8. ラジオボタンチェックボックスを装飾する際は元の input の隠し方に気をつける

display:nonevisibility:hiddenされている input はキーボード操作でのフォーカスが不可能になってしまうため、ラジオボタンチェックボックスを装飾する際は別のアプローチで隠すようにしましょう。

<label class="checkbox">
  <input class="checkbox__input" type="checkbox" />
  <span class="checkbox__icon" aria-hidden="true"></span>
  <span class="checkbox__text">規約に同意する</span>
</label>
.checkbox__input {
  height: 1px;
  opacity: 0;
  position: absolute;
  width: 1px;
  z-index: -1;
}

さらに、装飾されたチェックボックスラジオボタンがフォーカスされた際には、その状態がユーザーに明確に認識できるようにしましょう。 以下の CSS は、フォーカスされた際にチェックボックスの周りにアウトラインを表示し、関連するテキストを下線で強調する方法の例です。

.checkbox__input {
  height: 1px;
  opacity: 0;
  position: absolute;
  width: 1px;
  z-index: -1;
}

.checkbox:has(.checkbox__input:focus-visible) {
  outline: 1px solid blue;
}

.checkbox__input:focus-visible ~ .checkbox__text {
  text-decoration: underline;
}

9. アコーディオン UI は可能な限り details 要素を利用する

アコーディオン UI を details 要素で実装すると、非アクティブな要素内のテキストもページ内検索で見つけることができ、キーボード操作や支援技術によるナビゲーションも可能になります。さらに、JavaScript を使わないためパフォーマンスが向上し、JavaScript が動作しない場合でもアコーディオンが利用可能になります。

<details>
  <summary>見出し</summary>
  <p>コンテンツ</p>
</details>

例えば、BUYMA ではスマートフォン表示のフッターメニューに details 要素が使用されています。

BUYMAでdetails要素が取り入れられているサンプルです

ただし、jQuery の slideToggle のようなアニメーション効果を追加したい場合、閉じる際に CSS の transition が効かないため別途 JavaScript が必要になります。

余談ですが、jQuery の slideToggle のようなアニメーションを実装する際、現代では折りたたむ要素に display: gridtransition: grid-template-rows .3s ease-out (所要時間とイージングはお好みで調整してください) を指定し、 開閉時に grid-template-rows の値を 0fr ↔ 1fr に変更するだけで対応が可能です。

参考:detailsとsummaryタグで作るアコーディオンUI - アニメーションのより良い実装方法 - ICS MEDIA

10. モーダル表示時は背面のコンテンツを読み上げ・選択不可能にする

モーダルコンテンツ(ダイアログやドロワーメニューなど)が表示されている際には、背後にあるコンテンツがキーボードや支援技術からアクセスされないよう設定します。

背面コンテンツに inert 属性を付与することで実現できます。inert 属性があると、ブラウザはその要素に対するユーザーの入力イベント(フォーカスイベントや支援技術からのイベントを含む)を無視します。

<body>
  <div id="wrapper" inert>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </div>
  <div role="dialog" aria-modal="true" aria-labelledby="modal_1_title" tabindex="-1">
    <h2 id="modal_1_title">モーダルタイトル</h2>
    <p>モーダルコンテンツ</p>
  </div>
</body>

inert 属性は多くの現代のブラウザで利用可能ですが、未対応の環境での使用を検討している場合は、Polyfill が利用可能です。

www.npmjs.com

参考:HTMLElement: inert プロパティ

おわりに:BUYMA でウェブアクセシビリティを促進する理由

ウェブアクセシビリティを考慮することにより、サービスをより広範なユーザーに提供することが可能になります。これにより、アクセシビリティの問題からサービスの利用を諦めていた人々を取り戻し、機会損失を防ぐことができます。

さらに、使いやすいサービスを提供することで、全体的なユーザー体験を向上させることにもつながります。

弊社では、アクセシビリティチャンネルを Slack で設立し、アクセシビリティに関する Redmine チケットを作成するなど、取り組みを進めています。まだ完全に対応しきれていない部分は多いですが、近い将来、これらの「必ず達成しておきたいアクセシビリティ対応」を実現する目標に向けて努力を続けています。

明日の記事の担当は SELL チームの後藤さんです。お楽しみに!


株式会社エニグモ すべての求人一覧

hrmos.co