学ぶ、考える、書き出す。
tag:blog.kubosho.com,2014:feed
kubosho
2023-12-15T04:54:57.412Z
2022年の振り返り
tag:blog.kubosho.com,2022-12-31:entry://2022
<p>今年は良くも悪くも某国際球技イベントに振り回された年だった。</p>
<h2>仕事</h2>
<p>社内のエキスパート認定制度で実績としてはまだ足りないけど、これからに期待というポテンシャル枠としてNext Expertsというのに選ばれた。分野としてはアクセシビリティとなる。見習いエキスパート枠に選ばれたことを記念して(?)自社のオウンドメディアでも<a href="https://www.cyberagent.co.jp/way/list/detail/id=27588">インタビューを受けた</a>。</p>
<p>またウェブアクセシビリティ基盤委員会(WAIC) 作業部会2(実装)の委員になったのも2022年の始めのほうだった。</p>
<p>このように社内・社外に向けてアクセシビリティ向上を推進していく立場になったもの、アクセシビリティ向上を社内・社外で推進できたかというと、2022年前半はある程度社内でアクセシビリティ向上に向けた活動をできたが、それを継続する活動はできなかった。また社外に発信するのも5~7月に集中してやったが、それ以降は継続しなかった。</p>
<p>継続できなかった理由としては<a href="https://developers.cyberagent.co.jp/blog/archives/40544/">2022年、サイバーエージェントのアクセシビリティを振り返る | CyberAgent Developers Blog</a>に書いた通り、「ビジネスへの貢献があると認められて経済合理性がある状態」にできなかったので自分が推進しないといけない状態になったからだと考えている。</p>
<p>そして2022年の後半は某国際球技イベントに向けて活動していた。大変だったしいろいろ無になったときもあって異動や転職を考えた時期もあった。ただ某国際球技イベントをとても多くの人が楽しんでいるのを見て嬉しくなるとともに頑張ろうと思った。</p>
<p>2023年からはよりプロダクトに近いところで活動するので、その活動を通じてアクセシビリティ向上の経済合理性を証明したいと考えている。</p>
<h2>プライベート</h2>
<p>今年の大きな出来事は<a href="https://blog.kubosho.com/entries/i-entered-kua">京都芸術大学(KUA) 通信教育部芸術学部デザイン科イラストレーションコースに入学した</a>ことだった。</p>
<p>ただ仕事やゲームなどでイラストを描くことに対して優先度が下がったり、2022年の後半になるにつれて精神的に辛い時期も増えたり、学校のコミュニティに馴染めなかったりした結果、2022年中は単位を取れずなんのために入学したのか分からない感じになった。自分のお金が無駄になっただけなので人には迷惑かけていないけど。</p>
<p>イラストに対する熱も一段落してしまった感覚がある。大学の授業という形式でイラストを学ぶのに慣れなかったのもあるし、そもそも授業を受けるための力が不足していると感じたので、一旦休学してもう一度本などを見つつイラストを練習したいなと考えている。</p>
<p>あと2022年後半は副鼻腔炎らしき症状で数日ダウンすることを2回やった。どちらも長期休暇中にダウンしていたので仕事にはあまり影響が出なかったものの、長期休暇中にどこにも出かけられない感じになって悲しかった。ただ新型コロナウイルスには罹ってないと判定されたのは良かった。</p>
<h2>まとめ</h2>
<p>2023年は継続することを増やす1年にしたい。</p>
今年は良くも悪くも某国際球技イベントに振り回された年だった。
2022-12-31T16:24:08.000Z
2023-04-02T04:10:09.000Z
サウナで整ったけど危険性も感じた
tag:blog.kubosho.com,2022-12-19:entry://sauna
<p>サウナで整う状態を初体験したけど、体験してみてこれは身体にとって危ないやつだと思った。</p>
<p>サウナへ7〜8分ほど入った後、水風呂に1〜2分ほど入るのを2度やった時、2度目の水風呂のタイミングで身体の周りに熱の膜が張られている感覚があった。</p>
<p>これがよく言われるやつかと思った後に水風呂から出たら、平衡感覚があまり無くなって壁伝いでないと歩けなくなった。</p>
<p>なんとか椅子までたどり着いて座ると視界がくるくるするような感覚があった後、身体の血行が良くなる感覚があって、その後に頭がスッキリして疲れが取れるような感覚があった。</p>
<p>この一連の流れは心地良さがあって、これが「整う」ことかと感じた。</p>
<p>しかし椅子に座るまでの平衡感覚の失い方や血の巡りが急に良くなった感覚などを考えると、明らかに血管に対してダメージを与えていると考えてしまった。</p>
<p>言ってしまえば「整う」のは自分の寿命を多少犠牲にして超回復するような代物ではないかと考えた。</p>
サウナで整う状態を初体験したけど、体験してみてこれは身体にとって危ないやつだと思った。
2022-12-19T09:11:24.000Z
2022-12-19T09:11:24.000Z
eslint-plugin-importによってVitestの設定ファイル上でエラーが発生する場合がある
tag:blog.kubosho.com,2022-11-23:entry://eslint-plugin-import-error-on-vitest-configuration-file
<p><code>vitest</code> と <code>eslint-plugin-import</code> に依存している環境では、vitest.config.ts内で <code>vitest/config</code> をインポートすると <code>Unable to resolve path to module 'vitest/config'. eslint(import/no-unresolved)</code> というエラーが出る場合があります。</p>
<p>これはnode_modules/vitest以下にconfig.d.tsだけがある状態で、config.jsの実体はdist/config.jsにあることが元で発生するようです。ディレクトリ構造を示すと次のようになります。</p>
<pre><code>/node_modules/vitest
|-- dist
| |-- config.cjs
| |-- config.d.ts
| |-- config.js
`-- config.d.ts
</code></pre>
<p>vitest/config.d.tsの内容はvitest/dist/config.jsでexportしているものをそのままexportしています。</p>
<pre class="language-typescript"><code class="language-typescript"><span class="token keyword module">export</span> <span class="token exports"><span class="token operator">*</span></span> <span class="token keyword module">from</span> <span class="token string">'./dist/config.js'</span>
</code></pre>
<h2>解決方法</h2>
<p>ESLintの設定ファイルで <code>import/resolver</code> 内の <code>node.extensions</code> の値に <code>d.ts</code> を追加すると <code>d.ts</code> 内のモジュール読み込みが解決できるようになり、ESLintの <code>import/no-unresolved</code> のエラーが無くなります。</p>
<pre class="language-javascript"><code class="language-javascript">settings<span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token string">'import/resolver'</span><span class="token operator">:</span> <span class="token punctuation">{</span>
node<span class="token operator">:</span> <span class="token punctuation">{</span>
extensions<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'.js'</span><span class="token punctuation">,</span> <span class="token string">'.jsx'</span><span class="token punctuation">,</span> <span class="token string">'.ts'</span><span class="token punctuation">,</span> <span class="token string">'.tsx'</span><span class="token punctuation">,</span> <span class="token string">'.d.ts'</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre>
vitest と eslint-plugin-import に依存している環境では、vitest.config.ts内で vitest/config をインポートすると Unable to resolve path to module 'vitest/config'. eslint(import/no-unresolved) というエラーが出る場合があります。
2022-11-23T05:16:24.000Z
2022-11-23T05:50:53.000Z
Next.js + Vercel + microCMSなどを使ってほぼ無料でブログを運用する
tag:blog.kubosho.com,2022-08-24:entry://my-blog-architecture
<p>当ブログのシステム構成について紹介します。構成を真似することでほぼ無料(後述)でブログを運営できます。</p>
<h2>当ブログの構成概要</h2>
<p>いわゆるJamstack構成です。構成を画像で示すと次の通りです。</p>
<p><img src="https://blog-assets.kubosho.com/blog_system_diagram.png" alt="ブログの構成を表した図"></p>
<p>microCMSまたは<a href="https://github.com/kubosho/blog.kubosho.com">ブログのリポジトリ</a>に変更がある場合、Vercelの<a href="https://vercel.com/docs/concepts/git/deploy-hooks">Deploy Hooks</a>を使ってVercel上の環境を更新するようにしています。</p>
<p>Next.js上でビルドするときに、ヘッドレスCMSのAPIを使ってブログの記事などを取得し、<a href="https://nextjs.org/">Next.js</a>の<a href="https://nextjs.org/docs/basic-features/data-fetching/get-static-props">getStaticProps</a>を使ってStatic Site Generateをできるようにしています。</p>
<p>ブログのコンテンツは<a href="https://vercel.com/docs/concepts/edge-network/overview">Vercelが提供しているCDN</a>によってキャッシュされます。</p>
<p>また画像などはAmazon S3上にアップロードしたものを、CloudFrontでキャッシュして配信するようにしています。</p>
<h2>どうしてブログをJamstack構成で作ろうと思ったか</h2>
<p>もともとこのブログは<a href="https://hatenablog.com/">はてなブログ</a>上で書かれていました。</p>
<p>はてなブログを使っていた理由としては、WordPressなどのCMSを使った場合に、本体やプラグインの更新管理が面倒だったのと、投稿画面が使いやすかったためでした。</p>
<h3>素振り環境が欲しくなった</h3>
<p>はてなブログでブログを運用するうちに、Webフロントエンドやサーバーサイドも含めた素振り環境が欲しくなりました。</p>
<p>そうした思いと、はてなブログProで提供されている機能のうち独自ドメインくらいしか恩恵を受けていないことに気づき、ブログを自前で作ろうと思い立ちました。</p>
<p>そこでブログを作り出した当初は、サーバーサイドも含めて作っていました。</p>
<p>ただ作業する中でいつまで経っても完成しない未来が見えたので、サーバーサイド側を作りこむのは諦め、Next.jsを使ってさくっと作って公開することにしました。</p>
<h2>どのような技術スタックになっているか</h2>
<p>使っているサービスやフレームワーク・ライブラリーを表にしました。</p>
<table>
<thead>
<tr>
<th>技術</th>
<th>リンク</th>
</tr>
</thead>
<tbody>
<tr>
<td>フレームワーク</td>
<td><a href="https://nextjs.org/">Next.js</a></td>
</tr>
<tr>
<td>ヘッドレスCMS</td>
<td><a href="https://microcms.io/">microCMS</a></td>
</tr>
<tr>
<td>ホスティング</td>
<td><a href="https://vercel.com/">Vercel</a></td>
</tr>
<tr>
<td>画像ストレージ</td>
<td><a href="https://aws.amazon.com/jp/s3/">Amazon S3</a></td>
</tr>
<tr>
<td>画像CDN</td>
<td><a href="https://aws.amazon.com/jp/cloudfront/">CloudFront</a></td>
</tr>
<tr>
<td>i18n</td>
<td><a href="https://github.com/lukeed/rosetta">Rosetta</a></td>
</tr>
<tr>
<td>マークダウンプロセッサー</td>
<td><a href="https://unifiedjs.com/">unified</a>, <a href="https://remark.js.org/">remark</a></td>
</tr>
<tr>
<td>HTMLコンバーター</td>
<td><a href="https://github.com/rehypejs/rehype">rehype</a></td>
</tr>
<tr>
<td>テスト</td>
<td><a href="https://vitest.dev/">Vitest</a></td>
</tr>
</tbody>
</table>
<p>この中からヘッドレスCMSの変遷について話します。</p>
<h3>最初はヘッドレスCMSにContentfulを使った</h3>
<p>はてなブログからNext.jsベースのブログに置き換えたとき、<a href="https://www.contentful.com/">Contentful</a>を使っていました。</p>
<p>しかし<a href="https://blog.kubosho.com/entry/migrating-from-contentful-to-markdown-file">自動保存のタイミングでIMEが確定されて書いた記事の文章がめちゃくちゃになる現象</a>に遭遇して、ContentfulからGitリポジトリにMarkdownファイルをコミットして、事前に記事の情報をまとめたJSONファイルを作る形式に変更しました。</p>
<h3>Markdownファイルをコミットする形式からmicroCMSへの移行</h3>
<p>なんで移行しようと思ったかは覚えていないですが、6時間くらいかけてmicroCMSに記事を移行できたようです。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">だいたい 6 時間くらいでブログのシステムを Markdown を直接更新する形式から microCMS で記事を入稿する形式にできた</p>— kubosho (@kubosho_) <a href="https://twitter.com/kubosho_/status/1452620689240780802?ref_src=twsrc%5Etfw">October 25, 2021</a></blockquote>
<h2>どれほどの料金がかかるか</h2>
<p>今年実際にかかった料金を表にしました。</p>
<table>
<thead>
<tr>
<th>名前</th>
<th>プラン</th>
<th>料金</th>
</tr>
</thead>
<tbody>
<tr>
<td>microCMS</td>
<td>Hobbyプラン</td>
<td>¥0</td>
</tr>
<tr>
<td>Vercel</td>
<td>Hobbyプラン</td>
<td>¥0</td>
</tr>
<tr>
<td>Amazon S3</td>
<td>従量課金</td>
<td>¥0</td>
</tr>
<tr>
<td>CloudFront</td>
<td>従量課金</td>
<td>$0~$0.01</td>
</tr>
</tbody>
</table>
<h2>今後どうしていきたいか</h2>
<p>最後に当ブログの展望を示します。</p>
<h3>OGP imageの自動生成</h3>
<p>現在は記事がSNSなどにシェアされた場合、固定の画像が表示されます。</p>
<p>これを多くのCGMサービスで導入されているように、ブログのテーマに沿った画像を自動生成して使うようにしたいと考えています。</p>
<h3>デバフの導入</h3>
<p>今はサードパーティースクリプトなどが少ないので表示速度が早いですが、広告のスクリプトやWebフォントなどを導入してそれでもなお表示速度が早いというブログにしたいと考えています。</p>
<p>ただVercelのhobbyプランは広告を扱うと商用利用扱いになって<a href="https://vercel.com/docs/concepts/limits/fair-use-policy#commercial-usage">Proプラン以上の契約が必要</a>になります。なので広告のスクリプトを導入する場合はVercelのProプラン以上を契約するか、商用利用可のホスティングサービスに移動する必要があります。</p>
<h3>ブログのパフォーマンス指標の継続的な測定</h3>
<p>広告のスクリプトやWebフォントの導入に伴って、パフォーマンス指標の継続的な測定を何かしらでして、パフォーマンス向上施策がどのくらい効果あるのか見られるようにしたいと考えています。</p>
<h3>Googleアナリティクスの活用</h3>
<p>今はただGoogleアナリティクスを導入しているだけですが、コンバージョンの設定なども入れてPV数などを上げるための参考指標を作りたいと考えています。</p>
<h3>継続的にブログ更新できる仕組みづくり</h3>
<p>なるべくブログの記事投稿を楽にしようと思い、ブログの投稿フォームや画像アップローダーを作っています。</p>
<ul>
<li>ブログの投稿フォーム - <a href="https://github.com/kubosho/instant-blog-post-form">https://github.com/kubosho/instant-blog-post-form</a></li>
<li>画像アップローダー - <a href="https://github.com/kubosho/s3-image-uploader">https://github.com/kubosho/s3-image-uploader</a></li>
</ul>
<h2>最後に</h2>
<p>この記事が参考になったらブログのリポジトリにスターお願いします!</p>
<p><a href="https://github.com/kubosho/blog.kubosho.com">kubosho/blog.kubosho.com: My personal blog. Built with Jamstack technology stack.</a></p>
当ブログのシステム構成について紹介します。構成を真似することでほぼ無料(後述)でブログを運営できます。
2022-08-24T10:26:59.000Z
2022-11-28T15:39:57.000Z
携帯回線の契約を整理した
tag:blog.kubosho.com,2022-08-11:entry://reviewed-cell-phone-line-contract
<p>2022年の6月末まで、ahamoとIIJmioと楽天モバイルを契約していた。</p>
<p>ただ楽天モバイルが<a href="https://network.mobile.rakuten.co.jp/fee/un-limit/">Rakuten UN-LIMIT VII</a>という料金プランに移行するのに伴って、自分の携帯回線の契約を見直した結果、IIJmioを解約してahomoと楽天モバイルの2回線にした。</p>
<p>2回線契約している理由は、iPhoneとmotorola edge 20という機種を持っているのが理由となる。<br>
どちらも同じくらい使っているので、2機種ともいつでもどこでも使いたいという思いがあって、2回線契約している。</p>
<p>楽天モバイルが料金プランを改定するまでは、IIJmioの回線をデータ通信専用にして楽天モバイルを通話・SMS専用にすることで、楽天モバイルの回線で追加の料金がかかることを恐れることなくデータ通信をできていた。</p>
<p>ただ前述の通り楽天モバイルのプラン改定に伴って、楽天モバイルは0円で回線契約を維持できなくなった。</p>
<p>IIJmioを音声プランに切り替えた上でデータ回線をタイプAにしても良かったけど、契約を変えるのが面倒だったのと、<a href="https://corp.mobile.rakuten.co.jp/innovation/cloud-network/">完全仮想化クラウドネイティブモバイルネットワーク</a>というシステム構成が面白そうだなと考えたので、楽天モバイルに一本化することにした。</p>
2022年の6月末まで、ahamoとIIJmioと楽天モバイルを契約していた。
2022-08-11T10:47:10.000Z
2022-11-28T15:32:35.000Z
ブログ記事を投稿するためのフォームを作った
tag:blog.kubosho.com,2022-07-16:entry://created-blog-post-form
<p><a href="https://hatenablog.com/">はてなブログ</a>のMarkdownによる記事編集画面や<a href="https://esa.io/">esa - 自律的なチームのための情報共有サービス</a>のように、本文の編集画面とリアルタイムプレビューが横並びになるような投稿フォームが個人的に好みです。</p>
<p>ですが、ブログで使っている<a href="https://microcms.io/">microCMS</a>の投稿画面や、普段使っているマークダウンエディターの<a href="https://obsidian.md/">Obsidian</a>にはプレビューを横並びにするようなオプションが無かったため、自分で記事を投稿するためのフォームを作ってみました。</p>
<p>技術スタックとしては次の通りです。仕事では使っていないものばかりですが、いろいろ使ってみたかったものを揃えてみました。</p>
<ul>
<li><a href="https://lexical.dev/">Lexical · An extensible text editor framework that does things differently</a></li>
<li><a href="https://headlessui.com/">Headless UI - Unstyled, fully accessible UI components</a></li>
<li><a href="https://ja.vitejs.dev/">Vite | 次世代フロントエンドツール</a></li>
<li><a href="https://vitest.dev/">Vitest | A blazing fast unit test framework powered by Vite</a></li>
<li><a href="https://zustand-demo.pmnd.rs/">Zustand</a></li>
</ul>
<p>実際の記事投稿画面は次の通りです。</p>
<p><img src="https://blog-assets.kubosho.com/instant-blog-post-form.png" alt="記事の投稿フォームのスクリーンショット"></p>
<h2>備えている機能</h2>
<p>今回作った投稿フォームの特徴は次の通りです。</p>
<ul>
<li>ページの左側に本文編集フォームがある</li>
<li>ページの右側にリアルタイムプレビューがある</li>
<li>下書き状態・公開状態の切り替えが可能
<ul>
<li>ただmicroCMSはPOST APIにクエリーを付けたい場合は<a href="https://microcms.io/pricing">Teamプラン</a>以上の契約が必要になる……(作った後の動作確認で気づいた)</li>
</ul>
</li>
<li>ページを再読み込みしてもタイトル・URLのパス・本文の状態が保持される</li>
</ul>
<h2>これから作りたい機能</h2>
<p>いま考えていることとして、次に挙げる機能を作りたいと思っています。</p>
<ul>
<li>記事を投稿するときに確認画面を表示する</li>
<li>記事の投稿が完了したら完了と分かるような表示を追加する</li>
<li>記事の投稿に失敗したら失敗と分かるような表示を追加する</li>
<li>タグの追加ができる</li>
<li>カテゴリーの追加ができる</li>
<li>プレビュー画面のスタイルを<a href="https://blog.kubosho.com/">https://blog.kubosho.com/</a>と同じものを適用する</li>
<li><a href="https://github.com/fukayatsu/esarea">fukayatsu/esarea</a>やesaの本文編集フォームのように、tabキーやenterキーを押したときにマークダウンの記法が自動で挿入される</li>
<li><a href="https://textlint.github.io/">textlint · The pluggable linting tool for text and markdown</a>を導入して、記事を書いているときにエラーを出す</li>
<li>何かしらのホスティングサービスにアップロードして、いろんなデバイスからアクセスできるようにする
<ul>
<li>認証機能を作る必要がある</li>
</ul>
</li>
<li>本文編集部分とプレビュー部分のスクロール同期をする</li>
<li>Vimモード</li>
<li>画像アップロード</li>
</ul>
<h2>まとめ</h2>
<p>もしこの記事を見て良いなと思ったら、リポジトリへのstarとwatch登録お願いいたします。</p>
<p><a href="https://github.com/kubosho/instant-blog-post-form">kubosho/instant-blog-post-form: Blog post form for https://blog.kubosho.com.</a></p>
はてなブログのMarkdownによる記事編集画面やesa - 自律的なチームのための情報共有サービスのように、本文の編集画面とリアルタイムプレビューが横並びになるような投稿フォームが個人的に好みです。
2022-07-16T14:36:56.000Z
2022-11-28T13:54:02.000Z
ファミリーマート公式Twitterのツイートからより良い画像の代替テキスト(alt)を考える
tag:blog.kubosho.com,2022-07-07:entry://familymart-tweet-alt-text
<p>ファミリーマートの公式Twitterのツイートに、画像の代替テキストを改善できそうなツイートがありました。</p>
<p>この記事では画像の代替テキストのどういった点が惜しいのか、またどのように改善すればいいのか、私見を書きます。</p>
<p>※貶すつもりは全くなく、あくまでツイートを元にどういった代替テキストを書けば良いのかを考える記事です。</p>
<h2>どのようなツイートか</h2>
<p>ファミリーマート公式Twitterの該当ツイートを引用します。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これが、からあげの正解。<br>ファミから。<br><br>そのこだわりのすべてをALTでチェック。 <a href="https://t.co/TalY56q5PX">pic.twitter.com/TalY56q5PX</a></p>— ファミリーマート (@famima_now) <a href="https://twitter.com/famima_now/status/1534686713787711491?ref_src=twsrc%5Etfw">June 9, 2022</a></blockquote>
<p>※ツイートが削除されたので<a href="https://web.archive.org/web/20220609000048/https://twitter.com/famima_now/status/1534686713787711491">インターネットアーカイブに残っているツイート</a>を貼っておきます。</p>
<p>ツイートを一目見ただけだと、ファミからというファミリーマートで売られている唐揚げの写真が4枚並んだツイートです。</p>
<p>ただしツイートにもある通り、ファミからのこだわりが代替テキストに書かれていて、ツイートの画像上にあるaltボタンを押すとこだわりが見られるツイートになっています。</p>
<h2>なぜ代替テキストの使い方が惜しいのか</h2>
<p>4枚目のお皿の上に唐揚げがたくさん乗っている画像の代替テキストとして「食べてください」を連続して書くことは、画像と代替テキストの内容が一致せず、特定の状況・状態では正しい情報が伝わらなくなります。</p>
<p>また、1枚目の湯気が立ち込めた唐揚げを切った断面のドアップ画像・2枚目のファミからのパッケージ画像・3枚目の唐揚げが中央にあってドアップになっている画像は、画像で示している内容も代替テキストに書かれていますが、画像にはない情報や宣伝文句のような文章も書かれています。</p>
<p>画像と代替テキストの内容が一致していないのは、テキストが画像の代替という役目を果たせないことになります。</p>
<p>また画像にない情報や宣伝文句も代替テキストに含んでしまうと、TweetDeckや非公式アプリを使っている晴眼者は代替テキストに書かれた文章を見れず、伝えたい情報を伝えられないことになります。</p>
<h2>そもそも画像の代替テキストとは?</h2>
<p>画像の代替テキストはなんらかの状況・状態で画像が使えないときに、設定した代替テキストが使われます。</p>
<p>どういった状況・状態で代替テキストが使われるか一例を挙げます。</p>
<ul>
<li>スクリーンリーダーを使っている場合に、画像の代替テキストが読まれる</li>
<li>通信速度が遅く画像表示まで時間がかかる場合に、画像の代替テキストを表示する</li>
<li>CDNに障害が起きて画像が表示できない場合に、画像の代替テキストを表示する</li>
<li>Webブラウザーで特定の画像形式に対応していない場合に、画像の代替テキストを表示する</li>
<li>w3mやLynxなどのテキストベースのブラウザーで、画像表示に対応していない場合に画像の代替テキストを表示する</li>
<li>検索エンジンのクローラーが、画像の代替テキストを元に画像の情報を得る</li>
</ul>
<p>HTMLにおいては、img要素のalt属性の値に画像の代替テキストを設定します。</p>
<p>画像の代替テキストの書き方として<a href="https://html.spec.whatwg.org/multipage/images.html#alt">HTMLの仕様</a>には次のように書かれています。</p>
<blockquote lang="en">
One way to think of alternative text is to think about how you would read the page containing the image to someone over the phone, without mentioning that there is an image present. Whatever you say instead of the image is typically a good start for writing the alternative text.
</blockquote>
<p>同じ部分を<a href="https://momdo.github.io/html/images.html#alt">日本語訳されたHTMLの仕様</a>を見てみると次のように書かれています。</p>
<blockquote>
<p>代替テキストを考える1つの方法は、画像の存在があることを言及することなく、電話で誰かに画像を含むページをどのように読むかを考えることである。通常、画像の代わりにいうものは何でも、代替テキストを記述するための良いスタートである。</p>
</blockquote>
<p>さてTwitterの話に戻ると、画像の代替テキストのことを「画像の説明」という言葉で説明しています。</p>
<p>Twitterのヘルプにある<a href="https://help.twitter.com/ja/using-twitter/write-image-descriptions">良い画像の説明を作成する方法</a>を引用すると、「画像の説明は、目の不自由な方や弱視の方、ユーザー補助テクノロジーをご利用の方、低帯域幅の地域にお住まいの方、さらなる背景情報を求めている方の一助」向けの機能と書かれています。</p>
<p>Twitterの画像の説明も、HTMLのimg要素のalt属性に指定するような文言を書くことを意図していそうです。</p>
<h2>どのように代替テキストを改善するか</h2>
<p>ここまで書いたことを踏まえて、ファミリーマートのツイートの画像の代替テキストを考えてみます。</p>
<h3>ツイートで何を伝えたかったのかを考える</h3>
<p>ファミリーマートのツイートですが、製品の美味しさやシズル感を伝えたかったと推測します。</p>
<p>製品のストーリーを伝えることで製品開発者の熱い思いがこのツイートを見た人達に伝わって、好意的な印象を持つことで実際の購入に至ってほしい考えがあったと考えます。</p>
<p>こういったストーリーをTwitterで書くには、Twitterに投稿できる文字数では足りなさそうです。しかしストーリーを別途書いておく特設ページが用意できなかったのかもしれません。</p>
<p>そのため、altボタンを押すと見られるようにすればいいというTwitter運用担当者の工夫があったと考えられます。</p>
<p>また4枚目のお皿の上に唐揚げがたくさん乗っている画像の説明では「食べてください」を連続して書くことで、altボタンを押した人達を驚かせたり、クスっと笑わせたりという公式アカウントがおちゃめなことをしているというギャップを感じさせたかったと思います。</p>
<p>実際リプライで<q>4枚目ホラーで草</q>というツイートがあり、これはTwitter運用担当者が意図した反応だと考えられます。</p>
<h3>代替テキストの改善例</h3>
<p>というわけで、自分が考える代替テキストの改善例を書きます。まずもう一度ツイートを引用します。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これが、からあげの正解。<br>ファミから。<br><br>そのこだわりのすべてをALTでチェック。 <a href="https://t.co/TalY56q5PX">pic.twitter.com/TalY56q5PX</a></p>— ファミリーマート (@famima_now) <a href="https://twitter.com/famima_now/status/1534686713787711491?ref_src=twsrc%5Etfw">June 9, 2022</a></blockquote>
<p>※ツイートが削除されたので<a href="https://web.archive.org/web/20220609000048/https://twitter.com/famima_now/status/1534686713787711491">インターネットアーカイブに残っているツイート</a>を貼っておきます。</p>
<p>このツイートにある画像の代替テキストを書くのであれば次のようにするかもしれません。</p>
<ul>
<li>画像1枚目の代替テキストは「唐揚げの断面がドアップになっていて、断面から湯気が出ている様子」</li>
<li>画像2枚目の代替テキストは「ファミから醤油味とファミから塩味のパッケージ」</li>
<li>画像3枚目の代替テキストは「唐揚げが中央にあり、その唐揚げから湯気が出ている様子」</li>
<li>画像4枚目の代替テキストは「白いお皿の上に唐揚げがたくさん乗っていて、その後ろに付け合わせの野菜がある」</li>
</ul>
<p>電話口の相手に伝える感じだと、こんな感じで書けば伝わりそうです。</p>
<p>また4枚目の「食べてください」を連呼する形式を活かすのであれば、スマートフォンのメモアプリに「食べてください」とひたすら書いたものをスクリーンショットという形式で投稿して、代替テキストに「食べてください」をひたすら書く形式がありそうです。</p>
<h2>おまけ: 自分が思う良い感じの代替テキスト</h2>
<p>まず<a href="https://twitter.com/zennoh_food">全農広報部【公式】日本の食を味わう</a>のツイートが挙げられます。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">フライパンでできるサラダチキンの作り方、ご紹介しています。今月の広報誌エプロンです。サラダチキンは鍋で茹でるイメージでしたが、フライパンでできるんですね。夏場、お湯を沸かすと思うと一気に腰が重くなりますがフライパンなら…なんとか…!(フライパン大好き民)<a href="https://t.co/5EWrikEpd2">https://t.co/5EWrikEpd2</a> <a href="https://t.co/7vtZqbhX2z">pic.twitter.com/7vtZqbhX2z</a></p>— 全農広報部【公式】日本の食を味わう (@zennoh_food) <a href="https://twitter.com/zennoh_food/status/1544115957634723840?ref_src=twsrc%5Etfw">July 5, 2022</a></blockquote>
<p>画像の内容が代替テキストでも過不足無く表現されていると感じます。</p>
<p>他のツイートだと、にじさんじ所属のVTuberである壱百満天原サロメのツイートが挙がります。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">きょうのおまんが、ホラー回と言われていてにっこりしてしまったので、おまけですわ😊 <a href="https://t.co/nfShKjKWw7">pic.twitter.com/nfShKjKWw7</a></p>— 壱百満天原サロメ💯🦂 (@1000000lome) <a href="https://twitter.com/1000000lome/status/1543884318765891584?ref_src=twsrc%5Etfw">July 4, 2022</a></blockquote>
<p>画像の内容を全て書いているわけではないですが、漫画で伝えたいことを表現できている代替テキストで百満点ですわ~!</p>
<h2>まとめ</h2>
<p>代替テキストは人によって考え方にばらつきがありますし、状況によっても代替テキストの内容が変わるので、一概にこれが正解とは言いづらいものです。</p>
<p>ただ適切な代替テキストを設定することで、より多くの状況・状態にある人に伝えたいことを伝えられるようになります。</p>
<p>代替テキストを設定したことがない人は、とりあえず代替テキストを一度設定してみると面白いかもしれません。</p>
<h2>参考リンク</h2>
<ul>
<li><a href="https://help.twitter.com/ja/using-twitter/write-image-descriptions">良い画像の説明を作成する方法 | Twitterヘルプ</a></li>
<li><a href="https://yuugop.com/articles/practicalaccessiblehtml/pah01.html">altはつけるだけじゃなくて - 実践アクセシブルHTML 第一回</a></li>
<li><a href="https://www.slideshare.net/nozomisawada969/ss-122034985">代替テキストの基本から応用まで</a></li>
</ul>
ファミリーマートの公式Twitterのツイートに、画像の代替テキストを改善できそうなツイートがありました。
2022-07-07T02:01:43.000Z
2022-11-28T14:30:00.000Z
ブログを国際化対応した
tag:blog.kubosho.com,2022-06-16:entry://introduce-i18n-in-blog
<p>当ブログのUIで使う文言を国際化対応しました。</p>
<p><a href="https://github.com/kubosho/blog.kubosho.com/pull/933">Introduce i18n by kubosho · Pull Request #933 · kubosho/blog.kubosho.com</a></p>
<p>国際化対応には<a href="https://github.com/lukeed/rosetta">rosetta</a>という軽量の国際化対応ライブラリーを使いました。</p>
<p>文言だけを各言語に対応させる分には必要なAPIが揃っていたのと、bundle sizeが426バイトだったのでJavaScriptのサイズが大きくならないのも良いと思い、rosettaを選択しました。</p>
<p>きっかけとしては、Androidアプリでの開発ではLintで文字列に都度IDを振って文字列リソースとして記載するよう指摘される旨のツイートを見て、Webでも同じ対応を入れていいはずと感じたためやりました。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Androidはこの辺しっかりしてて、「文字列は都度IDを振ってres/values/strings.xmlに文字列リソースとして記載しなさい」というのがAndroid Lintの指摘事項になってるんだよね。おかげで日本語をUIの中にベタ書きしない習慣を身につけやすい。<br>(まあ僕もWebだとベタ書きしてしまうのだけど) <a href="https://t.co/ZSONvK7u1d">https://t.co/ZSONvK7u1d</a></p>— なかざん💉💉💉 (@Nkzn) <a href="https://twitter.com/Nkzn/status/1531110969073537024?ref_src=twsrc%5Etfw">May 30, 2022</a></blockquote>
<p>正直あまり深く考えずにやれそうだからやりますわ~という感じでやりました。</p>
<p>感想としては、文言が特定のディレクトリに集約されたため、文言を変えるときに作業が楽になるなと感じました。</p>
<p>多言語対応という意味では現状日本語しか対応していないため、国際化対応によって何か得られたというのは無いです。</p>
<p>今後はブログの記事も多言語で書けるようになっていきたいです。</p>
当ブログのUIで使う文言を国際化対応しました。
2022-06-16T00:00:03.000Z
2022-11-28T13:57:24.000Z
AVA上でsinon.useFakeTimers()を複数のテスト内で実行するとエラーが出る
tag:blog.kubosho.com,2022-05-20:entry://run-sinon-useFakeTimers-for-each-test-on-ava-throw-error
<p>最近<a href="https://sinonjs.org/">Sinon.JS</a>のバージョンをv14.0.0に上げたときに、エラーが出てテスト実行が失敗するようになりました。</p>
<p>この記事では対処方法を書いていきます。</p>
<h2>事象</h2>
<p>たとえば次のようなテストがあったとします。</p>
<p><code>sinon.useFakeTimers</code> は<a href="https://sinonjs.org/releases/latest/fake-timers/">ドキュメント</a>にある通り、<code>setTimeout</code> や <code>clearTimeout</code>などを置き換える関数です。</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword module">import</span> <span class="token imports">test</span> <span class="token keyword module">from</span> <span class="token string">'ava'</span><span class="token punctuation">;</span>
<span class="token keyword module">import</span> <span class="token imports">sinon</span> <span class="token keyword module">from</span> <span class="token string">'sinon'</span><span class="token punctuation">;</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token string">'test'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">t</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> fakeTimer <span class="token operator">=</span> sinon<span class="token punctuation">.</span><span class="token method function property-access">useFakeTimers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
t<span class="token punctuation">.</span><span class="token method function property-access">pass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
fakeTimer<span class="token punctuation">.</span><span class="token method function property-access">restore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token string">'test2'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">t</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> fakeTimer <span class="token operator">=</span> sinon<span class="token punctuation">.</span><span class="token method function property-access">useFakeTimers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
t<span class="token punctuation">.</span><span class="token method function property-access">pass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
fakeTimer<span class="token punctuation">.</span><span class="token method function property-access">restore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<p>2回目の <code>sinon.useFakeTimers()</code> を実行するとき、先ほどのテストファイルで言うと <code>test2</code> を実行するときに次のようなメッセージが表示されます。</p>
<pre><code>TypeError {
message: 'Can\'t install fake timers twice on the same global object.',
}
</code></pre>
<h2>原因</h2>
<p>書き換えられたグローバルオブジェクトを戻すために <code>sinon.useFakeTimers</code> と <code>fakeTimer.restore()</code> を対になる形で実行しないといけません。</p>
<p>うっかり <code>fakeTimer.restore()</code> を実行しないまま <code>sinon.useFakeTimers</code> を実行すると、元の日時に復元することが難しくなります。</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token comment">// サンプル</span>
<span class="token keyword">const</span> sinon <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"sinon@12.0.0"</span><span class="token punctuation">)</span>
<span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span><span class="token string">"Original time: "</span> <span class="token operator">+</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "Original time: 1653007080412"</span>
<span class="token keyword">let</span> fakeTimer <span class="token operator">=</span> sinon<span class="token punctuation">.</span><span class="token method function property-access">useFakeTimers</span><span class="token punctuation">(</span><span class="token known-class-name class-name">Date</span><span class="token punctuation">.</span><span class="token method function property-access">parse</span><span class="token punctuation">(</span><span class="token string">"2014-06-05T12:07:07.662Z"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
fakeTimer <span class="token operator">=</span> sinon<span class="token punctuation">.</span><span class="token method function property-access">useFakeTimers</span><span class="token punctuation">(</span><span class="token known-class-name class-name">Date</span><span class="token punctuation">.</span><span class="token method function property-access">parse</span><span class="token punctuation">(</span><span class="token string">"2018-04-11T14:08:00Z"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
fakeTimer<span class="token punctuation">.</span><span class="token method function property-access">restore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span><span class="token string">"Restored time: "</span> <span class="token operator">+</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "Restored time: 1401970027662"</span>
</code></pre>
<p>今回のサンプルコードの場合はまだ復元できると思いますが、これがより回数を重ねて <code>sinon.useFakeTimers</code> を実行してしまうとより復元が難しくなります。</p>
<p>この問題が、<a href="https://github.com/sinonjs/sinon/issues/2449">Impossible to restore fake timers in certain situations. · Issue #2449 · sinonjs/sinon</a>で報告されて、対応として <code>@sinonjs/fake-timers</code> 側で<a href="https://github.com/sinonjs/fake-timers/pull/426">Prohibit faking of faked timers by cjbarth · Pull Request #426 · sinonjs/fake-timers</a>というPull Requestがマージされました。</p>
<p>Pull RequestのSolutionに「If an attempt is make to fake a timer that is already faked, an exception will be thrown.」と書いてある通り、timerがすでにfakeだった場合に再度 <code>sinon.useFakeTimers</code> を実行した場合に例外が投げられるという変更がされました。</p>
<p>この変更により、複数のテストで <code>sinon.useFakeTimers</code> と <code>fakeTimer.restore</code> を実行していた場合に、AVA上でテストが並列で実行されることもあって <code>fakeTimer.restore</code> が実行される前に <code>sinon.useFakeTimers</code> が実行される場合が出てきました。</p>
<p>その結果として「Can't install fake timers twice on the same global object.」というエラーが出力されるようになりました。</p>
<h2>解決策</h2>
<p>解決方法は2つあります。</p>
<p>まず1つは、テストコード側で並列実行をやめて直列実行にすることです。具体的には次の通り書くとテストが成功します。</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword module">import</span> <span class="token imports">test</span> <span class="token keyword module">from</span> <span class="token string">'ava'</span><span class="token punctuation">;</span>
<span class="token keyword module">import</span> <span class="token imports">sinon</span> <span class="token keyword module">from</span> <span class="token string">'sinon'</span><span class="token punctuation">;</span>
test<span class="token punctuation">.</span><span class="token method function property-access">serial</span><span class="token punctuation">(</span><span class="token string">'test'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">t</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> fakeTimer <span class="token operator">=</span> sinon<span class="token punctuation">.</span><span class="token method function property-access">useFakeTimers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
t<span class="token punctuation">.</span><span class="token method function property-access">pass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
fakeTimer<span class="token punctuation">.</span><span class="token method function property-access">restore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
test<span class="token punctuation">.</span><span class="token method function property-access">serial</span><span class="token punctuation">(</span><span class="token string">'test2'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">t</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> fakeTimer <span class="token operator">=</span> sinon<span class="token punctuation">.</span><span class="token method function property-access">useFakeTimers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
t<span class="token punctuation">.</span><span class="token method function property-access">pass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
fakeTimer<span class="token punctuation">.</span><span class="token method function property-access">restore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<p>または <code>test.before</code> や <code>test.after</code> といったテストファイル内の最初と最後のテスト前後で実行されるフックを使って、fakeTimerを使うのも良いです。</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword module">import</span> <span class="token imports">test</span> <span class="token keyword module">from</span> <span class="token string">'ava'</span><span class="token punctuation">;</span>
<span class="token keyword module">import</span> <span class="token imports">sinon</span> <span class="token keyword module">from</span> <span class="token string">'sinon'</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> fakeTimer <span class="token operator">=</span> <span class="token keyword null nil">null</span><span class="token punctuation">;</span>
test<span class="token punctuation">.</span><span class="token method function property-access">before</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
fakeTimer <span class="token operator">=</span> sinon<span class="token punctuation">.</span><span class="token method function property-access">useFakeTimers</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
test<span class="token punctuation">.</span><span class="token method function property-access">after</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>fakeTimer<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword control-flow">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
fakeTimer<span class="token punctuation">.</span><span class="token method function property-access">restore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token string">'test'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">t</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
t<span class="token punctuation">.</span><span class="token method function property-access">pass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token string">'test2'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">t</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
t<span class="token punctuation">.</span><span class="token method function property-access">pass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<p>AVAのように並列実行がデフォルトのテストフレームワークだと同じ問題が起きそうですが、他のJestやVitestなどはどうしているのか気になります。</p>
最近Sinon.JSのバージョンをv14.0.0に上げたときに、エラーが出てテスト実行が失敗するようになりました。
2022-05-20T00:57:40.000Z
2022-05-20T05:23:39.000Z
KanbanFlowのプレミアムプラン登録までの気持ちよさ
tag:blog.kubosho.com,2022-05-01:entry://kanbanflow-premium-plan
<p><a href="https://kanbanflow.com/">KanbanFlow</a>をかなり使っている。</p>
<p>KanbanFlowを使い始めたきっかけとしては、<a href="https://amzn.to/3EXm0ob">SOFT SKILLS ソフトウェア開発者の人生マニュアル</a>で紹介されていたからだった。</p>
<p><a href="https://experience.dropbox.com/ja-jp/resources/pomodoro-technique">ポモドーロ・テクニック</a>を実施するためのタイマーも実装されていると書かれていて、実際触った感じ次の点が良かったのでKanbanFlowで個人的なタスクの管理を始めた。</p>
<ul>
<li>公開する設定がないため<a href="https://www.itmedia.co.jp/news/articles/2104/06/news118.html">誤って公開状態になることがない</a></li>
<li>ページの読み込みが早い</li>
<li>タスク管理に必要な情報だけがUIとしてあるので、操作に迷わない</li>
</ul>
<p>特に困らずKanbanFlowを半年使ってきたので、そろそろKanbanFlowの運営元に還元したくなってきた。</p>
<p>あと有料版の機能で、次に挙げる機能が便利そうだったので有料版にしたかった。</p>
<ul>
<li>ボードを分類ごとに横分割するSwimlanes</li>
<li>Two-factor authentication</li>
<li>Analytics & Reporting全般</li>
</ul>
<p>以上の2点から有料版を契約しようと思った。</p>
<p>ただ<a href="https://kanbanflow.com/pricing">有料プランページ</a>の導線が分からず、Googleで検索して見つけた。これはこれでどうなんだとも思いつつ、ガツガツしすぎていない姿勢がまず気に入った。</p>
<p>またトライアル期間はクレジットカードの登録も必須ではなく驚いた。</p>
<p>世の中のサービスはだいたいトライアル期間にもクレジットカードの登録を求められると思う。</p>
<p>悪質なサービスでは年契約のプランを月辺りに換算した料金を目立たせた上で、お得なように見せかけてトライアル契約させようとしてくるし、こちら側から解除しなければ勝手に課金されるサービスがある。</p>
<p>そういった<a href="https://www.kgri.keio.ac.jp/news-event/083668.html">ダークパターン</a>が横行しているこの世の中で、KanbanFlowのプレミアムプラン導線が目立たなかったり、クレジットカードの登録が必須でなかったりという素朴さは新鮮に感じたし気持ちよかった。</p>
<p>利用者目線としては、世の中のサービス全てがKanbanFlowのように、サービスの根幹となる機能をちゃんと使わせた上でさらに便利な機能を有料で提供して、長期的な目線で有料会員を増やすという方向性になってほしいと感じた。</p>
<p>とはいえ、有料会員が増えなくて資金がショートするのは往々にしてありそうだし、<del>資金がショートしなかったとしても思想を変えるにはKPI至上主義者を全て消す必要がありそうだけど。</del></p>
KanbanFlowをかなり使っている。
2022-05-01T00:00:02.000Z
2022-05-01T00:00:02.000Z
京都芸術大学(KUA) 通信教育部芸術学部デザイン科イラストレーションコースに入学した
tag:blog.kubosho.com,2022-04-01:entry://i-entered-kua
<p><img src="https://blog-assets.kubosho.com/student_id.png" alt="京都芸術大学の学生証。学籍番号・氏名・生年月日・写真などは隠した状態になっている"></p>
<p><a href="https://www.kyoto-art.ac.jp/news/info/744">略称が「瓜芸」や「KUA」と呼ばれるほう</a>の京都芸術大学(以降はKUAと書きます)通信教育部芸術学部デザイン科イラストレーションコースに2022年4月1日をもって入学しました。</p>
<p><a href="https://tenohira.kyoto-art.ac.jp/illustration/">イラストレーションコース | 京都芸術大学 通信教育部</a></p>
<h2>なぜ入学したのか</h2>
<p>イラスト自体は数年前からずっと描きたいと思っていて、実際に2015年は少し練習をしていました。</p>
<p>ただその時は練習方法が悪かったのかあまり上達せず、いつしか描かなくなっていました。</p>
<p>下手な絵ではなく上手い絵を描きたかったですが、描いた絵は下手だったので描く気が失せたのはあります。</p>
<p>時は流れて2021年6月、<a href="https://amzn.to/3IQ4R01">HUIONというメーカーの液晶タブレット</a>がAmazonのセールで割と安くなっていて思わず買いましたが、箱から液タブを出すことなく少し放置していました。</p>
<p>ただ<a href="https://note.com/enzen3852/n/na1fecd0ac10b">【練習内容公開】イラストを100日練習しました|燕禅|note</a> という記事を見て、描き続けた結果を見た自分は<a href="https://amzn.to/3JZ7cr4">ソッカの美術解剖学ノート</a>を買い、2021年9月辺りから本を見つつ模写するということをやり始めました。</p>
<p>そして年末辺りから放置していた液晶タブレットを箱から取り出し、CLIP STUDIO PAINTで絵を描き始めた結果、高校生のときにHTMLとCSSを書き始めたときの夢中になれる感情が蘇ってきて、イラストを描くことがもっと上手くなりたいと思い、イラストに関する知識や技術を体系的に学べそうかつ通信教育課程のコースがあったKUAに入学願書を出しました。</p>
<p>KUAの通信教育部芸術学部デザイン科イラストレーションコースは入学試験が無く、必要な書類を提出して漏れがなければ入学許可が降りる形で、2022年の2月初めくらいに願書を出して2月末には入学許可のメールとその後学生証などが郵便で届きました。</p>
<h2>どうなりたいのか</h2>
<p>ここまで書いた通り、イラストを練習し始めたのは2021年9月からで、デジタル移行は2021年12月からと、正直イラストを描いた経験というのは少ないです。</p>
<p>イラストを描くための知識や技術を体系的に学びつつ、イラストを描き続ける生活が待っていると思いますし、仕事は辞めていないので仕事と学業の両立は今後課題になるかもしれません。</p>
<p>話は逸れますが仕事について書くと、仕事は辞めていないどころか2022年4月1日で<a href="https://www.cyberagent.co.jp/">今の会社</a>に入社してから丸5年経ちました。前職はいろいろあって8ヶ月で辞めましたが、そこからまさか自分の人生において小学校の次に長く同じ組織にい続けるとは思いもしませんでした。</p>
<p>また今年だけでも、<a href="https://www.cyberagent.co.jp/techinfo/info/detail/id=23823">社内のエキスパート認定制度</a>に自己推薦してみたらアクセシビリティー分野のNext Expertsという形でエキスパート見習い的な立場になったり、<a href="https://www.cyberagent.co.jp/news/detail/id=27400">携わっているサービスでワールドカップを全試合無料生中継する</a>ことが決まったりといろいろ変化がありました。</p>
<p>話を戻すと、仕事と学業をまずは両立していって、まずは同人イベントで表紙イラストから内容まで全て自分で作れる状態にしたいなと考えています。</p>
<p>そして将来的には、ソフトウェア開発者とイラストレーターの二足のわらじを履けたら自分のやりたいことを叶える形になって楽しそうだなと妄想しています。</p>
<h2>イラストを描くことに対する思い</h2>
<p>イラストを描くことは楽しく、そして現実世界を観測する機会が以前より増えて、世界に対する解像度というのが前よりはちょっと上がった実感もあり、メイドインアビスのアニメ主題歌の<a href="https://www.utamap.com/showkasi.php?surl=k-170823-304">Deep in Abyssの歌詞</a>にあるように「誰もが逆らえずに潜っていく その目を灯火より輝かせて」や「それが呪いでも鼓動は本物 二度と憧れは止まらない」といった状態になっているなと感じています。</p>
<p>とはいえ成長を実感できなくなる時もあり、少し苦しいと感じる場面もありましたが、それも含めてイラストを描くことはやめられないなという気持ちです。</p>
<p>まずはシラバスを眺めつつ、卒業に必要な単位と自分が学びたいことを考えて、学んでいきたいと思っています。あと学割も使えるところでは使っていきたいですね。</p>
2022年4月からイラストを本気で学ぶべく大学に入学した話です。
2022-04-01T00:00:02.000Z
2022-11-28T13:50:50.000Z
ベストオブ2021
tag:blog.kubosho.com,2021-12-31:entry://best-of-2021
<p><a href="https://blog.kubosho.com/entry/2020-to-2021">2020年の振り返りと2021年の目標立て</a>で書いたことを振り返ろうとしたものの、あまりできてなくて記事を書く気持ちが高まらなかったので、<a href="https://dskd.jp/archives/114.html">ベストオブ2021 - dskd</a>のフォーマットに沿って、ベストオブな2021を振り返ろうと思う。</p>
<h2>ベストオブ飼ったもの</h2>
<p>今年の4月から飼いだしたアメリカンショートヘアーがかわいい。存在するだけで癒しがある。毛並みはシルバータビーでもうすぐ1歳という状況。</p>
<p><img src="https://blog-assets.kubosho.com/luna.jpg" alt="アメリカンショートヘアーが少し高い場所で座っている様子"></p>
<p>Instagramのアカウントもあるのでぜひフォローしてほしい。<br>
<a href="https://www.instagram.com/luna_sawayama/">https://www.instagram.com/luna_sawayama/</a></p>
<h2>ベストオブ買ったもの</h2>
<p><a href="https://www.apple.com/jp/apple-watch-series-7/">Apple Watch Series 7</a>は買って大正解なものだった。</p>
<p>基本的な時計機能はやっぱり便利なのと、付けているだけで運動の状況を記録できたり、さまざまな体調面のトラッキングをできたり、充電が早くできたり、通知を手元で見られたり、Suicaと連携できたりと買ってよかったなーと思うことが多い。</p>
<p>セルラーモデルを買うか少し悩んだが、iPhoneを持たないで出かけることが無いのでGPSモデルにした。それで困ったことは特に無い。</p>
<p>他に買ったもので良かったものは次の通り。</p>
<ul>
<li><a href="https://amzn.to/3zePCut">MOFT X スマホスタンド</a></li>
<li><a href="https://amzn.to/3HtWkjj">motorola edge 20</a></li>
<li><a href="https://amzn.to/3mL1TSe">TVアニメ『ウマ娘 プリティーダービー Season 2』 フルカラーパーカー ツインターボ</a></li>
<li><a href="https://amzn.to/3FEi3V4">SONY WF-1000XM4</a></li>
</ul>
<p>MOFT X スマホスタンドはスマホスタンドで悩むことが無くなって、とりあえず新しいスマホを買ったらこれを買えばいいという物になった。</p>
<p>motorola edge 20はそろそろ古くなってきたPixel 3を置き換えるスマホとして、前から気になっていて、ある日未使用品が新品の価格より大幅に安く出ていたのを発見して衝動買いした。</p>
<p>画面の大きさの割にはそんなに重くなくて思ったよりも使っている。やっぱり画面が大きいのは正義だと思う。</p>
<p>ツインターボのパーカーは、材質がいいのとそこそこ再現度もあるので割と着ている。シルエット的にも<a href="https://umamusume.jp/character/detail/?name=twinturbo">ツインターボ | ウマ娘 プリティーダービー 公式ポータルサイト|Cygames</a>にある原案のダボっとした感じが出ていて良い。</p>
<p>パーカーの材質については、<a href="https://fullgra.jp/item/sweatshirt/805/">製造元のページ</a>を見るとおそらくスパンデックスと書かれているものだと思う。今の季節で着るにはパーカーだけだと寒いので上着を重ね着している。</p>
<p>SONY WF-1000XM4は完全ワイヤレスイヤホンで音質・ノイズキャンセリング性能は文句ない。ケースも小さめなので邪魔にならない。</p>
<p>接続も基本安定しているが、自分が音質優先モードにしていることもあって、たまに片耳だけ一瞬途切れることがある。あとケースから取り出すときに落としそうになったり実際に落としてしまったりすることがある。この辺りは欠点だと思う。</p>
<h2>ベストオブ総括</h2>
<ul>
<li>中古分譲マンションを買った</li>
<li>猫を飼いだした</li>
<li>仕事ではアクセシビリティーをよりやっていくようにした</li>
<li>イラスト練習を始めた</li>
</ul>
<p>と、挙げてみると変化はあったものの停滞感を感じる1年ではあった。振り返ろうとしても何を書けばいいのか迷ってしまった。</p>
<p>来年はもう少し楽しんで生きたい。</p>
2020年の振り返りと2021年の目標立てで書いたことを振り返ろうとしたものの、あまりできてなくて記事を書く気持ちが高まらなかったので、ベストオブ2021 - dskdのフォーマットに沿って、ベストオブな2021を振り返ろうと思う。
2021-12-31T11:15:54.000Z
2022-11-28T16:03:11.000Z
Anker Eufy RoboVac L70 Hybrid が壊れた
tag:blog.kubosho.com,2021-12-15:entry://anker-eufy-robovac-l70-hybrid-is-broken
<p>Anker のロボット掃除機「Eufy RoboVac L70 Hybrid」を 2019 年 12 月に買って、今まで使っていました。</p>
<p>しかし買ってから 2 年経とうかというところで挙動がおかしくなり、また電池を充電してもすぐ残量が無くなるようになりました。</p>
<p>なので製品の修理または交換をしてもらおうと思ったのですが、そもそも修理対応はしていないのと、保証対象外だと有償での交換をしてくれないことが分かりました。</p>
<h2>症状</h2>
<p>2021 年 10 月頃(買ってから 1 年 10 ヶ月経過)のことでしたが、掃除を開始しようとして同じところをぐるんぐるん回る挙動がたまに見られるようになりました。挙動的にロボット掃除機の反乱のような挙動でした。</p>
<p>この状態になってしまうと、アプリから充電スペースに戻すボタンを押してもぐるんぐるん回り続け一向に戻れない状況になります。なので、自分でロボット掃除機を充電スペースに戻すしかない状態でした。</p>
<p>次に 2021 年 11 月頃に電池がいつまで経ってもフル充電されないようになり、明らかに稼働時間が少なくなりました。それまでは家全体を掃除できていたのですが、一部屋を掃除できるかできないかくらいになってしまいました。</p>
<p>そして 2021 年 11 月終わり頃からは一晩中充電しても全く充電されていない状態というのも増えてきました。</p>
<p>他にはたびたび記録した部屋の間取りを忘れて再び間取りの学習をし直すことも増えてきました。こうなると設定した進入禁止区域も消去されるので再度設定し直さないといけなくなります。</p>
<h2>保証対象外になると有償でも交換してくれない</h2>
<p>これらの症状が出たことから修理対応を依頼しようとしたものの、<a href="https://www.ankerjapan.com/pages/warranty">Anker の製品は注文日から 18 ヶ月間のみ保証される仕様</a>になっていました。保証期間内は Anker 側で不具合と認めた場合に新品と交換してくれます。</p>
<p>注文日から 18 ヶ月を過ぎた手元の Eufy RoboVac L70 Hybrid は、問い合わせたところ保証対象外となっていました。</p>
<p>保証対象外になると有償での修理や交換も受け付けないため、廃棄するか、Anker に問い合わせて製品を回収してもらうか、自力で修理するかの三択になります。</p>
<p>なお修理対応については<a href="https://www.ankerjapan.com/pages/warranty">保証内容</a>に次の一文がありました。</p>
<blockquote>
<p>弊社では修理対応を行っておりません。</p>
</blockquote>
<h3>交換用の電池は公式に売っていない</h3>
<p>今回使えなくなった Eufy RoboVac L70 Hybrid は電池が主にダメになったので、電池交換をすればまだ使えるかもしれないと思いました。</p>
<p>しかし Anker 公式で交換用の電池は売っていません。検索すると <a href="https://batt.co.jp/products/detail/59874218">[INR18650 M26-4S2P]Anker Eufy Robovac L70 Hybrid ロボット掃除機 バッテリーセル交換 - バッテリーリフレッシュ・セル交換の専門店</a> というページは出てきます。</p>
<p>ただ住所がレンタルオフィスだったり、バッテリーの送り先が私書箱になっていたり、<a href="https://batt.co.jp/order/">特定商取引に関する法律に基づく表記</a>に書いてある運営責任者の名前で検索するとあまり良くない情報が引っかかったりと、あまり信用できない感じです。あとは利用規約の「第20条 (不良品と保証及びリセルサービスの性質及び注意事項について)」がとにかく責任逃れをしようと目論見ている感じがします。これは製品の都合上仕方ないのかもしれませんが、とはいえ怪しいと感じてしまいます。</p>
<p>一方ルンバは、<a href="https://store.irobot-jp.com/category/ROOMBA_BATTERY/">アイロボット公式オンラインストアで交換用バッテリーがある</a>ので安心感があります。</p>
<h2>感想と学んだこと</h2>
<p>Anker Eufy RoboVac L70 Hybrid は性能の割に値段が高すぎず、スペックと値段を比較してもルンバがカバーしていない部分をちょうど埋めていたと感じます。</p>
<p>ルンバの現行モデルと Eufy RoboVac L70 Hybrid の値段・スペック比較を表にまとめてみると次の通りです。表のデータは<a href="https://www.irobot-jp.com/roomba/">アイロボット公式サイト</a>と<a href="https://www.rentio.jp/matome/2019/01/roomba-compare/">[最新] ルンバ i3+を含む全30種類を一覧表で比較!おすすめと選び方を解説 - Rentio PRESS[レンティオプレス]</a>を参考にしています。</p>
<table>
<thead>
<tr>
<th>名前</th>
<th>値段</th>
<th>吸引力</th>
<th>形</th>
<th>稼働時間</th>
<th>おすすめの間取り</th>
<th>床材</th>
<th>ゴミ捨ての頻度</th>
<th>ブラシ</th>
<th>清掃完了まで自動充電・再開</th>
<th>清掃履歴確認</th>
<th>間取り自動学習</th>
<th>進入禁止エリア設定</th>
<th>カメラセンサー</th>
<th>高機能なセンサー</th>
<th>ダストカットフィルター</th>
<th>ゴミが多い場所の検知</th>
<th>ブラーバとの連携</th>
</tr>
</thead>
<tbody>
<tr>
<td>s9+</td>
<td>186,780</td>
<td>x40</td>
<td>D型</td>
<td>120分</td>
<td>5部屋以上</td>
<td>ラグ・カーペット・フローリング</td>
<td>数か月に1回</td>
<td>ゴム製</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
</tr>
<tr>
<td>i7+</td>
<td>142,868</td>
<td>x10</td>
<td>丸型</td>
<td>75分</td>
<td>5部屋以上</td>
<td>ラグ・カーペット・フローリング</td>
<td>数か月に1回</td>
<td>ゴム製</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
</tr>
<tr>
<td>i3+</td>
<td>79,800</td>
<td>x10</td>
<td>丸型</td>
<td>75分</td>
<td>3部屋以上</td>
<td>ラグ・カーペット・フローリング</td>
<td>数か月に2回</td>
<td>ゴム製</td>
<td>〇</td>
<td>〇</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
</tr>
<tr>
<td>i7</td>
<td>109,868</td>
<td>x10</td>
<td>丸型</td>
<td>75分</td>
<td>5部屋以上</td>
<td>ラグ・カーペット・フローリング</td>
<td>使用後毎回</td>
<td>ゴム製</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
</tr>
<tr>
<td>i3</td>
<td>49,800</td>
<td>x10</td>
<td>丸型</td>
<td>75分</td>
<td>3部屋以上</td>
<td>ラグ・カーペット・フローリング</td>
<td>使用後毎回</td>
<td>ゴム製</td>
<td>〇</td>
<td>〇</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
</tr>
<tr>
<td>e5</td>
<td>39,800</td>
<td>x5</td>
<td>丸型</td>
<td>90分</td>
<td>1部屋以上</td>
<td>フローリング</td>
<td>使用後毎回</td>
<td>ゴム製</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>〇</td>
<td>〇</td>
<td>-</td>
</tr>
<tr>
<td>693</td>
<td>39,800</td>
<td>x1</td>
<td>丸型</td>
<td>90分</td>
<td>1部屋以上</td>
<td>フローリング</td>
<td>使用後毎回</td>
<td>通常</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Eufy RoboVac L70 Hybrid</td>
<td>54,800</td>
<td>2200 Pa</td>
<td>丸型</td>
<td>150分</td>
<td>3部屋以上</td>
<td>ラグ・カーペット・フローリング</td>
<td>使用後毎回</td>
<td>通常</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>〇</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>※</td>
</tr>
</tbody>
</table>
<p>※ Eufy RoboVac L70 Hybrid は水拭き機能が標準搭載されている。掃除機内のタンクに水を入れると水拭きをしてくれる。</p>
<p>この表からも分かるように、値段はルンバの i3+ と i3 の間くらいです。しかしルンバの上位モデルにある機能が搭載されている場合があります。実際に使っていて良かった機能は次の通りです。</p>
<ul>
<li>ルンバ i7 以上に備えている間取りの自動学習機能がついている</li>
<li>ルンバの最上級モデル以上の稼働時間</li>
<li>ブラーバを別途買わなくても水拭き機能がデフォルトで付いている</li>
</ul>
<p>ただ欠点も次の通り多く見られました。</p>
<ul>
<li>保証が切れた後は有償であっても製品を交換してくれないため、消耗品でない部分が壊れた場合は破棄か回収してもらうしか無い</li>
<li>ブラシ部分がルンバみたいにゴムではないため髪の毛などが絡まりやすい</li>
<li>水拭き機能を使うときは床の材質を検知してくれないので、事前にアプリで水拭き機能利用時に進入禁止とするエリアを設定しないといけない</li>
<li>段差などは検知してくれないので、気づくと玄関から出られなくなっている場合がある</li>
<li>たまに記憶した間取りがリセットされて最初から学習し直しになる</li>
</ul>
<p>特に保証が切れたら交換が無いのは、自分にとってロボット掃除機のみならず Anker の 1 万円以上の製品は買わない理由になりました。</p>
Anker の製品保証で残念に思った話です。
2021-12-15T15:34:36.000Z
2021-12-16T01:36:43.000Z
自分がアクセシビリティ向上に力を入れる理由
tag:blog.kubosho.com,2021-11-02:entry://why-focus-on-improving-accessibility
<p>いま自分は、担当サービスのアクセシビリティ向上を推進する「アクセシビリティタスクフォース」を率いる立場になっています(アクセシビリティタスクフォースについては <a href="https://www.concentinc.jp/works/abematv_202101/">AbemaTV ABEMA iOS版アプリのアクセシビリティ向上支援 | 事例紹介 | 株式会社コンセント</a> で少し触れられています)。</p>
<p>現在、アクセシビリティ向上の文化やプロセスを社内に浸透させていくため、さまざまな施策を考え実行しています。</p>
<p>ただそうやって活動していくうちに、ふと気づいたことがありました。自分はなぜアクセシビリティ向上に力を込めているかという言語化をしていないことです。</p>
<p>アクセシビリティ向上の推進は、個人でやるには大変で、組織としてやっていくのが一番良いと思っています。</p>
<p>ただ、組織としてアクセシビリティ向上をやっていくように伝えていく中で、個人の思いというのは活動の原動力として大事だと思っています。ここをあやふやにしてしまうと、ふとしたときにくじけてしまい折れてしまう気がします。</p>
<p>自分がそうやってくじけて折れてしまわぬよう、ここで自分のアクセシビリティ向上に対する思いを言語化してみます。</p>
<h2>元々の自分の考え</h2>
<p>自分は元々「かけがえのないモノをつくる」というビジョンを持っています。</p>
<p>「かけがえのないモノ」の定義は自分の中でも完全に定まってはいないですが、現時点だと「社会インフラになるもの」を作りたいという考えです。</p>
<p>また高校生のときから HTML と CSS を書いてきた経験もあり「インターネットを基礎とした社会インフラをつくる」ことを自分の理想として掲げています。</p>
<p>その「インターネットを基礎とした社会インフラ」の中で、自分の基盤が HTML と CSS というのもあって、Web フロントエンドで貢献したいという考えを持っていました。</p>
<h2>聴覚障害者からのサービスに対するツッコミ</h2>
<p>さてここで、2 年前の <a href="https://japan-a11y-conf.com/vol2/">Japan Accessibility Conference digital information vol.2</a> (以下、JA11YC) での体験を話します。</p>
<p><a href="https://abema.tv/video/title/89-66">ABEMA Prime</a> という番組内で、かつて <a href="https://abema.tv/channels/abema-news/slots/CTEDYRdBBoo76w">補聴器ユーザーの苦悩と葛藤</a> (リンク先では期限切れで動画視聴できず)というテーマを取り上げたことがありました。</p>
<p>この番組を放送したあと、聴覚障害者の方から「字幕をつけないのはなぜか。聴覚障害者を排除することに自覚がないのか、自覚があってもやるべきことをしていないのはなぜか(要約)」といった意見をもらいました。</p>
<p>そしてこの意見を書いた人が、JA11YC の場にいてそこで話をしました。</p>
<p>話した内容自体は 2 年前ということもあり忘れてしまっています(これに関しては申し訳ないです)。</p>
<p>ただ、ここで自分は「サービスを楽しめない人を出してしまうなんて自分で自分が恥ずかしい」という気持ちになり、サービスのアクセシビリティ向上をやっていくという思いを強くしました。</p>
<h2>視覚障害者を誘導する体験</h2>
<p>そして JA11YC に参加した帰りに、視覚障害者の人を渋谷駅まで誘導する機会がありました。どういう流れで誘導することになったか詳細は思い出せないですが、自分から手を挙げた気がします。</p>
<p>ただ誘導するのは初めてということもあり、果たしてちゃんと誘導できるのか少し緊張しました。</p>
<p>渋谷の道玄坂のほうは点字ブロックがほとんどありませんでした。そのため、点字ブロックに沿って歩けず、ほぼ自分に頼って歩かないといけない状況でした。なので自分は口頭でいまどの辺りにいるかを、場所の名前や道路の形状なども交えつつ案内しました。</p>
<p>結果的にはなんとか渋谷駅まで誘導することができて、電車に乗ったところまで確認しました。</p>
<p>誘導し終えたあとは、正直いつもは感じない疲れを感じましたが、「視覚障害者を誘導して気づいた点」で後述するように自分の中では良い経験でした。</p>
<p>なお道中で前から来た人がすれ違おうとしたときに、あまり避けずに軽く肩を当てた後こちらが悪いかのように軽い舌打ちをしたときは、イラッとしました。</p>
<p>相手側ももしかしたらイライラしていたとかで気持ちが良くなかったのかもしれないですが、それでもそれを自分に向けないでほしいという気持ちでした。</p>
<h3>視覚障害者を誘導して気づいた点</h3>
<p>この経験は自分があまり意識してこなかった点に気付かされたという意味で、良い経験でした。気づいたことを挙げると次の通りです。</p>
<ul>
<li>渋谷駅周辺に点字ブロックがない箇所が多い。駅内は割とあるが、路上には無いほうが多い</li>
<li>渋谷駅周辺の道路は人の多さに対して歩道が狭かったり分かれ道があったりで、視覚障害者に限らず自分も歩きづらい
<ul>
<li>ハロウィンみたいなイベントがあったときなんかはもう……</li>
</ul>
</li>
<li>ざわざわしているところを歩くのは、歩くのに必要な手がかりが聞きづらくなるという意味で大変そう</li>
<li>歩いているときに前から来た人が避けてくれるとは限らないのが、大変そう</li>
<li>前述のカンファレンスに参加するために行きはタクシーで来たということで、タクシー代がかかる場面が多そう</li>
</ul>
<p>自分が気づいていなかっただけで、不自由な部分は多く転がっているのを感じました。この経験が元となり、せめて自分が関わるところはアクセスしやすくしたいと考えるようになりました。</p>
<h2>なぜ、いまの会社・サービスでアクセシビリティ向上をやるのか?</h2>
<p>自分の考えとしてはこれまで書いた通りですが、ではなぜ、いまの会社・サービスでアクセシビリティ向上を推進するタスクフォースを作ってまでアクセシビリティ向上を推進しているのでしょうか?</p>
<p>その理由としては、最近<a href="https://www.cyberagent.co.jp/corporate/purpose/">会社でパーパスが発表された</a>ことにあります。</p>
<p>パーパスは存在意義を示すものです。発表されたパーパスは「新しい力とインターネットで日本の閉塞感を打破する」という内容で、アクション的な項目の中に「新しい未来のテレビ ABEMA を、いつでもどこでも繋がる社会インフラに」があります。</p>
<p>そうです、会社として ABEMA を社会インフラにすることを明言しています。これによって、自分のビジョンと会社の向いている方向が合致していると感じるようになりました。また、アクセシビリティタスクフォースを立ち上げたときに「いつでもどこでも繋がる」というのは考えていて、それが会社としても明言されるようになり嬉しくなりました。</p>
<p>これらを踏まえて、いまの会社・サービスでアクセシビリティ向上を推進していき、やがては担当サービス外にも影響を及ぼせる様になりたいと思いました。</p>
<h2>アクセシビリティ向上を推進する上で気をつけていること</h2>
<p><a href="https://speakerdeck.com/ymrl/webenziniatosite-imazhi-tuteokitai-webakusesibiritei?slide=11">Webエンジニアとして いま知っておきたい Webアクセシビリティ</a>というスライドにも書かれているように、特定の個性・状況・環境だけを考えて倫理観に訴えるのではなく、自分も含めたみんながもっと便利に使えて、結果ユーザーが増えていくようなベストな方法を考えていくことを意識しています。</p>
<p>アクセシビリティ "対応" と書くと後ろ向きな感じになりがちなのと、特定のユーザー向けに特別対応をすると捉えがちというのもあるので、前向きにやれるようにアクセシビリティ "向上" を一貫して使うのも気をつけている点です。</p>
<p>また自分たちだけでアクセシビリティ向上をやれるところからやっています。例を出すと WCAG の達成基準を満たしているかチェックしたり、アプリを VoiceOver や TalkBack を有効にした状態で触ってみたりなどといったことはやってきました。</p>
<p>ただ自分たちだけでは留まらない領域もあります。例を出すと字幕対応などが最たる例でしょう。</p>
<p>そういった部分では自分たち以外の社内の人ともっと対話して、お互いにとってベストな物を出していきたいと考えています。</p>
<p>なお、いまも自分たちだけで話を閉じているわけではなく、Slack のチャンネルでアクセシビリティについて話したり考えたりするチャンネルはあり、そこである機能のアクセシビリティをより良くするための相談などがされます。</p>
<p>しかし相談されるなどといった受動的なコミュニケーションだけでなく、能動的なコミュニケーションをより取っていこうと考えています。</p>
いま自分は、担当サービスのアクセシビリティ向上を推進する「アクセシビリティタスクフォース」を率いる立場になっています(アクセシビリティタスクフォースについては AbemaTV ABEMA iOS版アプリのアクセシビリティ向上支援 | 事例紹介 | 株式会社コンセント で少し触れられています)。
2021-11-02T00:00:03.000Z
2021-11-02T03:26:47.000Z
自分だけで進めようとしすぎるのをやめたい
tag:blog.kubosho.com,2021-10-28:entry://one-for-all-all-for-one
<p>最近やっている仕事がスムーズに進まないと感じていて、それはなぜだろうと考えました。考えた結果、チームで進めたほうがいいものなのに自分だけで進めようとしすぎているのではと考えました。</p>
<h2>この考えの根底にあるもの</h2>
<p>自分だけで進めようとするのは、一緒にやる相手からバカや無能とか思われたくないとか、失敗したくないという理由が根底にあって、そういうのを考えるなら一人でやったほうが楽だと感じてしまうのがあります。</p>
<p>その根底にある考えが根付いた元をたどると、過去に <a href="https://web.archive.org/web/20131224132322/http://inputxoutput.com/html-doctype/">HTMLでDOCTYPE宣言はなぜ必要か?</a> という記事を書いたことがありました(記事の内容自体はもうちょっと違うように書けたかなと思う内容ですが、そこは横に置きます)。</p>
<p>前述した記事を書いたとき、はてなブックマークのコメントでこの author は何も分かっていないといったようなコメントがかなり付いたり、Twitter でもツッコミが多々入ったのを見かけたりして、それらは今考えると正しい意見だったとは思います。ただその時は少なからず心が傷つきました。</p>
<p>この記事を書いた後は、W3C や WHATWG の仕様書や MDN などを参照することが増えました。原文(英語)もこの時から読むようになったと思います。</p>
<h2>考えによる困った状態</h2>
<p>ただ前述した「相手からバカや無能とか思われたくない、失敗したくない」という考えが、年を重ねるごとに広がっている気がしています。</p>
<p>考えが広がっている理由としては、環境の変化や、会社に勤務し始めてからの年数的には中堅かそれ以上になってきて、より高いレベルの成果を求められるであろうと考えていることがありそうです。</p>
<p>あとは自分だけで進めて成果の大部分を自分のものにしたいというのもありそうです。この考えは<a href="https://dic.nicovideo.jp/a/%E3%82%A2%E3%83%AC%E3%82%AA%E3%83%AC%E8%A9%90%E6%AC%BA">アレオレ詐欺</a>が嫌いという自分の特性もありそうです。</p>
<p>ただその考えが邪魔をして、自分が困っているという状態を上手くさらけ出せなかったり、ある程度自分の中で納得した状態にならないと事を進められない状態になったりしています。</p>
<p>またその納得した状態になったとしてもどこか詰めが甘い部分があって、深い議論になると答えに窮することがあります。</p>
<h2>理想状態</h2>
<p>本当は分からないところは分からないと素直に素早く誰かに言って、一緒に考えて答えを出せるように巻き込めるようになるのが理想とは考えています。</p>
<p>「早く行きたければ一人で進め、遠くまで行きたければ皆で進め」のことわざの通り、いま関わっているものは個人よりチームでやったほうが、より高い目標を達成できそうという考えはあります。</p>
<p>なので積極的に意見を求めたり、より多くの人を巻き込んでいったり、自分が知っているものを他の人に委譲したりということをよりやっていくことで、目的達成の近道の一つを作っていくことをしたいです。</p>
最近やっている仕事がスムーズに進まないと感じていて、それはなぜだろうと考えました。考えた結果、チームで進めたほうがいいものなのに自分だけで進めようとしすぎているのではと考えました。
2021-10-28T16:16:09.000Z
2021-10-29T03:42:38.000Z
9 連休の成果
tag:blog.kubosho.com,2021-09-27:entry://long-holidays
<p>2021 年 9 月の連休をこんな感じで過ごしたというメモ。</p>
<h2>課題</h2>
<p>今まで自分のことがあまり見えておらず、また先行きも不安があったため、どこか自信がなかった。</p>
<h2>成果</h2>
<p>今回過去を振り返り、今後何をやりたいかを考えたことで、ある程度自分の未来についてクリアになった。</p>
<p>また KanbanFlow を使ったタスクの一覧化とポモドーロ・テクニックによるタスクの実行が上手くいったのも自信を取り戻すきっかけになったと思う。</p>
<h2>やったこと</h2>
<h3>2021-09-20</h3>
<ul>
<li>ポートフォリオを作るにあたってのタスクの大まかなタスク分け</li>
<li>ポートフォリオ構成のアイデア出し</li>
<li>1 ~ 3 社目までの経験の洗い出し</li>
<li>腹筋ローラーを膝コロと立ちコロそれぞれ 7 回</li>
<li>イラスト練習(鼻周りの練習)</li>
</ul>
<h3>2021-09-21</h3>
<ul>
<li>4 ~ 5 社目までの経験の洗い出し</li>
<li>自分の強みと伸ばしたい点の洗い出し</li>
<li>自分を紹介するエレベーターピッチの作成</li>
<li>自己紹介ページのデザインカンプ作成</li>
<li>腹筋ローラーを膝コロと立ちコロそれぞれ 8 回</li>
<li>イラスト練習(鼻周りの練習続き)</li>
</ul>
<h3>2021-09-22</h3>
<ul>
<li>1on1 のための 1on1 をとある人に打診</li>
<li>ポートフォリオのデザインカンプ仕上げ</li>
<li>ポートフォリオ用の技術選定と検証</li>
<li>腹筋ローラー 膝コロ 10 回、立ちコロ 9 回</li>
<li>イラスト練習(頭蓋骨の練習)</li>
</ul>
<h3>2021-09-23</h3>
<ul>
<li>海へ行った</li>
<li>SOFT SKILLS を読み終えた</li>
<li>腹筋ローラー 膝コロ 10 回、立ちコロ 10 回</li>
<li>イラスト練習(頭蓋骨の側頭部を練習)</li>
</ul>
<h3>2021-09-24</h3>
<ul>
<li>美容院へ行った</li>
<li>領収書の依頼をした</li>
<li>Lit の検証・実装</li>
<li>ポートフォリオの経験部分の HTML を書いた</li>
<li>HIGH OUTPUT MANAGEMENT を読み進める</li>
<li>腹筋ローラー 膝コロ・立ちコロそれぞれ 10 回</li>
<li>イラスト練習(頭蓋骨 簡易バージョン)</li>
</ul>
<h3>2021-09-25</h3>
<ul>
<li>ポートフォリオの HTML マークアップ</li>
<li>Markdown を HTML に変換するスクリプト実装</li>
<li>11ty の設定</li>
<li>Lit を使って作ったコンポーネントで Markdown の内容を使うようにする</li>
<li>HIGH OUTPUT MANAGEMENT を読み進める</li>
<li>腹筋ローラー 膝コロ・立ちコロそれぞれ 10 回</li>
<li>イラスト練習(頭蓋骨の続き)</li>
</ul>
<h3>2021-09-26</h3>
<ul>
<li>F1 ロシアグランプリを楽しんだ</li>
<li>ポートフォリオの CSS を書いた(まだ途中)</li>
<li>ポートフォリオのアコーディオン実装</li>
<li>HIGH OUTPUT MANAGEMENT を読み進める</li>
<li>腹筋ローラー 膝コロ 11 回・立ちコロ 10 回</li>
<li>イラスト練習(頭蓋骨の側面)</li>
</ul>
2021 年 9 月の連休をこんな感じで過ごしたというメモ。
2021-09-27T00:00:00.000Z
2022-11-28T16:03:30.000Z
良い体験を提供してくれた人に対して対価を支払いたい
tag:blog.kubosho.com,2021-07-20:entry://i-want-to-pay-for-provided-good-experience
<p>7/18 に <a href="https://anilovekyoto.com/event_0718.html">Ani Love KYOTO presents 内田彩 Symphonic Concert ~ en and ett ~</a> というコンサートに行ってきた。</p>
<p>今回のシンフォニック・コンサートは、内田彩さんにとって観客を入れるコンサートが約 1 年と半年ぶりだった。<br>
それを聞いて、確かに去年はオンライン配信限定のコンサートしかなかったと思い出した。</p>
<p>そんな久しぶりにやったコンサートは、シンフォニック・コンサートというオーケストラを従えた今までにない形式のコンサートだった。<br>
昨今のコンサートでコールなどの声出しができないことに対して、声出しできないことを気にしなくてもよくて、かつやったことない形式のコンサートをやろうと思ったと話していた。</p>
<p>昨今のこういった興行に対して良い影響があるとはいえない状況下で、柔軟な考えを持ちそして実行できる、内田彩さんや周りのスタッフに対し敬意を表したいと思った。</p>
<p>コンサート自体はオーケストラが演奏する前提のアレンジで普段とは違う形式で曲を聴けたのがよかったし、会場の音響の良さもあってボーカルとオーケストラどちらも良い感じに調和して聴けた。<br>
あとアンコールのときの誕生日サプライズがオーケストラ演奏による Happy Birthday to You という豪華なもので、すごいを通りこして笑うしかなかった。</p>
<p>関東圏から会場のロームシアター京都に行くため、正直時間とお金両方ともかかった。</p>
<p>それでも行って大変良かった。それはとても良い体験を得られたからだ。</p>
<p>そしてこのコンサートを通して自分が思ったのは「良い体験を提供してくれた人に対価を支払いたい」ということだった。</p>
<p>体験を提供する側は体験を提供するために投資しているし、投資している額は少なくないと思う。<br>
そうして提供された良いものに対して、良いものを提供してもらった対価は払いたいし、対価を払わないと存続できないと思う。</p>
<p>ということで、今後もこういった新しい体験を提供してほしいという期待も込めてグッズを買った。</p>
7/18 に Ani Love KYOTO presents 内田彩 Symphonic Concert ~ en and ett ~ というコンサートに行ってきた。
2021-07-20T12:00:00.000Z
2022-07-31T05:21:33.000Z
Twitterの右側サイドバーを消す
tag:blog.kubosho.com,2021-03-06:entry://remove-twitter-trend
<p>Twitterのトレンドは見るたびにイラつきを覚えます。そんなにイラつきを覚えるようなら見なければいいし、そもそもTwitterをやめろという話かもしれません。</p>
<p>ただ次のツイートにあるようにある意味で期待通りの報酬を得られる行為となります。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">インターネットでQOLを1番下げる行為は、間違いなく「嫌いな人間/集団/コンテンツを自分から見に行って、嫌なものを見つけて、嫌なのを確認する」事なんだけど、これはある意味で「期待通りの報酬を得られる」行為なので、常習化を招きやすいんだよな。人生には得てはいけない成功体験があるというな。</p>— rei@生きてるだけで疲労困憊発売延期 (@rei10830349) <a href="https://twitter.com/rei10830349/status/1178553747770753025?ref_src=twsrc%5Etfw">September 30, 2019</a></blockquote>
<p>そのためTwitterのトレンドを見てしまうことが多くトレンドを見るたびに後悔していました。ただやめられなくなっていて正直なところ常習化していました。</p>
<h2>なぜTwitterのトレンドを見てしまうのか</h2>
<p>TwitterのページをWeb上で見ると自然とトレンドが目に入ってきます。普段見ているTwitterの画面は画像の通りだと思います。</p>
<p><img src="https://blog-assets.kubosho.com/twitter_home_before.png" alt="CSSを調整する前のTwitterは3カラムになっている"></p>
<p>左サイドバーにナビゲーション、中央にツイート一覧、そして右サイドバーにTwitter内の回遊リンク一覧がある構成です。</p>
<p>この構成だと右サイドバーのTwitter内の回遊リンク一覧が目に入ります。特に「いまどうしてる?」というタイトルが付けられたTwitter内のトレンド一覧が目に入ります。</p>
<p>これはTwitter側でトレンドを見てもらうことでTwitter内を回遊してくれて、結果としてTwitter内で追っているKPIを達成できるというデータがあるのでしょう。なので目に入る位置にトレンドがあるのと、トレンドの先頭は広告枠になっているのだと思います。</p>
<p>ただTwitterのトレンドを目に入れたくない立場からすればとにかく消えてほしいものです。あとついでにおすすめユーザーも邪魔な気がしてきました。</p>
<h2>Twitterのトレンドを視界から消す(ついでにおすすめユーザーも)</h2>
<p>ということでTwitterのトレンドを視界から消します。</p>
<p>今回は<a href="https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=ja">Stylus</a>を使って、Twitter側で定義されているCSSを上書きしてTwitterのトレンドのみならず右サイドバーごと非表示にしました。</p>
<p>なおTwitterのトレンドを消す方法として、Chrome向けのTwitter拡張機能である<a href="https://chrome.google.com/webstore/detail/calm-twitter/cknklikacoaeledfaldmhabmldkldocj?hl=ja">おだやかTwitter</a>や<a href="https://chrome.google.com/webstore/detail/simplified-twitter/kfopmjhmejbgomgeajemgpgpbckpoopg/related">Simplified Twitter</a>を入れる方法や、<a href="https://www.tsukutarou.net/entry/Twitter-Trend-Shutout">地域を変更してトレンドのみ表示できないようにする</a>方法もあります。</p>
<h3>Twitterの右サイドバーを削除するときの課題と解決方法</h3>
<p>TwitterはReact Native for Webを使っています。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">If you use Twitter Lite you're now using a web app rendered by React Native for Web</p>— Nicolas (@necolas) <a href="https://twitter.com/necolas/status/913877194199359488?ref_src=twsrc%5Etfw">September 29, 2017</a></blockquote>
<p>これは今も変わってなさそうでHTMLに定義されているクラス名はランダムな文字列です。</p>
<p>このためクラス名を元にスタイル定義をすると、将来の変更でスタイルが適用されなくなりそうです。</p>
<p>そのためStylus上で <code>data-*</code> 属性のセレクタに対してスタイル定義をすれば将来的に壊れにくくなりそうという考えを持ちました。これに従って書いたCSSは次の通りです。</p>
<pre class="language-css"><code class="language-css"><span class="token selector"><span class="token attribute"><span class="token punctuation">[</span><span class="token attr-name">data-testid</span><span class="token operator">=</span><span class="token attr-value">'primaryColumn'</span><span class="token punctuation">]</span></span></span> <span class="token punctuation">{</span>
<span class="token property">max-width</span><span class="token punctuation">:</span> <span class="token number">600</span><span class="token unit">px</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector"><span class="token attribute"><span class="token punctuation">[</span><span class="token attr-name">data-testid</span><span class="token operator">=</span><span class="token attr-value">'sidebarColumn'</span><span class="token punctuation">]</span></span></span> <span class="token punctuation">{</span>
<span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>このCSSを適用したTwitterのスクリーンショットを見てみましょう。</p>
<p><img src="https://blog-assets.kubosho.com/twitter_home_after.png" alt="CSSを調整した後のTwitterは2カラム表示になっている。右サイドバーは非表示になっている"></p>
<p>見事にTwitterの右サイドバーを非表示にできています。今回の目的を達成しました。</p>
<h2>まとめ</h2>
<p>正直Twitterを見ないようにしたりアカウントを削除して何もかも見れなくしたりしたほうが手っ取り早いです。</p>
<p>しかし他サービスのログインに使っていたり、DMでやり取りしている人がいたり、拡散される役目をTwitterに依存しがちだったり、いろいろやめられない状況でした。なので今回は妥協案として右サイドバーを非表示にしました。</p>
<p>Twitter Blueにトレンドなどを削除する機能を作ってほしいですが、広告枠の扱いなども考えると難しそうです。</p>
Twitter のトレンドを見ると、イラつきを覚えるようになりました。そんなにイラつきを覚えるようなら見なければいいし、そもそも Twitter やめろという話はあります。
2021-03-06T00:00:00.000Z
2022-11-28T16:44:31.000Z
PreactとTypeScriptを使った環境でStorybookを使う方法
tag:blog.kubosho.com,2021-01-14:entry://preact-typescript-storybook
<p>Preact と TypeScript を使った環境で Storybook を使おうとしたら以下のエラーが出ました。</p>
<p><img src="https://blog-assets.kubosho.com/storybook_error.png" alt="Storybook上で出たエラー。ReferenceError: h is not definedと出ている。"></p>
<p>原因は Storybook を使うために必要なパッケージと Babel の設定が足りなかったことでした。</p>
<p>なので、<a href="https://github.com/storybookjs/storybook/tree/master/lib/cli#manually-specify-project-type">storybook/lib/cli#Manually specify project type</a>を参考に、次のコマンドを実行します。</p>
<pre class="language-shell"><code class="language-shell">npx -p @storybook/cli sb init --type preact
</code></pre>
<p>そして <code>.babelrc.js</code> を次のような設定にします。</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> presets <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'@babel/preset-env'</span><span class="token punctuation">,</span> <span class="token string">'@babel/preset-typescript'</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> plugins <span class="token operator">=</span> <span class="token punctuation">[</span>
<span class="token punctuation">[</span>
<span class="token string">'@babel/plugin-transform-react-jsx'</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span>
runtime<span class="token operator">:</span> <span class="token string">'automatic'</span><span class="token punctuation">,</span>
importSource<span class="token operator">:</span> <span class="token string">'preact'</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
module<span class="token punctuation">.</span><span class="token property-access">exports</span> <span class="token operator">=</span> <span class="token punctuation">{</span> presets<span class="token punctuation">,</span> plugins <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
<p>これで Yarn を使っている環境であれば <code>yarn storybook</code> をターミナル上で実行することで、Storybook が表示されるようになります。</p>
<h2>参考にしたページ</h2>
<ul>
<li><a href="https://github.com/preactjs/preact-compat/issues/541">Uncaught ReferenceError: h is not defined · Issue #541 · preactjs/preact-compat</a></li>
</ul>
Preact と TypeScript を使った環境で Storybook を使おうとしたら以下のエラーが出ました。
2021-01-14T00:00:00.000Z
2022-11-28T14:57:55.000Z
2020年の振り返りと2021年の目標立て
tag:blog.kubosho.com,2020-12-31:entry://2020-to-2021
<p>今年の振り返りと来年の OKR を書いていく。</p>
<p><img src="https://blog-assets.kubosho.com/marriage.jpg" alt="提出した婚姻届の写真"></p>
<h2>2020 年の振り返り</h2>
<p>世の中の大きな出来事と言えば、新型コロナウイルスの流行が挙げられる。自分も 2 月の終わりくらいから在宅勤務だった。</p>
<p>個人的に大きな出来事は 8 年付き合った(その内 5 年は同棲していた)相手と結婚したことが挙げられる。<br>
もう結婚指輪も注文していて、あとは届くのを待つだけという状態になっている。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">結婚してきた <a href="https://t.co/f0TDGK2KQ5">pic.twitter.com/f0TDGK2KQ5</a></p>— kubosho (@kubosho_) <a href="https://twitter.com/kubosho_/status/1339464307810074624?ref_src=twsrc%5Etfw">December 17, 2020</a></blockquote>
<p>この結婚ツイートにかなりの反響があったのと、<a href="https://www.amazon.jp/hz/wishlist/ls/2GJ4WDKLYFOPU?ref_=wl_share">欲しい物リスト</a>からさまざまな物が贈られてきたのは正直ビックリした。</p>
<p>仕事では主に以下のことをやった。</p>
<ul>
<li><a href="https://github.com/Financial-Times/polyfill-library">Financial-Times/polyfill-library</a>を使った differential polyfill serving の実装</li>
<li><a href="https://web.dev/granular-chunking-nextjs/">Improved Next.js and Gatsby page load performance with granular chunking</a>を元にした granular chunks の実装</li>
<li><a href="https://www.cyberagent.co.jp/news/detail/id=25533">テレビ&ビデオエンターテインメント「ABEMA(アベマ)」にて、話題の新作映画、国内外の人気ドラマ、大ヒットアニメなど多彩なジャンルの作品のレンタルが可能に</a>で紹介されているレンタル機能の一部機能を実装</li>
<li>アクセシビリティ周りでの顕在的・潜在的な課題の洗い出しと整理</li>
<li>アクセシビリティの品質目標とビジョン立て</li>
</ul>
<p>とはいえ、やりきれなかった部分もあった。来年はもっと頑張りたい気持ち。</p>
<h2>2021 年の OKR</h2>
<h3>羞恥心をなくす</h3>
<h4>モチベーション</h4>
<p>勉強など何かするでも見せたがらない性格を直したい。</p>
<blockquote>
<p>恥を感じる状況から逃げたい、もしくは恥を感じた記憶を消したいと思う「回避・隠蔽反応」<br>
人に見られている、人に笑われていると思う「被笑感」<br>
<a href="https://ja.wikipedia.org/wiki/%E7%BE%9E%E6%81%A5%E5%BF%83">羞恥心 - Wikipedia</a>より</p>
</blockquote>
<h4>OKR</h4>
<table>
<thead>
<tr>
<th>key</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Objective</td>
<td>3 つ以上のチャネルで発信を継続的におこなえている</td>
</tr>
<tr>
<td>Key Result</td>
<td>Twitter のフォロワーを 3,000 人以上にする</td>
</tr>
<tr>
<td>Key Result</td>
<td>YouTube のチャンネル登録数を 1,000 人以上にする</td>
</tr>
<tr>
<td>Key Result</td>
<td>ブログの DAU を 500 人以上にする</td>
</tr>
</tbody>
</table>
<h4>何をやるか</h4>
<ul>
<li>途中の過程を積極的に公開する</li>
<li>更新を苦にならないように効率化を図る</li>
</ul>
<h3>収入源を複数にする</h3>
<h4>モチベーション</h4>
<p>会社を辞めることになっても食いぱっぐれないようにしたい。</p>
<h4>OKR</h4>
<table>
<thead>
<tr>
<th>key</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Objective</td>
<td>本業以外の粗利が年 50 万円を超えている</td>
</tr>
<tr>
<td>Key Result</td>
<td>投資信託以外に投資を始める。年利 5%で運用する</td>
</tr>
<tr>
<td>Key Result</td>
<td>本業の仕事効率化を図り、今までやったことがない分野の勉強をして、その結果を 5 回以上発信する</td>
</tr>
</tbody>
</table>
<h4>何をやるか</h4>
<ul>
<li>開設した松井証券と SBI 証券の口座を活用する
<ul>
<li>どちらかの口座でつみたて NISA を始める</li>
</ul>
</li>
</ul>
<h3>美少女イラストを描けるようになる</h3>
<h4>モチベーション</h4>
<p>可愛い子を自分の手で生み出せるようになりたい。<br>
顔・服装・ポーズなどを自分の好きなようにできるようにしたい。</p>
<h4>OKR</h4>
<table>
<thead>
<tr>
<th>key</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Objective</td>
<td>全身を描いたイラストを 3 本 pixiv に投稿できている</td>
</tr>
<tr>
<td>Key Result</td>
<td>ソッカの美術解剖学ノートを読破する</td>
</tr>
<tr>
<td>Key Result</td>
<td>ペンタブや絵を描くためのソフトウェアを手足のように使えている</td>
</tr>
</tbody>
</table>
<h4>何をやるか</h4>
<ul>
<li>ソッカの美術解剖学ノートでの勉強過程を Twitter にあげる</li>
<li>毎日 1 時間をイラストの練習に充てる</li>
</ul>
<h3>中国語を話せるようになる</h3>
<h4>モチベーション</h4>
<p>妻が中国人なので妻や妻の親と中国語で話せるようになりたい。</p>
<h4>OKR</h4>
<table>
<thead>
<tr>
<th>key</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Objective</td>
<td>TBD</td>
</tr>
<tr>
<td>Key Result</td>
<td>TBD</td>
</tr>
<tr>
<td>Key Result</td>
<td>TBD</td>
</tr>
</tbody>
</table>
<h4>何をやるか</h4>
<ul>
<li>毎日 30 分を中国語の勉強に充てる
<ul>
<li>発音の練習と文法の勉強をそれぞれ 15 分ずつやる</li>
</ul>
</li>
</ul>
<h2>まとめ</h2>
<p>今年は新型コロナウイルスの影響でさまざまなことが変わっていった年だった。<br>
今年の年明けのタイミングではこんなことになるとは思っていなかったけど、だんだんと変化に慣れつつあるし、来年は変化を乗りこなすくらいの勢いで行きたい。</p>
今年の振り返りと来年の OKR を書いていく。
2020-12-31T00:00:00.000Z
2022-07-31T05:14:02.000Z
2020年の F1 の振り返りと2021年の F1 に期待すること
tag:blog.kubosho.com,2020-12-25:entry://f1-2020-and-f1-2021
<p><a href="https://adventar.org/calendars/4957">Splathon vol.1 Advent Calendar 2020</a> の 23 日目の記事となる。<br>
前日は<a href="https://naomi14.hatenablog.com/entry/2020/12/22/091750">今年のふるさと納税 - Naomi says,</a> という記事だった。</p>
<p>今年は個人的にスプラトゥーン関連でいくつか嬉しいことがあった。</p>
<ul>
<li>大王戦という Splathon 内のウデマエに応じて tier が分かれるリーグ戦で、将軍 tier(S+~ X2200?くらい)で優勝した</li>
<li>全ガチルール通して初めてガチエリアで X に到達した</li>
</ul>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/Splathon?src=hash&ref_src=twsrc%5Etfw">#Splathon</a> 内のリーグ対抗戦「大王戦」の将軍tier優勝した!!!!!!!! <a href="https://t.co/rMkeVyxBlh">pic.twitter.com/rMkeVyxBlh</a></p>— kubo5hogun (@kubo5ho) <a href="https://twitter.com/kubo5ho/status/1325817586114842625?ref_src=twsrc%5Etfw">November 9, 2020</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Xいったああああああ!!!!!!111 <a href="https://twitter.com/hashtag/Splatoon2?src=hash&ref_src=twsrc%5Etfw">#Splatoon2</a> <a href="https://twitter.com/hashtag/%E3%82%B9%E3%83%97%E3%83%A9%E3%83%88%E3%82%A5%E3%83%BC%E3%83%B32?src=hash&ref_src=twsrc%5Etfw">#スプラトゥーン2</a> <a href="https://twitter.com/hashtag/NintendoSwitch?src=hash&ref_src=twsrc%5Etfw">#NintendoSwitch</a> <a href="https://t.co/0w3Lv6k4ug">pic.twitter.com/0w3Lv6k4ug</a></p>— kubo5hogun (@kubo5ho) <a href="https://twitter.com/kubo5ho/status/1336303925062877185?ref_src=twsrc%5Etfw">December 8, 2020</a></blockquote>
<p>こういったことについて記事を書こうかと思ったが、それよりも F1 について語りたかったので、今年の F1 の振り返りと来年の F1 で期待する点を書いていく。</p>
<p>書きたいことを書いたら長くなったし、記事の内容はスプラトゥーンと関係ないけど気にしない。</p>
<h2>2020 年シーズンの振り返り</h2>
<p>今年は新型コロナウイルスが世界的に蔓延した年ということもあって、異例づくしのシーズンになった。<br>
今シーズンを簡単に振り返ると以下の通りになる。</p>
<ul>
<li>開幕戦のオーストラリアグランプリが直前で F1 チームのスタッフに新型コロナウイルスに感染した人が出てキャンセル
<ul>
<li>この結果シーズン開幕が 7 月までずれこむ</li>
</ul>
</li>
<li>例年と比べて番狂わせの多さ
<ul>
<li>とはいえやっぱり 3 カテゴリーに分かれた F1</li>
</ul>
</li>
<li>やっぱり強かったメルセデスとルイス・ハミルトン、前人未踏のチーム 7 連覇とミハエル・シューマッハーに並ぶ 7 度目のドライバーズチャンピオン</li>
<li>チャンピオンを狙ったレッドブル、期待外れな結果に終わる</li>
<li>トップ 3 の座から凋落したフェラーリ</li>
<li>復活し始めた古豪マクラーレン</li>
<li>新型コロナウイルスの蔓延によって、スーパーサブになったニコ・ヒュルケンベルグとジョージ・ラッセル</li>
<li>九死に一生を得たロマン・グロージャン</li>
</ul>
<h3>3 カテゴリーに分かれている F1</h3>
<p>今年のコンストラクターランキングを見ると、メルセデスが圧倒的な差で 1 位になっていて、これに続いてレッドブルが 2 位となっている。<br>
あとは 3 位~ 7 位が拮抗していて、8 ~ 10 位が拮抗するランキングになっている。</p>
<p>こういったポイントの獲得数がだいたい 3 カテゴリーに分かれる構造は、2014 年に車体やエンジン周りの規則が変更されてからあまり変わっていない。</p>
<table>
<thead>
<tr>
<th>順位</th>
<th>チーム</th>
<th>ポイント</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>メルセデス</td>
<td>573</td>
</tr>
<tr>
<td>2</td>
<td>レッドブル・ホンダ</td>
<td>319</td>
</tr>
<tr>
<td>3</td>
<td>マクラーレン</td>
<td>202</td>
</tr>
<tr>
<td>4</td>
<td>レーシングポイント</td>
<td>195</td>
</tr>
<tr>
<td>5</td>
<td>ルノー</td>
<td>181</td>
</tr>
<tr>
<td>6</td>
<td>フェラーリ</td>
<td>131</td>
</tr>
<tr>
<td>7</td>
<td>アルファタウリ・ホンダ</td>
<td>107</td>
</tr>
<tr>
<td>8</td>
<td>アルファロメオ</td>
<td>8</td>
</tr>
<tr>
<td>9</td>
<td>ハース</td>
<td>3</td>
</tr>
<tr>
<td>10</td>
<td>ウィリアムズ</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>(<a href="https://www.formula1.com/en/results.html/2020/team.html">データは F1 公式サイトより引用</a>)</p>
<p>2016 年辺りからトップ 3 はメルセデス・フェラーリ・レッドブルで固定されていたが、今年はメルセデスとレッドブルがトップ 2 で、マクラーレン・レーシングポイント・ルノー・フェラーリ・アルファタウリがその次、そしてアルファロメオ・ハース・ウィリアムズが続くという序列になっている。</p>
<p>メルセデスはだいたい最速の車を持っていて、そこにフロントロー(最前列)に 2 台同時に並べるドライバーを揃えているのが強い。</p>
<p>レッドブルやフェラーリは最速の車を持っていることもあったものの、ドライバーの腕が揃ってなかったり、戦略面で稚拙だったりと、持っているものを生かし切れない場面がメルセデスと比較すると多い。</p>
<p>そのためシーズンオフのテストで 2 チームが有望な結果を示していても、シーズンに入るとメルセデスが勝ち続けるということがこの数年続いている。</p>
<h4>番狂わせがあった今シーズン</h4>
<p>2016 年からはメルセデス・フェラーリ・レッドブルという 3 チームのどれかに所属していないと、頑張って表彰台に乗ったとしても 3 位止まりで 2 位以上の結果はほぼ得られないという状況が続いていた。</p>
<ul>
<li><a href="https://ja.wikipedia.org/wiki/2016%E5%B9%B4%E3%81%AEF1%E4%B8%96%E7%95%8C%E9%81%B8%E6%89%8B%E6%A8%A9#%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%BC%E3%82%BA%E3%83%BB%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89%E3%83%BB%E3%83%81%E3%83%A3%E3%83%B3%E3%83%94%E3%82%AA%E3%83%B3%E3%82%B7%E3%83%83%E3%83%97%EF%BC%88%E8%A3%BD%E9%80%A0%E8%80%85%E9%83%A8%E9%96%80%EF%BC%89">2016 年コンストラクターズランキング</a></li>
<li><a href="https://ja.wikipedia.org/wiki/2017%E5%B9%B4%E3%81%AEF1%E4%B8%96%E7%95%8C%E9%81%B8%E6%89%8B%E6%A8%A9#%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%BC%E3%82%BA%E3%83%BB%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89%E3%83%BB%E3%83%81%E3%83%A3%E3%83%B3%E3%83%94%E3%82%AA%E3%83%B3%E3%82%B7%E3%83%83%E3%83%97%EF%BC%88%E8%A3%BD%E9%80%A0%E8%80%85%E9%83%A8%E9%96%80%EF%BC%89">2017 年コンストラクターズランキング</a></li>
<li><a href="https://ja.wikipedia.org/wiki/2018%E5%B9%B4%E3%81%AEF1%E4%B8%96%E7%95%8C%E9%81%B8%E6%89%8B%E6%A8%A9#%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%BC%E3%82%BA%E3%83%BB%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89%E3%83%BB%E3%83%81%E3%83%A3%E3%83%B3%E3%83%94%E3%82%AA%E3%83%B3%E3%82%B7%E3%83%83%E3%83%97%EF%BC%88%E8%A3%BD%E9%80%A0%E8%80%85%E9%83%A8%E9%96%80%EF%BC%89">2018 年コンストラクターズランキング</a></li>
<li><a href="https://ja.wikipedia.org/wiki/2019%E5%B9%B4%E3%81%AEF1%E4%B8%96%E7%95%8C%E9%81%B8%E6%89%8B%E6%A8%A9#%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%BC%E3%82%BA%E3%83%BB%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89%E3%83%BB%E3%83%81%E3%83%A3%E3%83%B3%E3%83%94%E3%82%AA%E3%83%B3%E3%82%B7%E3%83%83%E3%83%97%EF%BC%88%E8%A3%BD%E9%80%A0%E8%80%85%E9%83%A8%E9%96%80%EF%BC%89">2019 年コンストラクターズランキング</a></li>
</ul>
<p>ところが<a href="https://ja.wikipedia.org/wiki/2020%E5%B9%B4%E3%81%AEF1%E4%B8%96%E7%95%8C%E9%81%B8%E6%89%8B%E6%A8%A9#%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%BC%E3%82%BA%E3%83%BB%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89%E3%83%BB%E3%83%81%E3%83%A3%E3%83%B3%E3%83%94%E3%82%AA%E3%83%B3%E3%82%B7%E3%83%83%E3%83%97%EF%BC%88%E8%A3%BD%E9%80%A0%E8%80%85%E9%83%A8%E9%96%80%EF%BC%89">2020 年コンストラクターズランキング</a>を見て分かるように、今年はコンストラクターズランキング 7 位以上はどちらかまたは片方のドライバーが 2 位以上になっている結果になった。</p>
<p>特にイタリアグランプリではピエール・ガスリーが、アブダビグランプリではセルジオ・ペレスがそれぞれ初優勝した。</p>
<p>ピエール・ガスリーは前身のスクーデリア・トロロッソ時代も数えて、スクーデリア・アルファタウリとホンダというタッグになってから 50 戦目という節目で優勝し、セルジオ・ペレスは参戦から 190 戦目という最も遅く優勝するという記録に残る優勝だった。</p>
<p>ちなみに思いもよらぬ優勝をした 2 人は、共に表彰台で座り込むというシンクロを見せた。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">P1!! My first victory in F1!!🏆<br>I’m lost for words, still struggling to realise, its just amazing!! <br>Everything was perfect, just missed the tifosis down under the podium. <a href="https://twitter.com/AlphaTauri?ref_src=twsrc%5Etfw">@alphatauri</a> we have done it!! Thanks everyone for all the messages & support!! Today is a day I’ll remember. <a href="https://t.co/3eILYSMsIu">pic.twitter.com/3eILYSMsIu</a></p>— PIERRE GASLY 🇫🇷 (@PierreGASLY) <a href="https://twitter.com/PierreGASLY/status/1302677964589592577?ref_src=twsrc%5Etfw">September 6, 2020</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ペレスキャリア10年目初優勝おめでとう<br>ガスリーと同じ構図だけどやっぱこうなるよね<a href="https://twitter.com/hashtag/F1jp?src=hash&ref_src=twsrc%5Etfw">#F1jp</a> <a href="https://t.co/qBZOZZWj27">pic.twitter.com/qBZOZZWj27</a></p>— ゆうsan (@yuu0222ura) <a href="https://twitter.com/yuu0222ura/status/1335661305798172673?ref_src=twsrc%5Etfw">December 6, 2020</a></blockquote>
<h3>相変わらず強いメルセデスとルイス・ハミルトン</h3>
<p>やっぱり今年もメルセデスとルイス・ハミルトンは強かった。</p>
<p>シーズン開始前はレッドブルとマックス・フェルスタッペンが喰おうとし、開幕戦ではチームメイトのバルテリ・ボッタスがルイス・ハミルトンを喰おうとしていた。</p>
<p>そういった挑戦者を持ち前の実力と安定感でなぎ倒し、終わってみればほぼ優勝し続けた結果としてのミハエル・シューマッハーに並ぶ 7 回目のワールドチャンピオンとなった。</p>
<p>特にイギリスグランプリのルイス・ハミルトンの走りは圧巻で、ファイナルラップに左前輪タイヤがパンクして半周以上速度を落とした走りにならざるを得ない状況になったにも関わらず、逃げ切って優勝するという離れ業をした。</p>
<p>このときのレースハイライト動画を見ると分かるが、タイヤ交換したマックス・フェルスタッペンが後ろからぐんぐんと追いつくなか、最後まで追いつかせずにチェッカーフラッグを受けるという意味の分からないことをやっている。</p>
<iframe src="https://www.youtube.com/embed/HmEsqWosuS8?start=326" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>このときは元々 2 位を走っていたバルテリ・ボッタスのタイヤがパンクして速度を落としたため、新たに 2 位になったマックス・フェルスタッペンがファステストラップ狙いとタイヤの摩耗に対する安全策として、ファイナルラップの前にピットインしてタイヤ交換をしていた。</p>
<p>結果的にこのことがルイス・ハミルトンにとって良いほうに作用し、タイヤがパンクして三輪で走らざるを得なくなっても勝ったという結果に繋がった。</p>
<p>これがもしファイナルラップでなくその 1 周か 2 周前にパンクしていたとか、バルテリ・ボッタスのタイヤがパンクしてなかったら優勝できてなかったと思われる。</p>
<p>ワールドチャンピオンを複数回取るドライバーは実力のみならず運も備わっているのかもしれない。</p>
<h3>期待外れに終わったレッドブル・ホンダ</h3>
<p>今年はレッドブルの車体側とホンダ製のパワーユニットが去年比で熟成され、いよいよチャンピオンチームであるメルセデスへ挑み、そしてマックス・フェルスタッペンが最年少チャンピオンの座を奪えるかもしれない。そういった期待がシーズン前のテストだとあった。</p>
<p><a href="https://www.as-web.jp/f1/569861?all">【レッドブル密着】RB16 の仕上がりに満足の表情。万全の状態で開幕へ/第 2 回 F1 バルセロナテスト最終日</a>や、<a href="https://www.as-web.jp/f1/569872?all">『ハイ・レーキ』継承のレッドブル・ホンダ RB16。低速域のダウンフォースも増加/全チーム戦力分析(1)</a>にもあるように、シーズン前のテストでは有望そうに見えていた。</p>
<p>しかし<a href="https://www.as-web.jp/f1/569391?all">スピンを繰り返すフェルスタッペン。僚友アルボンはレッドブル RB16 への懸念を否定</a>に書いてある通り、シーズン前のテストで両ドライバーがスピンを繰り返すという懸念材料はあった。</p>
<p>結果としてはシーズン通して 2 人のドライバーが合計 13 回の表彰台に乗り、内 2 回は 1 位という結果を残したものの、エースドライバーのマックス・フェルスタッペンにチームメイトのアレキサンダー・アルボンは匹敵することができなかったという印象だった。</p>
<p>アレキサンダー・アルボンは最後まで過敏な挙動を示すリヤを持った車を扱いきれず、予選で常にチームメイトから 0.4 ~ 0.5 秒離されていた。</p>
<p>こういったことがありつつも、パワーユニットの性能が求められるシルバーストン・サーキットでおこなわれた 70 周年記念グランプリで<a href="https://formula1-data.com/article/70th-anniversary-race-digest-2020">マックス・フェルスタッペンが優勝</a>したり、2014 年以降メルセデスがずっと勝ち続けていたアブダビグランプリで<a href="https://formula1-data.com/article/abudhabi-race-digest-2020">マックス・フェルスタッペンが優勝、アレクサンダー・アルボンも久しぶりに良いペースを見せ 4 位に入る</a>など、来季に向けて良い兆しは見えつつある。</p>
<p>来年はマックス・フェルスタッペンとセルジオ・ペレスという、まだ若いながらもキャリア的には中堅の域に入りつつあるドライバーと、ベテランドライバーのコンビになる。</p>
<p>マックス・フェルスタッペンのチームメイトが、F1 に参戦してまだ 2 年目というアレクサンダー・アルボンから、経験豊富なセルジオ・ペレスになることで、数年前のダニエル・リカルド(現ルノー、来季からマクラーレン)とマックス・フェルスタッペンのようにチームメイト同士で争ったり、メルセデスに挑んだりという場面が来年は多く見られるのかなという期待がある。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">BREAKING: Sergio Perez will partner Max Verstappen at Red Bull in 2021!<a href="https://twitter.com/hashtag/F1?src=hash&ref_src=twsrc%5Etfw">#F1</a> <a href="https://t.co/31xnAstbqn">pic.twitter.com/31xnAstbqn</a></p>— Formula 1 (@F1) <a href="https://twitter.com/F1/status/1339933551802855429?ref_src=twsrc%5Etfw">December 18, 2020</a></blockquote>
<h3>凋落したフェラーリ</h3>
<p><a href="https://www.as-web.jp/f1/564432?all">【津川哲夫の F1 新車初見チェック】中低速での改善が意識されるフェラーリ SF1000。レッドブルの大レーキ角コンセプトを導入か</a>の記事にある通り、2019 年のフェラーリは低ドラッグなマシンにパワフルなパワーユニットという<a href="https://dic.pixiv.net/a/%E7%9B%B4%E7%B7%9A%E7%95%AA%E9%95%B7">直線番長</a>的な特性を示していた。</p>
<p>それはダウンフォース不足に繋がり中低速なコーナーが弱点となっていた。</p>
<p>2020 年はこれを改善すべく、<a href="http://f1sokuho.mopita.com/pc/free/index.php?pass=&page=news/sp/body&no=137860&f=&">『ハイ・レーキ』採用のフェラーリ SF1000、車体&PU に課題あり。大幅改善も必要か/全チーム戦力分析(3</a>に書かれている通り、レーキ角を大きくしてホイールベースを短くした。</p>
<p>マシンの前面を路面に近づけ、マシンの背面は路面から離れた位置に置くことで<a href="https://motorz.jp/race/20920/">グラウンドエフェクト</a>を高め、車体を路面に押し付ける力、ダウンフォースを増すことを意図したものだと思われる。</p>
<p>このレーキ角を大きくしたのは<a href="https://f1-motorsports-gp.com/regulation/f1-airo-rake-floor-df/">2017 年のマシンの写真</a>と<a href="https://www.as-web.jp/f1/564072">2020 年のマシンの写真</a>を比較してみると、2020 年のマシンのほうが前傾になっていることが分かる。</p>
<p>こうして 2019 年のパワーユニットのパワーに合わせて車体側を改良したつもりだったが、車体側の改良は成功とは呼べないものだった。</p>
<p>そしてパワーユニットは去年のパワフルさが鳴りを潜めてしまい、結果として空気抵抗が大きくストレートで遅いマシンとなってしまった。</p>
<p>その結果、1981 年ぶりにコンストラクターズランキングが 5 位未満で終わる年になってしまった。<br>
しかも来年は<a href="https://jp.motorsport.com/f1/news/ferrari-reveals-sf21-name-and-launch-plan-ahead-of-2021-f1-test/4929479/">基本的に 2020 年に使ったマシンを続いて使うことになった</a>ため、このままだと今年同様の苦戦が見込まれる。</p>
<p>ただトークンと言われる仕組みを使うことでマシンの一部に変更を加えることができるので、いかにそれを生かせるかが来年のフェラーリにとっては重要になる。</p>
<h3>復活し始めた古豪、マクラーレン</h3>
<p>マクラーレンは同じようなポイントを獲得したチームと比較して、ドライバー間の差があまり広がっていない。</p>
<p>予選・決勝の勝敗もだいたい同じ、ポイントや予選・決勝の順位もだいたい同じと、かなりバランスが取れた編成になっている。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">END OF SEASON HEAD-TO-HEAD ⚔️<br><br>2020 was a good year on the track for <a href="https://twitter.com/McLarenF1?ref_src=twsrc%5Etfw">@McLarenF1</a> 👏<br><br>And the friendly rivalry between <a href="https://twitter.com/Carlossainz55?ref_src=twsrc%5Etfw">@Carlossainz55</a> and <a href="https://twitter.com/LandoNorris?ref_src=twsrc%5Etfw">@LandoNorris</a> took the team to P3 in the standings 👀<a href="https://twitter.com/hashtag/F1?src=hash&ref_src=twsrc%5Etfw">#F1</a> <a href="https://t.co/ZADpqSDlDr">pic.twitter.com/ZADpqSDlDr</a></p>— Formula 1 (@F1) <a href="https://twitter.com/F1/status/1340691932557824000?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote>
<p>マクラーレンは 2015 ~ 2017 年のホンダとのコラボレーションが失敗し、マシンも結果的にそんな良くなかったが、それを覆い隠すほどにホンダのパワーユニットが悪いという状況になり、チーム内の雰囲気が最悪な感じになっていた。</p>
<p>そこから<a href="https://jp.motorsport.com/f1/news/seidl-led-decision-to-switch-to-mercedes-engines-mclaren/4549852/">アンドレアス・ザイドルという切れ者が代表になった</a>り、<a href="https://ja.wikipedia.org/wiki/%E3%82%B8%E3%82%A7%E3%83%BC%E3%83%A0%E3%82%B9%E3%83%BB%E3%82%AD%E3%83%BC">ジェームス・キー</a>という中団チームで確かな評価を得ていたテクニカルディレクターを獲得した。</p>
<p>その成果が出ていたのが 2019 年からで、今年はさらに良い成果を出せた結果、コンストラクターズランキング 3 位になったと思っている。</p>
<p>来年は久しぶりにマクラーレン・メルセデスというコンビが復活する。<br>
現時点で最強のパワーユニットであるメルセデスのパワーユニットを搭載するので、よっぽどのミスマッチがなければ今年より良い結果になるのではないかと考えている。</p>
<p>なお今年はチーム内の雰囲気も良かったようで、来季はカルロス・サインツがフェラーリへ移籍するが、その移籍先のフェラーリやティフォシ(フェラーリの熱狂的なファン)に対してマクラーレンがカルロス・サインツを頼むというメッセージを Twitter 上で発表している。</p>
<blockquote class="twitter-tweet"><p lang="it" dir="ltr">💬 A message to our friends at <a href="https://twitter.com/ScuderiaFerrari?ref_src=twsrc%5Etfw">@ScuderiaFerrari</a> and to the famous tifosi. <br><br>🇮🇹 𝘜𝘯 𝘮𝘦𝘴𝘴𝘢𝘨𝘨𝘪𝘰 𝘢𝘪 𝘯𝘰𝘴𝘵𝘳𝘪 𝘢𝘮𝘪𝘤𝘪 𝘥𝘪 𝘚𝘤𝘶𝘥𝘦𝘳𝘪𝘢 𝘍𝘦𝘳𝘳𝘢𝘳𝘪 𝘦 𝘢𝘪 𝘴𝘶𝘰𝘪 𝘧𝘢𝘮𝘰𝘴𝘪 𝘵𝘪𝘧𝘰𝘴𝘪.<a href="https://twitter.com/hashtag/AdiosCarlos?src=hash&ref_src=twsrc%5Etfw">#AdiosCarlos</a> 🧡 <a href="https://t.co/B24NYpzOgF">pic.twitter.com/B24NYpzOgF</a></p>— McLaren (@McLarenF1) <a href="https://twitter.com/McLarenF1/status/1339103712523018242?ref_src=twsrc%5Etfw">December 16, 2020</a></blockquote>
<p>ちなみにマクラーレンとフェラーリの間では<a href="https://getnavi.jp/sports/270174/">2007 年にフェラーリのチーフメカニックがマクラーレンのチーフデザイナーに機密情報を渡す事件(通称スパイゲート)</a>があり、そのときを考えると感慨深いものがある。</p>
<h3>スーパーサブとなったニコ・ヒュルケンベルグとジョージ・ラッセル</h3>
<p>今年は 3 人のドライバーが新型コロナウイルスに感染して欠場となった。</p>
<ul>
<li><a href="https://response.jp/article/2020/07/31/337074.html">【F1】コロナ感染による欠場事例が初めて発生…セルジオ・ペレス、8 月 2 日決勝のイギリス GP 出場ならず</a></li>
<li><a href="https://www.dazn.com/ja-JP/news/%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%84/%E3%82%A2%E3%82%A4%E3%83%95%E3%82%A7%E3%83%ABgp%E6%AC%A0%E5%A0%B4%E3%81%AE%E3%82%B9%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB%E6%96%B0%E5%9E%8B%E3%82%B3%E3%83%AD%E3%83%8A%E3%82%A6%E3%82%A4%E3%83%AB%E3%82%B9%E3%81%AB%E6%84%9F%E6%9F%93%E3%81%97%E3%81%A6%E3%81%84%E3%81%9F%E7%8F%BE%E5%9C%A8%E3%81%AF%E9%99%B0%E6%80%A7f1/10ei8asps40ww1sso7pln9ya1a">アイフェル GP 欠場のストロール、新型コロナウイルスに感染していた…現在は陰性</a></li>
<li><a href="https://jp.motorsport.com/f1/news/hamilton-devastated-to-miss-sakhir-gp-after-covid-positive/4919579/">F1 ニュース|ハミルトン、まさかの新型コロナウイルス感染に衝撃「みんなも気をつけて……」</a></li>
</ul>
<p>これにより、昨年限りでシートを失っていたニコ・ヒュルケンベルグがレーシングポイントから参戦し、今年ウイリアムズから参戦していたジョージ・ラッセルがチャンピオンマシンのメルセデスから参戦することになった。</p>
<ul>
<li><a href="https://jp.motorsport.com/f1/news/f1-2020-rd5-70thanniversary-GP-hulkenberg-verstappen-richard/4852825/">F1 70 周年記念 GP |予選 3 位の”代役”ニコ・ヒュルケンベルグを、フェルスタッペン&リカルドが称賛「簡単なことじゃない」</a></li>
<li><a href="https://jp.motorsport.com/f1/news/russell-hopes-to-give-wolff-a-headache-before-2022/4923842/">ジョージ・ラッセル、サクヒールでの活躍がメルセデスにとって”頭痛の種”になることを期待|サクヒール GP</a></li>
</ul>
<p>結果としては 2 人とも表彰台に登ることはなかったものの印象的な活躍を見せた。<br>
ニコ・ヒュルケンベルグはあわやキャリア初表彰台が見え、ジョージ・ラッセルにいたってはピットインでのミスがなければ初ポイント獲得が優勝になるところだった。</p>
<h3>九死に一生を得たロマン・グロージャン</h3>
<p>今年は久しぶりに F1 で大事故があった。近年の F1 は全体的な安全性の向上によって、クラッシュしてもマシンが大炎上することはなかった。</p>
<p>2007 年の時点でさえ、マシン前面がなくなるような大クラッシュをしてもマシンは炎上しなかったし、ドライバーは軽い脳震盪と足の捻挫で済む感じだった。</p>
<p><a id='IEO5sPkcRpdxjnIhipLh5w' class='gie-single' href='http://www.gettyimages.co.jp/detail/74505957' target='_blank' style='color:#a7a7a7;text-decoration:none;font-weight:normal !important;border:none;display:inline-block;'>Embed from Getty Images</a><script>window.gie=window.gie||function(c){(gie.q=gie.q||[]).push(c)};gie(function(){gie.widgets.load({id:'IEO5sPkcRpdxjnIhipLh5w',sig:'-0JvoytSpzuI2z_AofXIRyv54B-efUf0kVEP5iUJ9ow=',w:'594px',h:'396px',items:'74505957',caption: true ,tld:'co.jp',is360: false })});</script><script src='//embed-cdn.gettyimages.com/widgets.js' charset='utf-8' async></script></p>
<p>しかし今年は大事故が起きた。バーレーングランプリでロマン・グロージャンがガードレールにぶつかりマシンが真っ二つになり大炎上した。</p>
<iframe src="https://www.youtube.com/embed/ZQ7_En2xEm4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>ただこれだけの事故でも意識がはっきりとあり、マシンからは脱出できて、肩を借りながらも歩くことができた。</p>
<p>2018 年から F1 にはコックピット周りに<a href="https://formula1-data.com/glossary/car/body/halo">ハロ(ヘイロー)</a>と呼ばれる保護装置が設置されている。<br>
これがロマン・グロージャンを保護した結果、意識を失うことなくマシンから脱出できたと思われる。</p>
<p>また<a href="https://formula1-data.com/article/grosjean-refused-to-be-stretchered-while-battling-intense-pain">死を受け入れた 28 秒間の舞台裏:僕の歩く姿を撮ってくれ…痛みに震えながらも担架を拒否したグロージャン</a>の記事によると、各方面に自分の無事を示すためあえて自分の足で歩いたということで、危機的な状況に陥っても気配りを忘れないのは本当に凄いと思う。</p>
<p>手の火傷により最終 2 戦は欠場したのと、来季の契約は結ばれないことが発表されていたことから、このまま F1 引退の可能性はあるが、シーズン後のテストで<a href="https://formula1-data.com/article/mercedes-open-to-grosjean-test-drive">メルセデス代表のトト・ヴォルフがマシンを用意しても良い</a>という声明を出している。</p>
<p>そのため、もしかしたらもう一度くらいは F1 マシンで走る姿が見られる…かもしれない。</p>
<h2>2021 年シーズン何を楽しみにしているか</h2>
<p>ここまでは様々なことがあった 2020 年の F1 について振り返ってきた。<br>
ここからは来シーズンの F1 で何を楽しみにしているかを書いていく。</p>
<h3>3 年ぶりにフェルナンド・アロンソが帰ってくる</h3>
<p>2018 年の最終戦を持って F1 から離れ、<a href="https://ja.wikipedia.org/wiki/%E4%B8%96%E7%95%8C%E4%B8%89%E5%A4%A7%E3%83%AC%E3%83%BC%E3%82%B9">世界三大レース</a>を制すべくル・マンやインディ 500 に挑んていたフェルナンド・アロンソ。</p>
<p>しかし F1 が恋しくなったのか 3 年ぶりに F1 に戻ってくる。しかも古巣のルノーから参戦というサプライズ。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">It’s official! <a href="https://twitter.com/alo_oficial?ref_src=twsrc%5Etfw">@alo_oficial</a> is back in F1 and will race for <a href="https://twitter.com/RenaultF1Team?ref_src=twsrc%5Etfw">@RenaultF1Team</a> in 2021 <a href="https://twitter.com/hashtag/F1?src=hash&ref_src=twsrc%5Etfw">#F1</a> <a href="https://t.co/O4zB2ckM0j">pic.twitter.com/O4zB2ckM0j</a></p>— Formula 1 (@F1) <a href="https://twitter.com/F1/status/1280819247116058625?ref_src=twsrc%5Etfw">July 8, 2020</a></blockquote>
<p>果たして再びフェルナンド・アロンソとルノーというコンビが成功するのか、それとも期待外れに終わるのか、今から楽しみではある。</p>
<p>ちなみに、最終戦のアブダビグランプリで 2005 年にドライバーズチャンピオンとコンストラクターズチャンピオンを取ったルノー R25 というマシンでデモランをした。</p>
<p>やはり 3 リッター V10 エンジンの音は甲高くてとても良い。個人的には 42 秒付近くらいからが最高。このドップラー効果たまんねえなという気持ちになる。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">What a treat to see this today! 😍<a href="https://twitter.com/alo_oficial?ref_src=twsrc%5Etfw">@alo_oficial</a> and the 2005 championship-winning R25 reunited on track at <a href="https://twitter.com/ymcofficial?ref_src=twsrc%5Etfw">@ymcofficial</a> 🇦🇪<br><br>🎥 <a href="https://twitter.com/RenaultF1Team?ref_src=twsrc%5Etfw">@RenaultF1Team</a> <a href="https://t.co/NQxTkV552K">pic.twitter.com/NQxTkV552K</a></p>— Formula 1 (@F1) <a href="https://twitter.com/F1/status/1337419371216400384?ref_src=twsrc%5Etfw">December 11, 2020</a></blockquote>
<p>車載カメラからの映像もとても良い。甲高い音とマシンの軽快さが楽しめる。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">The perfect onboard doesn't exi... Oh wow. <a href="https://twitter.com/hashtag/RSspirit?src=hash&ref_src=twsrc%5Etfw">#RSspirit</a> <a href="https://twitter.com/hashtag/AbuDhabiGP?src=hash&ref_src=twsrc%5Etfw">#AbuDhabiGP</a> <a href="https://twitter.com/alo_oficial?ref_src=twsrc%5Etfw">@alo_oficial</a> <a href="https://twitter.com/F1?ref_src=twsrc%5Etfw">@f1</a> <a href="https://t.co/i6L2eVA9yg">pic.twitter.com/i6L2eVA9yg</a></p>— Renault F1 Team (@RenaultF1Team) <a href="https://twitter.com/RenaultF1Team/status/1337457366737055746?ref_src=twsrc%5Etfw">December 11, 2020</a></blockquote>
<h3>楽しみな新人たち</h3>
<p>来年は今のところ新しく 3 人のドライバーが F1 に参戦する。そのうち 2 人の楽しみなドライバーを紹介する。</p>
<h4>7 年ぶりに日本人ドライバーが F1 に戻ってくる</h4>
<p>日本人ドライバーは 2014 年まで参戦していた(トヨタ → ザウバー → ケータハムという遍歴の小林可夢偉)。<br>
それ以降は日本人ドライバーがずっといなかったが、来年 2021 年は久しぶりに角田裕毅という日本人ドライバーが参戦する。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">BREAKING: Japan's Yuki Tsunoda joins the grid for 2021!<br><br>The 20-year-old - F2's rookie of the year - will race for <a href="https://twitter.com/AlphaTauriF1?ref_src=twsrc%5Etfw">@AlphaTauriF1</a> <a href="https://twitter.com/hashtag/F1?src=hash&ref_src=twsrc%5Etfw">#F1</a> <a href="https://t.co/Fk3tJx9Wk8">pic.twitter.com/Fk3tJx9Wk8</a></p>— Formula 1 (@F1) <a href="https://twitter.com/F1/status/1339121068364206080?ref_src=twsrc%5Etfw">December 16, 2020</a></blockquote>
<p>この角田裕毅というドライバーは今年 F1 の直下カテゴリーである F2 に参戦し、<a href="https://formula1-data.com/article/f2-round18-race2-2020">ルーキーながらランキング 3 位</a> になった。</p>
<p>F2 は 3 位以上であれば F1 に参戦できるだけのスーパーライセンスポイントを獲得できるため、F2 参戦初年度にしていきなり F1 に昇格できる資格を得たことになる。</p>
<p>そして実際来年はアルファタウリ・ホンダから参戦する。今年の実績からして勝てる可能性が少しでもあるマシンから参戦すること、また本人の実力もありそうということで、今から楽しみである。</p>
<h4>9 年ぶりにシューマッハーが F1 に戻ってくる</h4>
<p>そして来年はミハエル・シューマッハーの息子、ミック・シューマッハーが F1 に参戦する。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">BREAKING: Mick Schumacher to race in F1 in 2021!<br><br>The 21-year-old signs with <a href="https://twitter.com/HaasF1Team?ref_src=twsrc%5Etfw">@HaasF1Team</a> <a href="https://twitter.com/hashtag/F1?src=hash&ref_src=twsrc%5Etfw">#F1</a> <a href="https://twitter.com/hashtag/RoadToF1?src=hash&ref_src=twsrc%5Etfw">#RoadToF1</a> <a href="https://t.co/KfBCB8zK1T">pic.twitter.com/KfBCB8zK1T</a></p>— Formula 1 (@F1) <a href="https://twitter.com/F1/status/1334044805022756864?ref_src=twsrc%5Etfw">December 2, 2020</a></blockquote>
<p>今年の F2 ではチャンピオンを獲得し、文句なしで F1 に参戦できることになった。<br>
チーム自体は今年最遅を競うくらいの競争力だったが、ミック・シューマッハーがどこまで順応できるか見てみたい。</p>
<h2>まとめ</h2>
<p>今年の F1 は新型コロナウイルスの影響もあり、異例づくしのシーズンになったが、その分ドラマがあった。</p>
<p>来年の F1 が果たしてどうなるのか、引き続き見ていきたい。</p>
<h2>おまけ: F1 情報をどうやって得るか</h2>
<p>自分が見ている Web サイトや SNS アカウントは以下の通り。</p>
<h3>公式</h3>
<ul>
<li><a href="https://twitter.com/f1">Formula 1 Twitter</a>
<ul>
<li>ツイートは英語だが、割と読みやすい</li>
</ul>
</li>
<li><a href="https://www.youtube.com/user/Formula1">FORMULA 1 - YouTube</a>
<ul>
<li>レース後はハイライト動画がアップロードされるので、まずはそれを見てみるところから始めるのも良さそう</li>
</ul>
</li>
<li><a href="https://www.formula1.com/en/latest/all.html">Latest F1 News</a>
<ul>
<li>F1 公式のニュース一覧</li>
</ul>
</li>
</ul>
<h3>日本語の情報</h3>
<ul>
<li><a href="https://www.as-web.jp/">autosport web</a></li>
<li><a href="https://jp.motorsport.com/">motorsport.com 日本版|モータースポーツ情報サイト</a></li>
<li><a href="https://formula1-data.com/">F1 ニュース速報/解説【Formula1-Data】</a></li>
<li><a href="https://sports.yahoo.co.jp/f1/">F1 - スポーツナビ</a></li>
<li><a href="https://f1-stinger2.com/f1_news">F1 ニュース | F1/モータースポーツ深堀サイト:山口正己責任編集 F1 STINGER 【スティンガー】 独自の視点で F1 ニュースを発信</a></li>
</ul>
Splathon vol.1 Advent Calendar 2020 の 23 日目の記事となる。
2020-12-25T00:00:00.000Z
2022-11-28T15:40:09.000Z
WH-1000XM4を買うかどうか迷っている人は今すぐ買おう
tag:blog.kubosho.com,2020-12-21:entry://wh-1000xm4-review
<p><a href="https://adventar.org/calendars/4942">今年のベストバイガジェット Advent Calendar 2020</a> の 21 日目の記事となる。<br>
前日は<a href="https://note.com/imcz_izu/n/n1bf2840b5bd7">【今年のベストバイガジェット 2020】3 台目の LG VELVET |くじ| note</a> という記事だった。</p>
<p>今年買ってダントツに良かったのは<a href="https://www.sony.jp/headphone/products/WH-1000XM4/">ソニーの WH-1000XM4</a> というノイズキャンセリング付き無線(Bluetooth)接続ヘッドホンだと思う。<br>
<a href="https://www.sony.jp/headphone/lovemusic/the_first_take/lisa/">LiSA from THE FIRST TAKE × WH-1000XM4</a> で LiSA さんが付けているヘッドホンとなる。</p>
<iframe src="https://www.youtube.com/embed/l0l_Y63dvrk" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<h2>買うきっかけ</h2>
<p>WH-1000X シリーズは初代のときから見た目と機能性が気になっていた。前から欲しいとは思っていたが、4 万円近い値段ということもあり尻込みしていた。</p>
<p>そんなある日<a href="https://av.watch.impress.co.jp/docs/news/1269706.html">ソニー、装着したまま人と話せる NC/BT ヘッドフォン「WH-1000XM4」 - AV Watch</a> の記事を見た。</p>
<p>このとき新型が出る!と運命にも近い気持ちを感じ、WH-1000XM4 を買うための貯金を始め、そしてソニーストアで予約が開始されたときに速攻で注文した。</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">my new gear... <a href="https://t.co/qUI4S7g8cs">pic.twitter.com/qUI4S7g8cs</a></p>— kubosho (@kubosho_) <a href="https://twitter.com/kubosho_/status/1301729761006297088?ref_src=twsrc%5Etfw">September 4, 2020</a></blockquote>
<h2>使った感想</h2>
<p>このヘッドホンに限らない感想としては、Bluetooth 接続のヘッドホンなので、何かしながら何かを聞くといったときはコードが煩わしくなくて良いという感想がある。<br>
WH-1000XM4 に限った感想でいうと、音質・付け心地・遮音性といった 3 つの項目が主だった項目として挙げられる。</p>
<h3>音質</h3>
<p><a href="https://www.audio-technica.co.jp/product/ATH-MSR7">オーディオテクニカの ATH-MSR7</a> を持っているのでこれと比較してみると、低音、特にベースが強めに出ているものの基本的にはバランス良く出ている印象を受ける。<br>
ATH-MSR7 は高音が強めで低音が弱めな感じ。聴き比べると ATH-MSR7 のほうが音がクリアに聴こえる。</p>
<p><a href="https://www.sony.jp/headphone/products/WH-1000XM4/">WH-1000XM4 の商品ページ</a>でも他の項目と比較するとそこまで音質には言及されていない印象。<br>
ただノイズキャンセリングヘッドホンの中では音質は良いと思う。少なくとも 1 万 5000 円~ 2 万円前後のヘッドホンと比較できるくらいの音質にはなっている。</p>
<h3>付け心地</h3>
<p>付け心地は本当に最高。これだけで 1 万円分くらいの価値があると言ってもいい。</p>
<p>長時間付けてても頭頂部や耳が痛くならないし、それでいてヘッドバンキングをしてもヘッドホンが落ちないという絶妙な装着感がある。<br>
イヤーパッドのふわふわ感は他の追従を許さないと思う。</p>
<h3>遮音性</h3>
<iframe src="https://www.youtube.com/embed/DQybvOAC87U" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>上の動画で電車内が騒がしくてもヘッドホンを付ければ音楽しか聞こえなくなるという演出がある。これは割とそうという感じ。<br>
ノイズキャンセリング性能が高いので、音楽を鳴らすと本当に周囲の音が聞こえにくくなる。</p>
<p>一例として、電車に乗ると換気のために電車の窓を開けていることが多い。そのためガタンゴトンという音が普段に比べてよく聞こえる。<br>
この音がヘッドホンを付けて音楽を鳴らすとかなり軽減されて気にならないくらいになる。</p>
<h3>その他</h3>
<p>その他の良い点としては次の通り。</p>
<ul>
<li>ヘッドホンを外すと音楽再生が止まり、付けると音楽再生が開始される</li>
<li>WH-1000XM4 は 2 台の機器と同時接続することができるが、これが昨今のビデオチャットで会議をする環境下では便利</li>
<li>マイクの性能は普通に通話がおこなえる程度に良い</li>
</ul>
<h2>欠点</h2>
<p>唯一の欠点として、ハウジング部分のタッチセンサーの操作で意図しない操作をするときが稀にある。</p>
<figure>
<img src="https://blog-assets.kubosho.com/original_WH-1000XM4_007.jpg"
alt="WH-1000XM4のタッチセンサーコントロールの使い方を説明した画像">
<figcaption>画像は<a href="https://www.sony.jp/headphone/products/WH-1000XM4/feature_4.html">WH-1000XM4 特長 : 多様な使い方と操作方法 | ヘッドホン | ソニー</a>から引用。</figcaption>
</figure>
<p>上の画像を見てもらうと分かるが、ハウジング部分のタッチセンサー部分で指を左右に動かすと曲の頭出しができる。これがたまに音量操作(指を上下に動かす)と誤認される。<br>
指を斜めに動かすと誤認されがちなので、指をちゃんと意図した通りに動かすと良い。</p>
<h2>まとめ</h2>
<p>とにかく付け心地と遮音性は最高なヘッドホンで、これだけでも買ってよかったと思えるヘッドホンだった。<br>
もしこの記事を見て WH-1000XM4 が気になったら、Amazon のリンクを貼っておくので、ぜひ買ってほしい。</p>
<p><a href="https://www.amazon.co.jp/%E3%82%BD%E3%83%8B%E3%83%BC-%E3%83%AF%E3%82%A4%E3%83%A4%E3%83%AC%E3%82%B9%E3%83%8E%E3%82%A4%E3%82%BA%E3%82%AD%E3%83%A3%E3%83%B3%E3%82%BB%E3%83%AA%E3%83%B3%E3%82%B0%E3%83%98%E3%83%83%E3%83%89%E3%83%9B%E3%83%B3-WH-1000XM4-Bluetooth-%E6%9C%80%E5%A4%A730%E6%99%82%E9%96%93%E9%80%A3%E7%B6%9A%E5%86%8D%E7%94%9F/dp/B08F25MLF9/ref=as_li_ss_il?th=1&linkCode=li3&tag=o2p-22&linkId=bccc40f7775ea4353bd09cbb623cf13d&language=ja_JP" target="_blank"><img src="https://ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B08F25MLF9&Format=_SL250_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=o2p-22&language=ja_JP" alt=""><br>WH-1000XM4</a><br>
<img src="https://ir-jp.amazon-adsystem.com/e/ir?t=o2p-22&language=ja_JP&l=li3&o=9&a=B08F25MLF9" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
今年のベストバイガジェット Advent Calendar 2020 の 21 日目の記事となる。
2020-12-21T00:00:00.000Z
2022-11-28T15:33:55.000Z
ロジクールのStreamCamを買った
tag:blog.kubosho.com,2020-12-15:entry://logicool-streamcam
<p><a href="https://www.logicool.co.jp/ja-jp/product/streamcam">ロジクール StreamCam</a>が Amazon のブラックフライデーで安くなっていたので買った。<br>
値段はもろもろ割引が入って 13,320 円だった。ただ <a href="https://amzn.to/3nlacTj">今の Amazon 上の値段</a>がグレーと白ともに 14,800 円で売られていた。<br>
しかもグレーのほうは 5% 割引が効くということで少し複雑な気持ちになった。</p>
<p>箱はこんな感じで、特に言うことはない。</p>
<p><img src="https://blog-assets.kubosho.com/new-web-camera-1.jpg" alt="ロジクールStreamCamが入った箱"></p>
<p>カメラをディスプレイの上に置くとこんな感じ。見た目としては悪くない。<br>
土台部分の縦幅が狭いので、ベゼルが狭いディスプレイでもはみ出さないのは良い。</p>
<p><img src="https://blog-assets.kubosho.com/new-web-camera-2.jpg" alt="ロジクールStreamCamの見た目。カメラ部分は角丸の長方形で真ん中にカメラがあり、周辺をマイクが覆っている"><br>
<img src="https://blog-assets.kubosho.com/new-web-camera-3.jpg" alt="ロジクールStreamCamをディスプレイの上に置いた場合、ベゼルが狭くてもはみ出すことがない"></p>
<p>また JOBY のゴリラポッドにも対応しているのは良い。基本はディスプレイに載せたままなので三脚に載せるのはあまりしてないけど…</p>
<p>難点を上げるとすれば、プラグの形式が Type-C であること。<br>
普段から MacBook Pro と Windows PC を切り替えて使っているので、Web カメラは USB 切替器に繋げておきたい気持ちがある。<br>
ただ<a href="https://hanpenblog.com/6148">仕様違反の USB Type-C 変換アダプターが売られている話</a>という話があり、USB Type-C レセプタクルがある機器は問答無用で仕様違反かつ一歩間違うと危ない代物なので、しかたなく Web カメラは付け替えている。</p>
<p>肝心のカメラ性能は、今まで使っていた<a href="https://www.logicool.co.jp/ja-jp/product/hd-webcam-c270n">ロジクール Webcam C270n</a>と比較すると以下の点が変わった。</p>
<ul>
<li>画質が向上した</li>
<li>画角が広くなった</li>
<li>手を振ってもブレなくなった</li>
</ul>
<p>全体的な感想としてはかなり満足。今年買って良かったものの一つになった。</p>
ロジクール StreamCamが Amazon のブラックフライデーで安くなっていたので買った。
2020-12-15T00:00:00.000Z
2022-11-28T15:34:53.000Z
WindowsでもmacOSのようなキー操作を実現する
tag:blog.kubosho.com,2020-08-30:entry://use-autohotkey-to-macos-like-keymapping
<p>前から macOS のように Windows でも Ctrl キーを使ったカーソル移動をおこないたいと思っていました。<br>
また macOS のショートカットは Command キーを使うことが多いため、Windows でも各種ショートカットに Windows キーを使うようにしたいと思っていました。</p>
<p>今回これらを実現するべく、レジストリエディターと<a href="https://www.autohotkey.com/">AutoHotkey</a>を使って、キーボードショートカットを望む形にしました。</p>
<h2>レジストリエディターを使って、左の Windows キーを F13 キーに変更する</h2>
<p><a href="http://www.grismar.net/ventrilocapsfix/">Push To Talk Fix - Remapping keys to F13</a>内にある「Remap Left Windows Key to F13」を適用します。<br>
次のレジストリ情報を任意の場所に <code>.reg</code> 形式で保存して実行したあと、PC を再起動すれば左の Windows キーが F13 キーに変わります。</p>
<pre><code>Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,64,00,5b,e0,00,00,00,00
</code></pre>
<h2>AutoHotkey を使ってキーボードショートカットを実装する</h2>
<p>キーボードショートカットの設定は次の通りになりました。</p>
<pre class="language-ahk"><code class="language-ahk">#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#UseHook, On
#SingleInstance, force
; F13 & Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
; macOS like keymap
F13 & /::^/
F13 & ,::^,
F13 & 1::^1
F13 & 2::^2
F13 & 3::^3
F13 & 4::^4
F13 & 5::^5
F13 & 6::^6
F13 & 7::^7
F13 & 8::^8
F13 & 9::^9
F13 & 0::^0
F13 & a::^a
F13 & b::^b
F13 & c::^c
F13 & f::^f
F13 & h::^h
F13 & i::^i
F13 & k::^k
F13 & l::^l
F13 & n::^n
F13 & p::^p
F13 & q::!F4
F13 & r::^r
F13 & s::^s
F13 & t::^t
F13 & v::^v
F13 & w::^w
F13 & x::^x
F13 & z::^z
F13 & Enter::^Enter
F13 & Space::#s
; https://superuser.com/questions/1246946/autohotkey-remapping-altshifttab-to-lwinshifttab
F13 & Tab::
AltTabMenu := true
If GetKeyState("Shift","P")
Send {Alt Down}{Shift Down}{Tab}
else
Send {Alt Down}{Tab}
return
#If (AltTabMenu)
~*F13 Up::
Send {Shift Up}{Alt Up}
AltTabMenu := false
return
#If
; Windows keymap
F13 & e::#e
F13 & Up::#Up
F13 & Right::#Right
F13 & Down::#Down
F13 & Left::#Left
#IfWinNotActive, ahk_exe WindowsTerminal.exe
Return
#IfWinNotActive
; Emacs like keymap
#IfWinNotActive, ahk_exe WindowsTerminal.exe
^p::Send, {Up}
^f::Send, {Right}
^n::Send, {Down}
^b::Send, {Left}
^+p::Send, {Shift}+{Up}
^+f::Send, {Shift}+{Right}
^+n::Send, {Shift}+{Down}
^+b::Send, {Shift}+{Left}
^a::Send, {Home}
^e::Send, {End}
^d::Send, {Delete}
^h::Send, {BackSpace}
^m::Send, {Enter}
^k::Send, {Shift}+{End}{BackSpace}
Return
#IfWinNotActive
</code></pre>
<p>先ほど左の Windows キーをリマップして作り出した F13 キーをふんだんに使って、Windows の Control キーを使ったキーボードショートカットを F13 キーを使うように変更しています。<br>
Control キーについては Emacs っぽくカーソル移動のショートカットに割り当てています。<br>
Windows Terminal を使っているときはショートカットを無効化したかったため、<a href="https://pouhon.net/ahk-win-active/2812/">[AutoHotKey]#IfWinActive で対象ウインドウを指定する | Output 0.1</a>を参考にしてショートカットを無効化しています。</p>
<h2>まとめ</h2>
<p>Windows をメインで使い始めてだいぶ経ちますが、ようやく思い通りの操作ができるようになって嬉しいです。</p>
前から macOS のように Windows でも Ctrl キーを使ったカーソル移動をおこないたいと思っていました。
2020-08-30T00:00:00.000Z
2022-11-28T14:56:53.000Z
自作 PC を組んで運用し始めてもうすぐ1年が経とうとしている
tag:blog.kubosho.com,2020-06-09:entry://first-time-home-built-computer
<p>2019 年の 9 月頃に自作 PC を組んで運用をおこなっているが、自作 PC について Twitter でしか書いてなかったため、ブログにも書いて自作 PC はいいぞというのを伝えていきたい。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">現在のPCの状況 <a href="https://t.co/pHfMaHdMjI">pic.twitter.com/pHfMaHdMjI</a></p>— kubosho (@kubosho_) <a href="https://twitter.com/kubosho_/status/1273271843864973312?ref_src=twsrc%5Etfw">June 17, 2020</a></blockquote>
<h2>なぜ自作 PC を組もうと思ったか</h2>
<p>2019 年で 30 歳を迎えるにあたって、せっかくだし前から興味はあったけど難しそう・お金がかかりそうという点で手を出せていなかった自作 PC に手を出そうと思ったから。</p>
<h2>自作 PC のスペック</h2>
<p>スペックは次の通り。合計すると 227,983 円だった。<br>
なるべく数年は使えるものを買おうと思って、買っていたらこうなった。<br>
ただ改めて見てみると、自分でもなんでこんなにお金がかかっているんだという気持ちになった。</p>
<table>
<thead>
<tr>
<th>パーツ</th>
<th>名前</th>
<th>購入時の値段</th>
</tr>
</thead>
<tbody>
<tr>
<td>CPU</td>
<td>AMD Ryzen 7 3700X</td>
<td>¥42,984</td>
</tr>
<tr>
<td>メモリ</td>
<td>CORSAIR CMW32GX4M2C3200C16</td>
<td>¥21,796</td>
</tr>
<tr>
<td>マザーボード</td>
<td>ASRock X570 Taichi</td>
<td>¥35,653</td>
</tr>
<tr>
<td>SSD-1</td>
<td>WesternDigital WDS500G1B0C-EC</td>
<td>¥7,980</td>
</tr>
<tr>
<td>SSD-2</td>
<td>CFD CSSD-M2B1TPG3VNF</td>
<td>¥0 <a href="#footnote-1">※1</a></td>
</tr>
<tr>
<td>グラボ</td>
<td>MSI GeForce RTX 2060 AERO ITX 6G</td>
<td>¥41,432</td>
</tr>
<tr>
<td>ケース</td>
<td>CORSAIR CC-9011133-WW</td>
<td>¥11,860</td>
</tr>
<tr>
<td>電源</td>
<td>玄人志向 KRPW-GK550W/90+</td>
<td>¥6,600</td>
</tr>
<tr>
<td>OS</td>
<td>Microsoft Windows 10 Pro 日本語版</td>
<td>¥27,860</td>
</tr>
<tr>
<td>キャプチャーボード</td>
<td>elgato 4K60 Pro MK.2</td>
<td>¥31,818</td>
</tr>
</tbody>
</table>
<h2>自作 PC を組んだ感想</h2>
<p>正直 PC を組むのはもうちょっと難しいと思っていたが、マザーボードに付属していた説明書を見ながらやったら割と簡単に組めた。<br>
ミニ四駆を作ったことがある人であれば、多分自作 PC を組めると思う。</p>
<p>難しかったのは組む以前のパーツ選定のほうが難しかった。性能と値段のバランスがいい感じになるパーツを相性を気にしつつかなり探し回っていた…</p>
<p>あと自作 PC には<a href="https://en.wikipedia.org/wiki/IKEA_effect">IKEA 効果</a>があるなと感じる。自分が組み立てた PC は最高である。</p>
<h2>実際に運用した感想</h2>
<p>とにかく快適そのもの。CPU・GPU を使った処理が重いと感じることもなく、また記憶装置へのアクセスも遅いと感じたことがない。<br>
これだけでも自作 PC を組んで良かったと思っている。</p>
<p>メモリは 32GB 積んでいるけど、これだけ積むとメモリを食う Google Chrome や<a href="https://github.com/microsoft/WSL/issues/4166">WSL 2 を使っていると Vmmem がメモリを食いまくるバグ</a>が気にならなくなる。</p>
<p>また CPU クーラー・メモリ・マザーボードが光るものとなっているが、正直光るのが楽しい。</p>
<h2>これから</h2>
<p>個人的にはもうちょっと光らせてもいいかなと思い、<a href="https://apac.coolermaster.com/jp/cooling/case-fan/masterfan-mf120-halo/">Cooler Master: MasterFan MF120 Halo</a>というケースに取り付けるファンを買った。<br>
電源も Seasonic 製の物に替えてみたいなとは思うが優先度は低い。</p>
<p>またスペックを余らせてしまっているので、VR の開発や高スペックを求められる PC ゲームに手を出したいとは思っている。</p>
<h2>おまけ: 自作 PC を組んでいる様子</h2>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">自作PCを組もうと思ったらCPUを買い忘れていた</p>— kubosho (@kubosho_) <a href="https://twitter.com/kubosho_/status/1175211827195568128?ref_src=twsrc%5Etfw">September 21, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Ryzen 7 3700Xを買ってある程度組んだ。この後電源の配線という面倒な作業がある… <a href="https://t.co/rBQxorZpKo">pic.twitter.com/rBQxorZpKo</a></p>— kubosho (@kubosho_) <a href="https://twitter.com/kubosho_/status/1175457876011147264?ref_src=twsrc%5Etfw">September 21, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ようやく組み終わった。いい感じに動いているっぽい <a href="https://t.co/oTWX5cu51F">pic.twitter.com/oTWX5cu51F</a></p>— kubosho (@kubosho_) <a href="https://twitter.com/kubosho_/status/1175815348047642624?ref_src=twsrc%5Etfw">September 22, 2019</a></blockquote>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">自作PCの配線がどんどんきれいになっていく <a href="https://t.co/uhZs1BO00h">pic.twitter.com/uhZs1BO00h</a></p>— kubosho (@kubosho_) <a href="https://twitter.com/kubosho_/status/1185967932917997569?ref_src=twsrc%5Etfw">October 20, 2019</a></blockquote>
<p>コードはケースの裏側で配線したほうが、空気の流れが改善されてより各パーツを冷やしやすくなる…はず。</p>
<ul>
<li id="footnote-1">※1 2019年の誕生日のときにAmazonギフト券を大量にもらい、そのギフト券で買ったため実質無料で手に入れたと言える</li>
</ul>
2019 年の 9 月頃に自作 PC を組んで運用をおこなっているが、自作 PC について Twitter でしか書いてなかったため、ブログにも書いて自作 PC はいいぞというのを伝えていきたい。
2020-06-09T00:00:00.000Z
2022-11-28T14:52:15.000Z
記事の内容が思いつかない症候群
tag:blog.kubosho.com,2020-05-25:entry://content-of-article-can-not-think-of-anything-syndrome
<p>2019 年は丸 1 年ブログの記事を書かず、2018 年も長い記事を書いていなかった。<br>
そのせいか書きたい題材はあるものの、記事の内容が思いつかない、もしくは書こうとしても面倒くさくなるということになっている。</p>
<p>とはいえ自分の Twitter のタイムラインを見ていると、さまざまな人がブログ・ポッドキャスト・YouTube などといったさまざまな手段で発信している。</p>
<p>中にはサービスを作って公開している人もいる。</p>
<p>そういうのを見ると、自分の中に羨ましい・楽しそうという気持ちが芽生えて、ああこの流れに自分も乗っていきたいという気持ちが高まる。<br>
そうしてまずはブログの記事から書こうと思うものの、内容が思いつかない、または書こうとしても面倒くさくなるということが起きる。</p>
<p>まあこういうのもさらけ出して、自分の中の発信のハードルを下げていって量を出せるようにしていけば、いつか質も伴った発信ができるようになるのかなと思う。<br>
ブログだけでなくせっかく機材が揃っているのでポッドキャストや YouTube などを使った発信というのもしていきたいな。</p>
2019 年は丸 1 年ブログの記事を書かず、2018 年も長い記事を書いていなかった。
2020-05-25T00:00:00.000Z
2022-07-31T05:33:26.000Z
ブログの記事管理をContentfulからGitリポジトリに変更した
tag:blog.kubosho.com,2020-05-18:entry://migrating-from-contentful-to-markdown-file
<p>このブログは最初はてなブログで書いていて、1 年前にこっそり Next.js + Contentful という仕組みに変えて運用していた。<br>
今回仕組みをふたたび変えて、Markdown ファイルを Git リポジトリにコミットしていく形式にした。</p>
<p>コミットした Markdown ファイルは GitHub 上へ push すると Vercel の GitHub integration によって Vercel 上にデプロイされる仕組みとなっている。<br>
その辺の仕組みについてコードを読みたい人は <a href="https://github.com/kubosho/kubosho.com/blob/master/src/entry/entryConverter.ts">entryConverter.ts</a> と <a href="https://github.com/kubosho/kubosho.com/blob/master/tools/entriesJsonBuilder.ts">entriesJsonBuilder.ts</a> を読むと良い。</p>
<h2>なぜ Contentful から Markdown ファイルを編集する形式に変えたのか</h2>
<p>理由は 3 つある。</p>
<h3>1. Contentful の Markdown エディタの挙動が信用できなくなった</h3>
<p><a href="https://blog.kubosho.com/entry/working-style-after-covid-19">リモートワーク体制になって変わったこと・変わらなかったこと</a>の記事を書いていたときに、次のツイートに示す事象に遭遇した。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Contentfulのエディタで記事を書いていたら自動保存のタイミングでIMEが確定されていたようで、文章がめちゃくちゃになっていた。そしてその状態がエディタに表示されてなかったので、何も対策できなかった…<a href="https://t.co/IDBnTnzZf6">https://t.co/IDBnTnzZf6</a></p>— kubosho (@kubosho_) <a href="https://twitter.com/kubosho_/status/1253014495930118146?ref_src=twsrc%5Etfw">April 22, 2020</a></blockquote>
<p><a href="https://www.contentfulcommunity.com/t/can-i-disable-auto-save-in-the-content-posting-editor/2626">Contentful Community</a> にも同様の問題が報告されていた。<br>
Markdown エディタを使ってフルスクリーン状態で記事を書いていたらこの問題が発生した。後日問題が再現するか試したが、再現しなかったので複合的な要因でバグるのかもしれない。</p>
<p>とはいえ、記事を書くときに「記事ちゃんとした形で保存されているのかな…」といった余計な思考が混ざることが記事を書くことを億劫にさせるし、安定した環境で書きたくなった。</p>
<h3>2. Contentful の 編集画面が気に食わない</h3>
<p>ブログ記事を書くときに自分は本文部分とプレビュー部分をそれぞれ横並びに表示したい。<br>
どういうことかは次に示すはてなブログの編集画面の画像を見てもらうと分かると思う。</p>
<p><img src="https://blog-assets.kubosho.com/hatena-blog-editor.png" alt="はてなブログの編集画面は本文とプレビューで2カラムになっている"></p>
<p>だが Contentful の編集画面は 1 カラムになっている。<br>
次に示す Contentful の編集画面の画像を見てもらうと分かるように自分の理想とするレイアウトになっていない。</p>
<p><img src="https://blog-assets.kubosho.com/contentful-editor.png" alt="Contentfulの編集画面は1カラムになっていて余計な空白が空いているため使いづらい"></p>
<p>一応 Contentful 上の Content model から本文のエディタを Markdown エディタにしたうえでフルスクリーンモードにすると、編集画面とプレビュー画面が横並びに表示されるようにはなる。<br>
ただこの表示にすると、先ほど書いたように本文がとんでもないことになることがあるので詰んでしまう。</p>
<p>また Markdown エディタにした場合、エディタ部分の font-family に <code>font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace!important;</code> が指定されているため、特に Windows 環境だと次に示すように文章を書く気になれない見た目になる。</p>
<p><img src="https://blog-assets.kubosho.com/contentful-markdown-editor.png" alt="ContentfulのMarkdownエディタの画面"></p>
<h3>3. 思ったよりいろんな環境でブログの記事を書かない</h3>
<p>いつでもどこでもブログの記事を書けるようにしたいが WordPress は導入が面倒だなと思って、裏側を Headless CMS ひいては Contentful にしてみたものの、スマホやタブレットでブログの記事を書くことはなかった…</p>
<p>実際に運用してみたらほぼパソコンからしか記事を書いていなかったので、だったら使い慣れたテキストエディタ上で記事を書けたほうが筆が進むのではと思い、移行に至った。</p>
<p>実際この記事も使い慣れた Visual Studio Code 上で書いているが、使い慣れているだけあって頭のリソースを 100%文章に向けられている。これで良かった。</p>
<h2>まとめ</h2>
<p>ちゃんとユースケースを考えよう。</p>
このブログは最初はてなブログで書いていて、1 年前にこっそり Next.js + Contentful という仕組みに変えて運用していた。
2020-05-18T00:00:00.000Z
2022-11-28T15:38:42.000Z
リモートワーク体制になって変わったこと・変わらなかったこと
tag:blog.kubosho.com,2020-04-24:entry://working-style-after-covid-19
<p>Twitter を見ていたら「フルリモート体制になった人に聞いてみたいことを考えてみた」というツイートが流れてきた。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">フルリモート体制になった人に聞いてみたいことを考えてみた。<br><br>- 身だしなみの変化量<br>- 気分転換の仕方<br>- 身体のメンテナンス方法<br>- 雑談の効果や必要性、実施方法<br>- 新しく始めたこと<br>- 事前にやって良かったこと<br>- 消費の変化<br>- 自宅やオフィスに対する価値観に変化があったか</p>— naomix (@naomix) <a href="https://twitter.com/naomix/status/1252976696568864769?ref_src=twsrc%5Etfw">April 22, 2020</a></blockquote>
<p>ということで、このツイートに便乗してブログの記事を書いてみる。</p>
<p>昨今の状況に漏れず、自分も 2 月末くらいからリモートワークをしている。<br>
合わせてこれは当たり前かもしれないが、外出も散歩と買い物以外は控えている。</p>
<p>そんな状況のもとで、日々どんな感じで過ごしているかを書いていく。</p>
<h2>身だしなみの変化量</h2>
<p>前よりは髭を剃る頻度は減った。あまり外に出ないのと、髭脱毛をしていて前よりは生える速度が遅くなったという 2 つが重なったことが要因。</p>
<p>朝に身だしなみを整えたり服を着替えたりといったことは変わらずやっている。これがないと気分が切り替わらない。</p>
<h2>気分転換の仕方</h2>
<p>1 人でカラオケへ行くことやラブライブ!関連や内田彩さんのライブへ行くことが封じられてしまって厳しさがある。</p>
<p>カラオケについては<a href="https://item.rakuten.co.jp/jttonline/017284/">ミュートマイク</a>を買って、DAM の PC 版も契約した。声がこもるし完全な代替とは言わないものの、それなりにカラオケを楽しめる環境はできて良い。</p>
<p>またどうしようもなく疲れたときは、ひたすら YouTube を垂れ流している。最近は Splatoon かあつまれ どうぶつの森(以下あつ森)関連の動画ばかり見ている。</p>
<p>あと長風呂することも好きなので長風呂をしている。もちろん水分補給は忘れないようにしている。</p>
<h2>身体のメンテナンス方法</h2>
<p>平日の 15 時にラジオ体操第一をやっている。</p>
<iframe src="https://www.youtube-nocookie.com/embed/feSVtC1BSeQ" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>それ以外はやれていない。自粛云々関係なく 3 年前と比較して平均で 4kg は太っているのでちょっとヤバいなという気持ちはある。<br>
リングフィットアドベンチャーを持っているので再開しようという気持ちはある。</p>
<h2>雑談の効果や必要性、実施方法</h2>
<p>毎朝、朝会と称して日々についてフリーテーマで一言言い合う場がチーム内で設けられている。<br>
これのおかげでふんわり皆の様子が分かったり喋ったりができているので、良い仕組みだと思っている。</p>
<p>あと、リモートワークを始めた当初は以下のようなことを言っていた。</p>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">リモートワークをしていても、オフィスに出社したときのように、雑談したくなるタイミングがあるので、その辺解決できると良いのだけれど</p>— kubosho (@kubosho_) <a href="https://twitter.com/kubosho_/status/1233345213063581697?ref_src=twsrc%5Etfw">February 28, 2020</a></blockquote>
<p>しかし、リモートワークを重ねるうちにだんだんこういった気持ちが薄れていった。<br>
同居している婚約者がいるので、タイミングを計って話しかけることもあるのが良いのかもしれない。</p>
<p>あと夜にボイチャをしながらゲームをすることが割とあるので、1 日のうち複数人としゃべらない日が連続することは少ない。</p>
<h2>新しく始めたこと</h2>
<p>あつ森を買って遊んでいる。</p>
<p>現実世界でどうしても普段より精神的に落ち込みがちだけど、新型コロナウイルスの蔓延やそれに伴う社会の変化とは無縁の世界を見ていると少しほっとする。<br>
また島を整えたりカブ価を見るために、朝すぐに布団から出て Switch を立ち上げる習慣ができてきた。</p>
<p>仕事面では、作業環境に二酸化炭素濃度測定計を買ってモニタリングするようにした。<br>
1000ppm を超えたら換気するようにしている。</p>
<h2>事前にやって良かったこと</h2>
<p>作業環境の整備はやっておいて良かった。</p>
<p>元々家の中に執務スペースがあったので、そこで作業しやすくなるよういろいろ買っていた。<br>
おかげで急にリモートワーク前提になっても作業環境という点では困らなかった。</p>
<p>インターネット回線周りも光回線を引いていて、下り平均 120Mbps くらい、調子がいいと 200 ~ 300Mbps 出るときもあるので必要十分だと思う。</p>
<h2>消費の変化</h2>
<p>Uber Eats を前より頼むようになったので、エンゲル係数は前より上がっている…</p>
<p>あとボイスチャットを良いものにしたり YouTube Live などで配信できるようにしたりするために、ミキサーなどを買った。</p>
<h2>自宅やオフィスに対する価値観に変化があったか</h2>
<p>都内のオフィスに通勤することって、場所や気持ちを切り替える上で割と重要だったんだなという思いは持った。</p>
<p>それに気づいたあとは近所を 20 分ほど歩くようにしたけど、それなりに気分転換できる。</p>
Twitter を見ていたら「フルリモート体制になった人に聞いてみたいことを考えてみた」というツイートが流れてきた。
2020-04-24T00:00:00.000Z
2022-11-28T16:03:19.000Z
WSL上のChromiumでPDF出力をする
tag:blog.kubosho.com,2018-08-05:entry://output-pdf-in-wsl-chromium
<p>Windows Subsystem for Linux(WSL)上で Headless Chrome を使って、PDF 出力をしてみました。<br>
やり方としては次に示すコマンドを実行すれば、C ドライブ上の Temp フォルダの中に Google をスクリーンショットした <code>output.pdf</code> が出力されます。</p>
<pre class="language-shell"><code class="language-shell"><span class="token function">sudo</span> <span class="token function">apt</span> <span class="token function">install</span> chromium-browser
chromium-browser --headless --disable-gpu --print-to-pdf<span class="token operator">=</span>/mnt/c/Temp/output.pdf https://www.google.com
</code></pre>
Windows Subsystem for Linux(WSL)上で Headless Chrome を使って、PDF 出力をしてみました。
2018-08-05T00:00:00.000Z
2022-11-28T14:50:45.000Z
TypeScriptでsetInterval()の型が合わない理由と解決方法
tag:blog.kubosho.com,2018-07-18:entry://setinterval-trap-on-typescript
<p><code>@types/node</code> に依存した状態で以下のようなコードを書いたときに <code>Type 'Timer' is not assignable to type 'number'.</code> というエラーメッセージが出ます。</p>
<pre class="language-typescript"><code class="language-typescript"><span class="token keyword module">export</span> <span class="token keyword">class</span> <span class="token class-name"><span class="token maybe-class-name">ExampleClass</span></span> <span class="token punctuation">{</span>
intervalId<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span>
<span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span> <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">// do something</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">clearInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<h2>原因</h2>
<p><code>@types/node</code> に依存している場合 <code>setInterval()</code> の返り値が <code>NodeJS.Timer</code> となるためです。<code>@types/node</code> に依存していなければ <code>setInterval()</code> の返り値は <code>number</code> になります。</p>
<ul>
<li><code>@types/node</code> の型定義: <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/010a8de/types/node/timers.d.ts#L73-L76">https://github.com/DefinitelyTyped/DefinitelyTyped/blob/010a8de/types/node/timers.d.ts#L73-L76</a></li>
<li>TypeScriptの <code>lib.dom.d.ts</code> の型定義: <a href="https://github.com/microsoft/TypeScript/blob/3431912/lib/lib.dom.d.ts#L16739">https://github.com/microsoft/TypeScript/blob/3431912/lib/lib.dom.d.ts#L16739</a></li>
</ul>
<h2>解決方法</h2>
<h3>1. <code>setInterval()</code> を使う箇所で <code>window.setInterval()</code> とする</h3>
<p><code>window</code> オブジェクトにある <code>setInterval()</code> の返り値の型は <code>number</code> となっています。なので <code>window.setInterval()</code> が使える環境であれば <code>window.setInterval()</code> と書き換えると解決できます。</p>
<p>参考: <a href="https://github.com/TypeStrong/atom-typescript/issues/1053#issuecomment-321126192">setInterval - Type 'Timer' is not assignable to type 'number' · Issue #1053 · TypeStrong/atom-typescript</a></p>
<h3>2. <code>setInterval()</code> の返り値を入れるプロパティの型を変更する</h3>
<p><code>window.setInterval()</code> と書き換える方法は、SSRをしているときには使えません。たとえばNext.jsを使っている場合にはエラーが出ると思われます。</p>
<p>この場合は以下のように <code>intervalId</code> の初期値に <code>null</code> を入れておいて、<code>clearInterval()</code> を実行するところで <code>setInterval()</code> の返り値が <code>this.intervalId</code> に入っているか確かめる方法があります。</p>
<pre class="language-typescript"><code class="language-typescript"><span class="token keyword module">export</span> <span class="token keyword">class</span> <span class="token class-name"><span class="token maybe-class-name">ExampleClass</span></span> <span class="token punctuation">{</span>
intervalId<span class="token operator">:</span> <span class="token maybe-class-name">NodeJS</span><span class="token punctuation">.</span><span class="token property-access"><span class="token maybe-class-name">Timer</span></span> <span class="token operator">|</span> <span class="token keyword null nil">null</span><span class="token punctuation">;</span>
<span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span> <span class="token operator">=</span> <span class="token keyword null nil">null</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span> <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">// do something</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">clearInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span> <span class="token operator">=</span> <span class="token keyword null nil">null</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<h3>3. <code>setInterval()</code> 全体を <code>Number()</code> で囲む</h3>
<p><a href="https://blog.csdn.net/ollin2012/article/details/88963553">关于typescript的定时器setInterval()坑_ollin2012的博客-CSDN博客_ts 定时器类型</a>で紹介されている手法を多少改変して、<code>setInterval()</code> 全体を <code>Number()</code> で囲んで <code>number</code> 型にtype assertionする手法もあります。</p>
<pre class="language-typescript"><code class="language-typescript"><span class="token keyword module">export</span> <span class="token keyword">class</span> <span class="token class-name"><span class="token maybe-class-name">ExampleClass</span></span> <span class="token punctuation">{</span>
intervalId<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span>
<span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span> <span class="token operator">=</span> <span class="token known-class-name class-name">Number</span><span class="token punctuation">(</span><span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">// do something</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">clearInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token property-access">intervalId</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<h2>まとめ</h2>
<p>手癖のように <code>intervalID</code> が入るところで初期値として <code>0</code> を代入していましたが、TypeScriptではハマる可能性が高いので気をつけましょう。</p>
@types/node に依存した状態で以下のようなコードを書いたときに Type 'Timer' is not assignable to type 'number'. というエラーメッセージが出ます。
2018-07-18T00:00:00.000Z
2022-11-28T08:18:51.000Z
Atomic Designを実案件に導入して運用してみた結果はどうなのか
tag:blog.kubosho.com,2017-12-18:entry://atomic-desigin-on-abematv
<p>かつて<a href="http://blog.kubosho.com/entry/using-atomic-design">Atomic Design の考え方と利点・欠点</a>という記事を書きました。<br>
この記事内で日本では<a href="https://abema.tv/">AbemaTV</a>で使われていると書きました。そして今でも AbemaTV では Atomic Design の考えに基づいてコンポーネントが作られています。</p>
<p>AbemaTV での経験を通じて、Web アプリケーションのクライアントサイドの開発者という立場から Atomic Design はどうなのかについて書いていきます。</p>
<p>なお AbemaTV ではビューライブラリとして React を使っているので、React 前提の話になります。</p>
<h2>Atomic Design に基づくのは実際どうなのか</h2>
<p>基本的には良いです。良い点について書いていたら<a href="https://ygoto3.com/posts/atomic-design-on-actual-project/">Atomic Design を実案件に導入 - UI コンポーネントの粒度を明確化した結果と副産物 | ygoto3.com</a>や<a href="https://www.slideshare.net/ygoto3q/atomic-desigin-powered-by-react-abematv/31">Atomic Design powered by React @ AbemaTV</a>に書いてある内容と似てきたので、良い点についてはこれらの資料を見てください。</p>
<p>ただし問題点もあります。いま思いつく限りでは大きく 2 つ問題があると考えています。</p>
<h3>人によってコンポーネントの粒度が違う</h3>
<p>Atomic Design において <code>atoms</code> はそれ単体で使うことはなく <code>molecules</code> や <code>organisms</code> 内に取り込まれた状態で使われます。</p>
<p>また <code>molecules</code> にあたるコンポーネントは単一責任の原則に基づくのが良いとされています。</p>
<p>しかしコンポーネントによっては <code>props</code> が多すぎるものもあります。特に <code>molecules</code> の一部コンポーネントは <code>props</code> が 22 個あります。<br>
実際に該当のコンポーネントは挙動を変更する理由がいくつかある状態です。</p>
<p>この場合は責務ごとにコンポーネントを分割すればよかったのかもしれません。<br>
もしくは<a href="https://reactjs.org/docs/higher-order-components.html">Higher-Order Components - React</a>を取り入れても良いかもしれません。</p>
<h4>デザイナーとデベロッパーのコンポーネントの粒度も違う</h4>
<p>今だとデザイナーが Sketch の Symbol 上に構築したコンポーネントの粒度とデベロッパーが実装したコンポーネントの粒度が違うものもあります。</p>
<p>デザイナーとデベロッパーのどちらかの考えに粒度を合わせるのが良いでしょう。<br>
この場合、基本的にはデザイナーの考えに合わせたほうが良いと思います。<br>
<a href="http://morishitter.hatenablog.com/entry/2016/07/29/204642">morishitter の CSS の書き方(2016 年夏) - morishitter blog</a>にもある「デザインの意図を正確に理解した上で書かれた CSS は破綻しない」です。</p>
<p>とはいえ、自分もあまり余裕がなかったため「なぜこのデザインなのか」をあまり聞けていません(Slack 上でどのデザインにするかやりとりしているときに「これが良いですねー」とか反応するくらい)。</p>
<p><a href="http://demo.patternlab.io/">Pattern Lab のデモ</a>に作りたいコンポーネントのカテゴリーがあったらお互いそれに沿うようにするのもいいでしょう。<br>
たとえば <code>blocks</code> だったら <code>molecules</code> で <code>sections</code> だったら <code>organisms</code> という感じです。</p>
<h3>コンポーネントのテストが面倒</h3>
<p>コンポーネントのテストを書く場合は <code>enzyme</code> を使って <code>find()</code> などを用いて要素があるかを探し、表示されている文字が期待のものと合致しているかなどをテストすると思います。</p>
<p>この場合テストとは直接的に関係ないコードがテストコード内に存在することになります。<br>
テストを書くときに Virtual DOM 内をいちいち探索しないといけなくなるため、そこまでテストコードが書かれていないコンポーネントが増えることにもなります。<br>
また各コンポーネントがどのような <code>props</code> を持っているか調べないといけないため特に <code>organisms</code> にあたるコンポーネントのテストは面倒になるでしょう。</p>
<p>そのため Jest の<a href="https://facebook.github.io/jest/docs/en/snapshot-testing.html">Snapshot Testing</a>のように、スナップショットとなるコードを書いてテストコード側でそれと合致するか確かめるようにする流れができつつあります。</p>
<hr>
<p>この記事は<a href="https://adventar.org/calendars/2216">AbemaTV Advent Calendar 2017</a>の 17 日目の記事でした。<br>
AbemaTV では<a href="https://recruit.abematv.co.jp/jobs/engineer/">Atomic Design のよりよい運用を考えたいデベロッパーを募集中</a>です。</p>
かつてAtomic Design の考え方と利点・欠点という記事を書きました。
2017-12-18T00:00:00.000Z
2022-11-28T15:23:41.000Z
CSSを破綻させない
tag:blog.kubosho.com,2016-12-14:entry://not-break-css
<p>12/3(土)に<a href="https://builderscon.io/builderscon/tokyo/2016/session/720e29c6-9b11-46f3-adf4-f6f52e4fcbb9">CSS を破綻させない</a>という内容を<a href="https://builderscon.io/builderscon/tokyo/2016">builderscon tokyo 2016</a>で話しました。</p>
<p>そこで使った発表資料の内容を編集した上で、<a href="http://qiita.com/advent-calendar/2016/css">CSS Advent Calendar 2016</a> 14 日目の記事として公開します。</p>
<h2>CSS は破綻しやすい</h2>
<p>OOCSS の提唱者 Nicole Sulliban 氏も<a href="http://www.andoh.org/2009/11/web-directions-east-2009-nicole.html">"CSS is too fragile"</a>と 2008 年のイベントで言いました。<br>
なぜ破綻しやすいのか。それは CSS の特性が絡んでいます。</p>
<h2>CSS の特性</h2>
<p>CSS の特性としておもに 3 つあります。</p>
<p>はじめに、記述を間違えてもエラーにならないことです。ブラウザで表示確認をおこなって初めて見た目がおかしいことに気づきます。</p>
<p>次に、スタイルが適用される条件としてルールセットを書く順序は関係ありますが、常に関係があるわけではない点です。</p>
<p>ちなみにルールセットは CSS のセレクタ・プロパティ・値の定義をまとめたものです。<br>
分かりやすい図として<a href="http://terkel.jp/archives/2011/09/css-rule-structure/">CSS ルールセット構造図 · terkel.jp</a>内の画像があるので引用します。</p>
<p><img src="//blog-assets.kubosho.com/css-rule-set.png" alt="CSSのルールセットの図"></p>
<p>最後に、ルールセット間で同じプロパティが定義されている場合、順序・詳細度・重要度にもとづいて適用されるスタイルが決定されます。CSS をややこしくしているのはここですが、意識して書かないと容易に破綻します。</p>
<p>ここからは実際に CSS が破綻した例を見ていきます。</p>
<h2>CSS の破綻</h2>
<p>CSS の破綻はいくつか種類があります。これらの要素のうち 2 つ以上が複合して起きていると手がつけられない CSS になります。</p>
<h3>スタイルの上書きが複数ある</h3>
<p>スタイルの上書きは Bootstrap など CSS フレームワークを使うときに独自の見た目を実現しようとすると起こりがちな問題です。<br>
スタイルの上書きが多くなるとどんな見た目になるのか予測できなくなり破綻します。</p>
<pre class="language-css"><code class="language-css"><span class="token selector"><span class="token class">.button</span></span> <span class="token punctuation">{</span>
<span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token unit">px</span> solid <span class="token hexcode color">#ccc</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">/* ...長いコードの後や別ファイルなど... */</span>
<span class="token selector"><span class="token class">.button</span></span> <span class="token punctuation">{</span>
<span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token unit">px</span> solid <span class="token hexcode color">#666</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">/* ...長いコードの後や別ファイルなど... */</span>
<span class="token selector"><span class="token class">.article</span> <span class="token class">.button</span></span> <span class="token punctuation">{</span>
<span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token unit">px</span> solid <span class="token hexcode color">#00c</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<h3>前に書いたセレクタの詳細度が高い</h3>
<p>前に書いたセレクタの詳細度が高くてスタイルが上書きできないことも破綻の一因になります。<br>
先ほどのスタイルの上書きを多くしていると起こりがちな問題です。<br>
これがもたらす結果としては <code>!important</code> の濫用です。</p>
<pre class="language-css"><code class="language-css"><span class="token comment">/* 詳細度はa=0, b=4, c=0なので0.4.0となる */</span>
<span class="token selector"><span class="token class">.container</span> <span class="token class">.form</span> <span class="token class">.form-group</span> <span class="token class">.form-submit-button</span></span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
<span class="token comment">/*
詳細度はa=0, b=1, c=0なので0.1.0となる
上書きできない。つらい
*/</span>
<span class="token selector"><span class="token class">.form__submit-button</span></span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
</code></pre>
<h3>命名規則がバラバラ</h3>
<p>よくあることとして単語の区切りがケバブケース・キャメルケース・スネークケースのようにバラけていると、どの規則に合わせればいいのか分からずいつまでも命名規則が統一されません。</p>
<pre class="language-css"><code class="language-css"><span class="token selector"><span class="token class">.account-login-button</span></span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
<span class="token selector"><span class="token class">.commentSubmitButton</span></span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
<span class="token selector"><span class="token class">.form_submit_button</span></span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
</code></pre>
<h2>CSS の破綻 まとめ</h2>
<p>ここまで CSS が破綻する理由について書きました。まとめると次のとおりです。</p>
<ul>
<li>詳細度が管理されていない</li>
<li>ルールセットの分割粒度が明確ではない</li>
<li>命名規則が決まっていない</li>
</ul>
<h2>CSS を破綻させない</h2>
<p>ここからは CSS を破綻させないためにはどうすればいいのかを書いていきます。</p>
<h3>詳細度を管理する</h3>
<p>CSS などのファイルを分割するときはファイル内で下へ行くにつれて詳細度が高くなるようにします。またセレクタ定義や ID セレクタを書きすぎないようにするのも重要です。</p>
<p>例を挙げるとフォーム共通のスタイルを適用するときにセレクタを定義しすぎないことです。<br>
これにより少ないセレクタ定義で適用したスタイルを上書きできて秩序が保つことができます。</p>
<pre class="language-css"><code class="language-css"><span class="token comment">/* 詳細度はa=0, b=2, c=0なので0.2.0となる */</span>
<span class="token selector"><span class="token class">.form</span> <span class="token class">.form-button</span></span> <span class="token punctuation">{</span>
<span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">/* ... */</span>
<span class="token comment">/*
詳細度はa=0, b=2, c=0なので0.2.0となる
記述の順序が後なので値が上書きされる
*/</span>
<span class="token selector"><span class="token class">.comment-form</span> <span class="token class">.form-button</span></span> <span class="token punctuation">{</span>
<span class="token comment">/* 上書きできる */</span>
<span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">10</span><span class="token unit">px</span> auto<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<h3>ルールセットの分割粒度を明確にする</h3>
<p>スタイルの上書きを減らすためにルールセットの分割粒度を明確にすることも重要です。<br>
これはさまざまな方法が提案されていて、たとえば<a href="https://github.com/hiloki/flocss">FLOCSS</a>や<a href="https://smacss.com/">SMACSS</a>、<a href="http://ecss.io/">ECSS</a>などがあります。</p>
<p>これは作るものによって適しているものが違うため一概にどれがいいか言えません。<br>
スタイルを適用したいときにルールセットをどこに置けばいいのかチーム内で迷わないようにするのが重要です。</p>
<h3>命名規則を決める</h3>
<p>命名規則も<a href="http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/">MindBEMding</a>や<a href="http://ecss.io/chapter5.html#h-H2_1">ECSS</a>、<a href="https://smacss.com/book/categorizing">SMACSS</a>などさまざまなものがあります。これもチーム内で使う命名規則を一致させることが重要です。</p>
<h2>CSS を破綻させない まとめ</h2>
<p>ここまで CSS の破綻を起こさないためにどうしたらいいか書きました。まとめると次のとおりです。</p>
<ul>
<li>詳細度を管理する</li>
<li>チーム内でルールセットの分割粒度を明確にする</li>
<li>チーム内で命名規則を決める</li>
</ul>
<p>しかしこれらを実践する前により大事なことが 1 つあります。<br>
それは<strong>デザイナーとの認識合わせ</strong>です。</p>
<p>これは<a href="http://morishitter.hatenablog.com/entry/2016/07/29/204642">デザインの意図を正確に理解した上で書かれた CSS は破綻しない</a>という言葉があります。</p>
<p>デザイナーが作った Sketch や Photoshop のファイルを見て質問や提案をおこない、デザイナーと UI を実装する人で意図の認識を合わせることが重要です。<br>
もっと言うなら Sketch や Photoshop などで作る以前のプロトタイピングの段階から関わるとお互い意図の認識がしやすくなると思います。<br>
プロトタイピングツールは<a href="https://www.invisionapp.com/">InVision</a>が代表的です。</p>
<p>これを踏まえてまとめると、<strong>チームで議論して良い CSS 設計を考えよう</strong>になります。</p>
<h2>CSS がすでに破綻している場合は?</h2>
<p>builderscon の Q&A で「途中から入ったプロジェクトの CSS が破綻していた場合どう改善したらいいのか?」というのがあったのですが、今のところチームで話し合って設計指針を決めて 1 から書き直すしかないと考えています。</p>
<h2>参考資料</h2>
<ul>
<li><a href="http://dskd.jp/archives/54.html">僕は CSS を見殺しにした - dskd</a></li>
<li><a href="https://app.codegrid.net/entry/2016-ecss-1">Enduring CSS の設計思想 - ECSS が目指す設計 | CodeGrid</a></li>
<li><a href="https://app.codegrid.net/entry/smacss-1">SMACSS による CSS の設計 - ベースとレイアウト | CodeGrid</a></li>
<li><a href="http://qiita.com/BYODKM/items/b8f545453f656270212a">破綻しにくい CSS 設計の法則 15 - Qiita</a></li>
<li><a href="http://qiita.com/BYODKM/items/8c777db2d89f4e830c93">CSS が破綻する 4 つの理由 - Qiita</a></li>
</ul>
12/3(土)にCSS を破綻させないという内容をbuilderscon tokyo 2016で話しました。
2016-12-14T00:00:00.000Z
2022-11-28T15:18:37.000Z
人生に悩んでいる20代後半〜30代前半は夏アニメのReLIFEを見たほうがいい
tag:blog.kubosho.com,2016-10-10:entry://relife
<p>録りためていた夏アニメの<a href="http://relife-anime.com/">ReLIFE</a>をこの休日を使って一気見したのですが、ストーリーが自分にぶっ刺さり、また自分の人生を見つめ直し、これから後悔しない人生にするためにはどうしたら良いのか考えるきっかけになったので、ReLIFEは何がいいのかを一応ネタバレをさけつつ書いていきます。</p>
<h2>あらすじ</h2>
<p><a href="http://relife-anime.com/story/introduction.html">公式サイト</a>内のイントロダクションから引用するとこんな感じです。</p>
<blockquote>
<p>海崎新太(27歳)は、新卒として入社した会社を3ヶ月で退職。その後の就活もうまく行かず、親からの仕送りも打ち切られ田舎に戻ることを迫られる。悩みを打ち明けられる友達も彼女もいない……途方に暮れる海崎の前に謎の人物・夜明了が現れる。</p>
</blockquote>
<blockquote>
<p>夜明は海崎にニートを対象にした社会復帰プログラム「リライフ」への参加をもちかける。その内容は、謎の秘薬で見た目だけ若返り、1年間高校生として高校に通うことだった――。</p>
</blockquote>
<p>と、設定自体は現実にはあり得ないですが、主人公の海崎が周りの高校生と交流して影響を与えつつ、自身も忘れていたものを取り戻すという青春アニメです。</p>
<p>「ある程度社会人経験を積んだ人が、自分と照らし合わせたりしてもどかしさを覚えつつニヤニヤして見る」感じです。</p>
<h2>なぜ良いと思ったのか</h2>
<p>まずストーリーで引き込まれ、その次にED曲でさらに引き込まれました。<br>
また登場人物やセリフ(主にヒロインの日代のセリフ)も刺さりました。</p>
<h3>ストーリー</h3>
<p>1・2話で続きが気になるような伏線を入れてきて、この伏線がどうなるか見続けたくなり、またその後もきっちりと続きが気になるところで終わらせていて、構成が上手いと感じました。</p>
<p>主人公の海崎はあらすじにもあるように新卒で入った会社をとある事情で3ヶ月で退職し、その後コンビニのバイトで食いつなぐも仕送りを打ち切られ、路頭に迷いそうになります。まずこの設定が現在の自分と合わさって少し感情移入し見ようという気になりました。</p>
<p>また、1話のタバコが見つかり先生に反省文の提出を求められる場面で、過去に海崎の身に何かあった描写や、2話で小野屋が海崎と一緒に大神をからかうのですが、海崎と同じくリライフしてきたのでは?と思わせる描写があり、この伏線はどうなるのかが気になりました(結局違う方向でしたが)。<br>
同じく2話では、一見とっつきづらそうな日代が実は友達がほしいという思いを発露したのも意外な展開でした。</p>
<p>ただ3話ではその友達が欲しいというのが、バレー部の狩生にとって誤解される結果になり確執につながってしまいます(そののち解消しますが)。</p>
<p>また、両思いなのになかなか成就しない恋を見ては「早くお前らくっついて末永く爆発してほしい」ともどかしさを覚えたりしました。これは自分が学生時代に同じ経験をした結果、告白ができなかったということが関係しているかもしれません。</p>
<h3>ED曲に使われる曲が20代後半〜30代前半にものすごく刺さる</h3>
<p><a href="https://ja.wikipedia.org/wiki/ReLIFE#.E4.B8.BB.E9.A1.8C.E6.AD.8C">ReLIFE - Wikipedia</a>の主題歌を見ると分かりますが、「イージュー★ライダー」「HOT LIMIT」「タイミング」など、1990年代後半〜2000年代前半の間に小学〜中学生だった人にとってはものすごく刺さる選曲となっています。</p>
<p>特に第3話の「タイミング」はその後の展開を考えるとまさにタイミングが良かったり、第12話の「夏祭り - Whiteberry」はED曲が流れ始めたときの状況も合わさって「選曲した人は神か!」となりました。</p>
<h3>登場人物</h3>
<p>海崎は、その生い立ちから今の自分と重なるところがあり、感情移入して見てました。そして海崎の行動を見て、今までの自分が後悔した点を振り返り、そして今後後悔しないで生きるにはどうしたらいいのか考えるきっかけになりました。<br>
また全体を通して、受け身の態勢ではなく積極的に自分の周辺を変えていこうという姿勢は見習おうと思いました。<br>
ただ最終回でヘタレ感が半端なかったのが残念ですが…</p>
<p>日代も、一見愛想がなく無口ですが、2話でネコのスタンプに似ていると言われたときに「にゃあ」と返したり、3話で海崎から借りた1,000円札をターバンを巻いた形に折って返したりと、どこか変わっている部分もあり憎めない性格になっています。むしろかわいい。あと、後述するセリフがグサグサと自分の心に刺さりました。</p>
<p>狩生は、真っ直ぐで頑張りすぎるところがあるがそこがいいのと、最終回で急激にその魅力が増したように思えます。ツンデレ乙といった感じでしょうか。</p>
<h3>セリフ</h3>
<p>5話では、海崎が狩生に対して「人を貶そうとする行為は結局自分を貶す。今まで積み重ねてきた努力や信頼を自分で踏みにじるな」というのが、改めてそういうことをやらないようにしようと思いました。<br>
5話はそれ以外にも名ゼリフがあってとてもよいです。</p>
<p>9話では、日代が海崎に対して「いつまでも失敗を引きずっている自分を倒したいんです。失敗は忘れてはいけないと思います。でも、悪い思い出のまま引きずっていて逃げ続けていたら、いつまでも変われないと思うんです。失敗があったからこそできるようになることもあると思うんです」というのが、自分の最近の振る舞いを考えてここから何を変えたらいいのか、どのような行動指針で動けばいいのか考えさせられました。</p>
<p>また、10話ではとある理由で試合に来なかった狩生に対して日代が説得するのですが、経験則から説得して「本当にこれでいいんですか?本当はどうしたいんですか?」というのが、自分の過去を振り返ってこれでよかったのかと考えさせられました。</p>
<h2>見た結果</h2>
<p>全体をとおして青春を感じたり海崎の積極性を見て、もどかしさや焦り、また自分の学生時代を思いだして、海崎のように積極性があったらとあのときはこうできたと思いました。<br>
そして直近で自分があまり上手くいってなかったということもあり、はたしてこのままで良いのだろうかと思考を重ねていたところでこのアニメを見た結果、改めて自分の行動指針はなんだったっけと振り返るきっかけになりました。</p>
<p>ここまで書いて、なんだか自己啓発本やセミナーを受けた後の感想みたいと思いましたが、それは自分がこのアニメがきっかけで自分の人生を振り返って後悔した点と、これから後悔しないためにどう行動すればいいのか考えたのが関係しているかもしれません。</p>
<p>また、今までは自分が若いと思っていた節もあったのですが、もうおっさんになってしまったと自覚しました。</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">ReLIFEがぶっ刺さったのはおっさんになってしまったからか…</p>— kubosho_ (@kubosho_) <a href="https://twitter.com/kubosho_/status/785107773713358848">October 9, 2016</a></blockquote>
<h2>見てみる</h2>
<p><a href="https://www.amazon.co.jp/dp/B01HDFJNHU">Amazonプライムビデオ</a>で全話配信されているのと、<a href="http://www.comico.jp/special/index.nhn">comico内の「ReLIFEチャンネル」</a>でも1話無料、その後はcomico内のポイントを消費で見られるようです。</p>
<p>あともちろんcomicoでも連載しているのと、紙やKindle版もあります。<br>
今回のアニメは夏休み中までを描いていましたが、comico上だと2学期の文化祭のストーリーもあります。ここでも日代さんがかわいい。<br>
また漫画版だと、アニメと展開が違ったり端折られている部分が描かれていたりしているため、アニメを見た状態でも1話から見たほうがいいです。</p>
<p><a href="http://www.comico.jp/articleList.nhn?titleNo=2">ReLIFE | 夜宵草 - 話題沸騰中のアニメ「ReLIFE」の原作をタダ読み!!</a></p>
録りためていた夏アニメのReLIFEをこの休日を使って一気見したのですが、ストーリーが自分にぶっ刺さり、また自分の人生を見つめ直し、これから後悔しない人生にするためにはどうしたら良いのか考えるきっかけになったので、ReLIFEは何がいいのかを一応ネタバレをさけつつ書いていきます。
2016-10-10T00:00:00.000Z
2022-06-21T06:15:57.000Z
Atomic Designの考え方と利点・欠点
tag:blog.kubosho.com,2016-07-19:entry://using-atomic-design
<p>Atomic Design はデザインシステムを作る方法論となります。<br>
デザインシステムというのはスタイルガイドやブランドのガイドラインなどを指すようです。</p>
<p>日本だと<a href="https://abema.tv/">AbemaTV(アベマ TV)</a>で使われています。<br>
(<a href="http://ygoto3.com/posts/atomic-design-on-actual-project/">Atomic Design を実案件に導入 - UI コンポーネントの粒度を明確化した結果と副産物 | ygoto3.com</a>より)</p>
<p>Atomic Design は今までのページ単位と違いコンポーネント単位でデザインカンプを作る考え方です。<br>
作ったコンポーネント同士の組み合わせでページを作ります。</p>
<p>Atomic Design はコンポーネントの単位を 5 つに分けています。<br>
その 5 つの単位は Atoms(原子)・Molecules(分子)・Organisms(有機体)・Templates(テンプレート)・Pages(ページ)です。<br>
各コンポーネントの詳細は次のとおりです。</p>
<h2>Atoms(原子)</h2>
<p>Atoms(原子)は、UI を構成する基礎的な要素が該当します。</p>
<p>フォームでいうと、画像で示すようにラベル・入力部分・ボタンの各要素が Atoms となります。<br>
他の要素では、カラーパレットやフォント、アニメーションが Atoms に入ります。</p>
<p><img src="//blog-assets.kubosho.com/atoms.png" alt="Atomsを指した図。フォームのラベル・入力フォーム・ボタンがAtomsとなる"></p>
<p>Atoms に振り分ける基準としては、<strong>対象の要素が機能的にそれ以上分割できない</strong> 場合、Atoms へ振り分けます。<br>
フォームで例えると、ラベルはそれ以上機能的に分割できません。<br>
また入力フォームやボタンもそれ以上機能的に分割できません。</p>
<p>Atoms 単体だと抽象的でどういう意味を持つかは分からないです。<br>
入力フォームだけ見ても、それがアカウント登録フォームもしくはコメント入力フォームという情報は読み取れません。</p>
<p>Atoms はコンポーネントの基礎部分になります。<br>
それは、Atoms を組み合わせてより大きなコンポーネントを構成するという点から言えることです。</p>
<p>また Atoms を俯瞰できるページを用意しておくことで、そのページがどのようにデザインされたかという雰囲気を感じ取ることができます。<br>
それによりページデザインに一貫性を持たせることができます。</p>
<h2>Molecules(分子)</h2>
<p>Molecules(分子)は、Atoms を組み合わせて作る要素です。<br>
この Atoms を組み合わせて Molecules を作るというのは「単一責任の原則」や UNIX 哲学の「1 つのプログラムは 1 つのことをうまくやる」に基づいているようです。</p>
<p>Molecules になることで意味を持つ要素となります。<br>
たとえば、Atoms であるラベル・入力フォーム・登録ボタンという 3 つのコンポーネントがあってもそれら単体は意味をなしません。<br>
しかし、これらの要素を組み合わせることにより「ラベルで示したことに応じて、入力フォームに何かを書いて、登録ボタンを押す」という意味が示せるようになります。</p>
<p><img src="//blog-assets.kubosho.com/molecules.png" alt="Moleculesを指した図。フォームのラベル・入力フォーム・ボタンをまとめたものがMoleculesとなる"></p>
<p>Molecules はできるだけ単純にして、再利用性や UI の一貫性を高めます。</p>
<h2>Organisms(有機体)</h2>
<p>Organisms(有機体)は、Atoms や Molecules、また他の Organisms を組み合わせて作る要素です。今までの Atoms や Molecules とは違い複雑な要素になります。<br>
ヘッダーやフッターと呼ばれる要素はこの Organisms になります。</p>
<p>たとえば画像で示すようなヘッダーは「タイトル」という Atoms と、「ナビゲーション」「SNS のボタン群」という Molecules が組み合わさって、ヘッダーという Organisms になっています。</p>
<p><img src="//blog-assets.kubosho.com/organisms.png" alt="Organismsを指した図。WebページのヘッダーやフッターなどがOrganismsとなる"></p>
<p>Organisms からそのページの特色が出やすくなります。</p>
<h2>Templates(テンプレート)</h2>
<p>ここから Atoms(原子)・Molecules(分子)・Organisms(有機体)といった化学的なものに例えることをしなくなります。<br>
これは仕事の依頼元や上司・同僚に見せるものということを明確にするため、より一般的な言葉を使います。</p>
<p>Templates(テンプレート)の説明に移ると、Templates はページ構造を説明するものです。<br>
Templates は Molecules や Organisms を組み合わせて作ります。</p>
<p>Templates の段階ではページ内容がまだ仮となります。Templates を言い換えるなら「<a href="https://www.google.co.jp/search?q=%E3%83%AF%E3%82%A4%E3%83%A4%E3%83%BC%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0&tbm=isch">ワイヤーフレーム</a>」になります。</p>
<h2>Pages(ページ)</h2>
<p>Pages(ページ)は、Template 内へ実際の文章や画像などが入ったものとなります。</p>
<p>ここまで 5 つの要素について概要を書きました。<br>
要素の振り分けかたについて、どのように考えたらいいかは<a href="http://atomicdesign.bradfrost.com/chapter-2/#atomic-design-is-for-user-interfaces">Atomic design is for user interfaces</a>内の Instagram で例えたものが分かりやすいと思います。</p>
<h2>Atomic Design の利点</h2>
<p>さて、Atomic Design を実際に適用した結果、次に挙げる 3 つの利点があると感じました。</p>
<h3>名前がついている</h3>
<p>Atomic Design はコンポーネントの大きさによって、それぞれ Atoms・Molecules・Organisms・Templates・Pages という名前がついています。<br>
この名前がついていることで、Atoms は「それ以上分割できないコンポーネント」ということや、Molecules の「Atoms を組み合わせた意味があるコンポーネント」という特徴が共有されやすくなると思います。</p>
<h3>デザインの変更に対応しやすくなる</h3>
<p>Atomic Design の考え方でコンポーネントを作ると、デザイン変更に対応しやすくなり再利用性も高くなります。<br>
特に Atoms や Molecules へ振り分けられるような細かいコンポーネントはデザイン変更にも強いです。</p>
<p>今回適用したページはそこまでデザイン変更が起こりませんでした。<br>
それでもデザイン変更があったときはいつもと比べて他コンポーネントへの影響を考えずに対応できました。</p>
<h3>セレクタの詳細度が平坦に近づく</h3>
<p>Atomic Design を適用するとセレクタの詳細度が平坦になるようです。</p>
<p>次の画像は今回 Atomic Design の考え方を使って作った CSS の詳細度を示したグラフですが、割と平坦なグラフになっています。</p>
<p><img src="//blog-assets.kubosho.com/css-valhalla.png" alt="神獄のヴァルハラゲートのイベントページのCSSの詳細度を指した図。飛び出すところがあまりない平坦なグラフとなっている"></p>
<p>また Atomic Design を採用している AbemaTV の CSS も突然詳細度が上がることなく平坦なグラフです。<br>
ただこれは中の人になって分かったことですが、CSS Modules の仕組み(css-loader)を取り入れているため CSS は各コンポーネントごとにスコープが閉じた状態で書くことができます。<br>
そのためセレクタの詳細度をあまり上げなくてもスタイル宣言をできるため、詳細度が抑えられています。</p>
<p><img src="//blog-assets.kubosho.com/css-abematv.png" alt="AbemaTVのCSSの詳細度を指した図。急に飛び出していない平坦なグラフとなっている"></p>
<h2>Atomic Design の欠点</h2>
<p>利点ばかりではなく、Atomic Design の欠点も見えました。</p>
<h3>デザイナーがどのようにデザインしていけばいいか分からない</h3>
<p>Atomic Design は「小さい単位でコンポーネントを作り大きいコンポーネントにしていく」というデザイン手法です。そのため、フロントエンド実装では利点があります。</p>
<p>しかしデザイナーからすると、Atomic Design の考え方でデザインすることは難しいかもしれません。<br>
実際、今回デザイナーへ Atomic Design について説明しました。<br>
ただ、デザインしてもらうときはコンポーネント単位ではなくページ単位でデザインしてもらう従来の方法をとりました。</p>
<p>デザイナーによるページデザインの段階で Atomic Design を取り入れることに関しては、どうしたらいいのかまだ分かりません。</p>
<h3>欠点に対しての対応</h3>
<p>今回はコンポーネントリストを作りました。以下の jsfiddle ではかなり簡略化したリストですが、以下のように Atoms・Molecules・Organisms とコンポーネントを分けて見せるようにしました。</p>
<iframe width="100%" height="300" src="//jsfiddle.net/bed3aj1k/2/embedded/result,css/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<p>デザイナーには通常通りページ単位でデザインカンプを作ってもらいました。<br>
そして、自分のほうでそのデザインカンプを見つつ、Atomic Design の各単位に要素を切り出し、コンポーネントを作りました。</p>
<p>作ったコンポーネントリストをプランナーやデザイナーに共有しておくことで、実機でどのように表示されるか分かりやすくなることと、開発者にも共有しておくことでコンポーネントを使うことを促し、結果としてコード量や実装の工数を減らすことを目論みました。<br>
また、コンポーネントリストは作っておくと、どのようにコンポーネントを分割するか意識することができます。</p>
<h2>まとめ</h2>
<p>今回初めて Atomic Design の考え方でページを作ってみました。<br>
結果としては、思ったより良い感じにハマった感があります。<br>
今後も Atomic Design の考え方に照らし合わせてコンポーネントを作り、良い感じに変更に強く分割されたコンポーネントを作っていきたいと思います。</p>
<h2>出典</h2>
<ul>
<li><a href="http://bradfrost.com/blog/post/atomic-web-design/">Atomic Design | Brad Frost</a></li>
<li><a href="http://atomicdesign.bradfrost.com/">Atomic Design by Brad Frost</a></li>
<li><a href="http://ygoto3.com/posts/smashing-conference-whistler-and-atomic-design/">最近よくクリエイターが移住するカナダで Atomic Design を学ぶ | ygoto3.com</a></li>
<li><a href="http://ygoto3.com/posts/atomic-design-on-actual-project/">Atomic Design を実案件に導入 - UI コンポーネントの粒度を明確化した結果と副産物 | ygoto3.com</a></li>
<li><a href="http://postd.cc/the-unicorn-workflow-design-to-code-with-atomic-design-principles-and-sketch/">珍しいワークフロー:Atomic Design の原則と Sketch でデザインからプログラミングまで | デザイン | POSTD</a></li>
<li><a href="http://design.dmm.com/entry/2016/02/05/153408">Atomic Design は Web 開発を救うのか - DMM.com ラボ デザイナーズブログ</a></li>
</ul>
Atomic Design はデザインシステムを作る方法論となります。
2016-07-19T00:00:00.000Z
2022-11-28T15:18:44.000Z
ErgoDox EZを2週間使ってみた感想
tag:blog.kubosho.com,2016-07-04:entry://ergodoxez-review
<p>最近夏コミに向けての執筆や Twitter クライアント作成に忙しいですが、それらを支える物として最近 ErgoDox EZ が加わりました。</p>
<p>ErgoDox EZ が欲しすぎて買おうかどうかを<a href="//eventdots.jp/report/20160610_588645">ErgoDox users meet up</a>に行ってから決めようとしていたところを、行く前に購入してしまったくらい ErgoDox EZ が気になっていたのですが、そんなに気になっていた ErgoDox EZ が届くまでと実際に使ってみた感想を書いていきます。</p>
<h2>届くまで</h2>
<p>自分は<a href="//www.indiegogo.com/projects/ergodox-ez-an-incredible-mechanical-keyboard#/">Indiegogo</a>経由で買い 2 週間ほどで届きましたが、どうやら<a href="https://ergodox-ez.com/">公式ページ</a>経由で買ったほうが早く届くようです(Twitter を見ていたら 5 日くらいで届いたという人がいた)。<br>
Indiegogo 経由と公式ページ経由を比較すると、Indiegogo を挟む分 Indiegogo 経由のほうが遅くなるのでしょうか?</p>
<p>また宅配業者は UPS でしたが、平日しか宅配してくれないのと、再配達が自動的に翌営業日に決められてしまうので、サポートへメールをしてヤマト運輸へ振り替えてもらいました。</p>
<p>なお、注文した後の流れは<a href="//qiita.com/moutend/items/dd3ac2b8cffd69809928">はじめての ErgoDox EZ 購入ガイド - Qiita</a>という記事が分かりやすく説明されています。</p>
<h2>使ってみて</h2>
<p>実際に使ってみて良い・悪い点両方見えてきたので、以下に記します。</p>
<h3>良い点</h3>
<p>はじめに、セパレート式かつ高さも自由に変えられるので、タイピング時に肩がリラックスした姿勢でタイピングできるようになったことです。<br>
このリラックス状態を知ってしまったら ErgoDox EZ から離れられそうにないです。<br>
また逆チルト状態にすると自分の手に合って良い感じです。</p>
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">ErgoDox EZを逆チルトしてみた図 <a href="https://t.co/JyJbnZI7Lx">pic.twitter.com/JyJbnZI7Lx</a></p>— くぼしょー㌠◎日曜西f47b (@kubosho_) <a href="https://twitter.com/kubosho_/status/749892423539576832">2016年7月4日</a></blockquote>
<p>次に、いろいろとカスタマイズができる点です。<br>
キー配列に関しては、既定のキー配列は癖が結構ありますが、気に入らなければ自分の好きなキー配列にできる点が自由な感じでいいです。<br>
ちなみに現状のキー配列は<a href="//github.com/kubosho/qmk_firmware/blob/master/keyboard/ergodox_ez/keymaps/kubosho/keymap.c">GitHub に上げています</a>。</p>
<p>カスタマイズ性というところでは、Cherry MX キースイッチと互換性があるキーキャップに変えられる点も iPhone ケース並の個性主張ができるという点でいいです。<br>
カスタマイズ情報については<a href="//okapies.hateblo.jp/entry/2016/05/15/164009">ErgoDox EZ カスタマイズ情報のまとめ - Okapies' Archive</a>にまとまっています。</p>
<p>あとは、タイプ時の音がここちよいです。Happy Hacking Keyboard と同じ押下圧(45g)の赤軸を選びましたが、その選択は間違っていなかったと思ってます。<br>
タイプ時の音については HHKB と比べると高い音です。</p>
<p>また、ErgoDox EZ は関係ないかもしれませんが、ErgoDox EZ を使い始めてからタイピング時の運指を意識するようになりました。<br>
今まで自分は左・右小指で押すべきキーを薬指で押していた癖があった(そして気づいてなかった)ために、使い始めて最初の日はタイプミスが多発しました。<br>
今でも「z」や「0」が若干苦手ですが、使い始めた当初に比べればだいぶマシになりました。<br>
タイピング時に運指を意識するようになった結果がどうなったかという参考に、現状の e-typings のスコアを貼っておきます。<br>
一番左は使い始めて 3 日目くらいの記録で、今は全国平均より上回っています。</p>
<p><img src="//blog-assets.kubosho.com/e-typing.png" alt="e-typingの成績。ErgoDox EZに慣れた結果、全国平均よりも上回ったスコアとなっている"></p>
<p>最後に、ErgoDox EZ はセパレート式という特徴があるので、空いた真ん中のスペースに何かおけるのは良いです。<br>
自分はカーソルを絶対座標で指定できる点がいいと思って<a href="//amzn.to/29eZdtJ">Intuos Art</a>を使っていますが、ペンタブは今までキーボードの右端に置くしかありませんでした。しかし ErgoDox EZ がセパレート式なおかげで写真のように真ん中に置けるようになり、より自然な形でペンタブが使えるようになりました。</p>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">こんな感じかな <a href="https://t.co/uLUmghjI6n">pic.twitter.com/uLUmghjI6n</a></p>— くぼしょー㌠◎日曜西f47b (@kubosho_) <a href="https://twitter.com/kubosho_/status/743969878382510080">2016年6月18日</a></blockquote>
<h3>悪い点</h3>
<p>リストレストが臭いと他の ErgoDox EZ のレビュー記事にも書いてあったりしますが、本当に臭いです。<br>
1 週間くらいは臭いが消えなかったので、その間は他のリストレストを使うのがいいと思います。</p>
<p>また、タイピングする際に正しい運指をしていないとタイピング速度がガタ落ちします。<br>
自分は使い始めて最初の日、通常の 20%くらいしか速度がでませんでした。<br>
とはいえ、これは自分の問題なので人によっては問題ないと思います。</p>
<h2>まとめ</h2>
<p>今もこの記事を ErgoDox EZ で書いています。ここまで記事を書いた感想としては、ErgoDox EZ は高い買い物ですが、それに見合うだけの価値はあるということです。</p>
最近夏コミに向けての執筆や Twitter クライアント作成に忙しいですが、それらを支える物として最近 ErgoDox EZ が加わりました。
2016-07-04T00:00:00.000Z
2022-11-28T15:35:41.000Z
Chromium のチャンネル間で変更された点を確認する方法
tag:blog.kubosho.com,2016-05-13:entry://chromium-version-diff
<p>とある事情により、Chromium の stable と beta チャンネル間で変更された点から、バグが直されたコミットがどれなのか確認する必要に迫られました。<br>
その時どのようにして目的のコミットにたどり着いたのか書いていきます。</p>
<h2>Chromium の各チャンネルのバージョンを確認する</h2>
<p><a href="https://omahaproxy.appspot.com/">OmahaProxy - Google Chrome</a>というページで確認します。<br>
これは各 OS の Chrome のチャンネルごとに現在のバージョンを表示しているページです。</p>
<h2>Chromium のチャンネル間で変更された点を見る</h2>
<p>実際に先ほどのページから stable と beta チャンネル間で変更された点を見てみます。それには画像内でも矢印で指していますが、任意のチャンネルの changelog 部分にある「cr」というリンクをクリックします。</p>
<p><img src="https://blog-assets.kubosho.com/chrome_version.png" alt="Chromiumの各チャンネルの情報を表示している画面"></p>
<p>すると、選択したチャンネル(以下の画像では dev チャンネル)の前と現在のバージョンで変更された点が見られます。</p>
<p><img src="https://blog-assets.kubosho.com/chrome_stable_dev.png" alt="Chromiumのstableチャンネルとdevチャンネルの差分を表示している画面"></p>
<p>ここから stable と dev チャンネル間で変更された点を見るにはアドレスバー上で以下のように URL を書き換えます。</p>
<p><code>https://chromium.googlesource.com/chromium/src/+log/:start..:end?pretty=fuller</code></p>
<p>たとえば 2021/3/6 現在の stable と dev チャンネル間で変更された点を見たい場合は <code>:start</code> に stable チャンネルのバージョンを <code>:end</code> に dev チャンネルのバージョンを入れます。</p>
<p><code>https://chromium.googlesource.com/chromium/src/+log/50.0.2661.102..51.0.2704.47?pretty=fuller</code></p>
<p>すると、以下のような感じで stable と beta チャンネル間で変更された点を見ることができます。</p>
<p><img src="https://blog-assets.kubosho.com/chrome_diff.png" alt="Chromiumのチャンネル間の更新差分を表示している画面"></p>
<p>あとはブラウザのページ内検索機能を使い、適当な語句で検索して目的のコミットを見つけるだけです。</p>
とある事情により、Chromium の stable と beta チャンネル間で変更された点から、バグが直されたコミットがどれなのか確認する必要に迫られました。
2016-05-13T00:00:00.000Z
2022-11-28T15:34:06.000Z
Nicoのこれまでとこれから
tag:blog.kubosho.com,2015-12-08:entry://nico
<p><a href="http://qiita.com/advent-calendar/2015/bootstrap">Bootstrap Advent Calendar 2015</a> 8日目の記事です。<br>
ここではBootstrapのテーマの1つである、<a href="http://nico.kubosho.com/">Nico</a>のこれまでとこれからについて書きます。</p>
<h2>これまで</h2>
<p>まずはNicoができてから、現時点の最新バージョンであるv3.3.6-1.1.0までの軌跡を振り返ります。</p>
<p>はじめにNicoを作ったきっかけとしては、現在冬コミに向けて執筆中の<a href="https://github.com/o2project/start-dash-of-site-making">サイト制作のSTART:DASH!!</a>という同人誌です。<br>
同人誌の目的上、ラブライブ!のアニメにでてきたラブライブ参加者募集サイトを実際に作る必要がでてきました。<br>
ただ1からCSSを書くのが面倒と感じた自分は、<a href="http://honokak.osaka/">Honoka</a>をforkし、オリジナルのBootstrapテーマを作ることにしました。</p>
<p>このラブライブ参加者募集サイトですが、図1のアニメ画像キャプチャを見て分かるように配色がピンク系となっています。<br>
配色がピンク系ということは、にこしかいないということで、名前がNicoに決まりました。</p>
<p>しかしHonokaをforkしてできあがったNicoですが、リポジトリーのファイルを見ているうちにいろいろと作業環境を整えたくなりました。<br>
そのためまずは作業環境を整えました。</p>
<h3>作業しやすくするためのSTART:DASH!!</h3>
<p>主にやったことは3つあります。</p>
<p>1つめは、Gruntをなんとなく気分的にグローバルインストールしたくないと思ったため、<a href="https://github.com/kubosho/Nico/commit/57c244d8b8c898efffb45e5e9977222f0a8f6d41">npmのrun-scriptでラップしました</a>。</p>
<p>2つめは、scssファイルがちゃんとできるか自動で確認したかったので、<a href="https://github.com/kubosho/Nico/blob/743aeb2a8e5e102506432dc450e8f2bc8f0efc06/.travis.yml">Travis CIを導入しました</a>。</p>
<p>3つめは、Travis CI導入に関係していますが、HonokaだったりNicoの公開用ファイルをgh-pagesブランチに上げる際は手動で上げないといけませんでした。<br>
しかし手動は面倒だと感じたため、<a href="https://github.com/kubosho/Nico/blob/743aeb2a8e5e102506432dc450e8f2bc8f0efc06/.bin/deploy-to-gh-pages.sh">よしなにgh-pagesブランチへpushしてくれるシェルスクリプトを書きました</a>。</p>
<h3>Nico襲来</h3>
<p>これで作業がしやすくなったので、ようやく配色をHonokaからNico仕様にしていきます。<br>
配色を考える上で真姫・凛・花陽・絵里・希のイメージカラーを入れたいと思い、考えた結果次のような配色になりました。<br>
<code>danger</code>が紫色になっているのは、希のイメージカラーを入れたいためだったのですが、一応根拠もあります。<br>
それは、天気予報で特別警報の配色が紫色というところから来ています。</p>
<table>
<thead>
<tr>
<th>名前</th>
<th>カラーコード</th>
<th>色</th>
</tr>
</thead>
<tbody>
<tr>
<td>default</td>
<td>#f3d4df</td>
<td><div style="width: 1em; height: 1em; background-color: #f3d4df;"></div></td>
</tr>
<tr>
<td>inverse</td>
<td>#ff50ac</td>
<td><div style="width: 1em; height: 1em; background-color: #ff50ac;"></div></td>
</tr>
<tr>
<td>primary</td>
<td>#ff50ac</td>
<td><div style="width: 1em; height: 1em; background-color: #ff50ac;"></div></td>
</tr>
<tr>
<td>success</td>
<td>#4caf50</td>
<td><div style="width: 1em; height: 1em; background-color: #4caf50;"></div></td>
</tr>
<tr>
<td>info</td>
<td>#5cfaf9</td>
<td><div style="width: 1em; height: 1em; background-color: #5cfaf9;"></div></td>
</tr>
<tr>
<td>warning</td>
<td>#ff5052</td>
<td><div style="width: 1em; height: 1em; background-color: #ff5052;"></div></td>
</tr>
<tr>
<td>danger</td>
<td>#ac62ff</td>
<td><div style="width: 1em; height: 1em; background-color: #ac62ff;"></div></td>
</tr>
</tbody>
</table>
<p>そして<a href="https://github.com/kubosho/Nico/releases/tag/v3.3.5a">Nico v3.3.5a</a>をリリースという流れになります。</p>
<h3>なんとかしなきゃ!</h3>
<p>リリースした後は、Honokaのバージョン更新に追従していくだけだったのですが、ある時自分の中で事件が起こります。<br>
それは、<a href="http://coliss.com/articles/build-websites/operation/work/best-templates-for-bootstrap-2015-autumn.html" rel="nofollow">商用利用無料!Bootstrap 3, Bootstrap 4をベースに最近のUIデザインのトレンドを取り入れた新作テーマのまとめ | コリス</a>という記事にHonokaと<a href="https://nkmr6194.github.io/Umi/">Umi</a>は掲載されたのですが、Nicoが掲載されなかったことです。<br>
最初は自分で使うために作ったとはいえ、せっかく作ったし他の人にも使ってほしいと思った自分にとって、ショックを受けた出来事でした。</p>
<p>この時にはHonokaのサイトからNicoがリンクされていたので見てないということはたぶん無いとは思う(と信じたい)のですが、それでも掲載されなかった理由を考えて、配色的に使いづらさがあったという結論に至りました。</p>
<p>特に<code>info</code>の色が強すぎること、また<code>warning</code>と<code>danger</code>の色が元のBootstrapだったり、Honokaとかけ離れているのが原因だったと思います。<br>
そのため、<code>v3.3.5-1.0.0</code>より次のような配色にしました。<br>
基本Honokaを踏襲しつつ、モノクロで見たときに<code>primary</code>より<code>success</code>のほうが色が強くなるよう調整しました。<br>
また<code>info</code> > <code>warning</code> > <code>danger</code>の順に色が強くなっています。</p>
<table>
<thead>
<tr>
<th>名前</th>
<th>カラーコード</th>
<th>色</th>
</tr>
</thead>
<tbody>
<tr>
<td>default</td>
<td>#f3d4df</td>
<td><div style="width: 1em; height: 1em; background-color: #f3d4df;"></div></td>
</tr>
<tr>
<td>inverse</td>
<td>#ff50ac</td>
<td><div style="width: 1em; height: 1em; background-color: #ff50ac;"></div></td>
</tr>
<tr>
<td>primary</td>
<td>#ff64b1</td>
<td><div style="width: 1em; height: 1em; background-color: #ff64b1;"></div></td>
</tr>
<tr>
<td>success</td>
<td>#0faf20</td>
<td><div style="width: 1em; height: 1em; background-color: #0faf20;"></div></td>
</tr>
<tr>
<td>info</td>
<td>#a27dac</td>
<td><div style="width: 1em; height: 1em; background-color: #a27dac;"></div></td>
</tr>
<tr>
<td>warning</td>
<td>#ff7302</td>
<td><div style="width: 1em; height: 1em; background-color: #ff7302;"></div></td>
</tr>
<tr>
<td>danger</td>
<td>#f45042</td>
<td><div style="width: 1em; height: 1em; background-color: #f45042;"></div></td>
</tr>
</tbody>
</table>
<p>なお<code>default</code>と<code>inverse</code>も色を変えれば使いやすくなるかもしれませんが、これを変えてしまうとNicoがNicoで無くなってしまうため、変える予定は今のところありません。</p>
<h2>これから</h2>
<p>というわけで必要に迫られて作り、いろいろと更新したNicoですが、これからの展望としてはHonokaの変更にできる限り付いていきたいと思います。<br>
なんだかんだでBootstrapは便利ですし、しばらく廃れないと思うので、このNicoやHonokaを通じてBootstrapがどのように進化していくのかを見ていこうと思います。</p>
Bootstrap Advent Calendar 2015 8日目の記事です。
2015-12-08T00:00:00.000Z
2022-06-21T06:20:22.000Z
なぜ CSS や Grunt はつらいと言われるのか
tag:blog.kubosho.com,2015-11-12:entry://why-css-and-grunt-is-hard
<p>少し主語を大きく書いてしまいましたが、<code>*.css</code> と <code>gruntfile.js</code> についての話です。</p>
<p>「<a href="http://0-9.sakura.ne.jp/pub/kbkz_tech/start.html">CSS に死を!</a>」と言われたり、「<a href="http://mizchi.hatenablog.com/entry/2014/12/28/160715">CSS 勉強するのはだるい</a>」と言われたりしますが、これらを見ていると「Grunt がつらい」という話と共通項があると感じました。</p>
<h2>どちらも設定ファイルである</h2>
<p>自分の考えとして前提を書くと「<code>*.css</code> と <code>gruntfile.js</code> はそれぞれ「どのような見た目にするか」「どのようなタスクを実行するか」を定義するための設定ファイルである」という考えです。</p>
<p>その前提のもと、設定ファイルであるという利点と欠点をこれから書いていきます。</p>
<h3>利点</h3>
<h4>少ない行数の時の見やすさ</h4>
<p><code>*.css</code> や <code>*gruntfile.js</code> は 200-250 行くらいまでなら、ソースコードの全体が少ない時間で把握でき、何をしているものなのかすぐに分かると思います。</p>
<h4>敷居の低さ</h4>
<p>CSS・Grunt ともに、ブログや Qiita などに上がっているソースコードをコピペしてくれば、なんとなくそれっぽい見た目になったり、タスクが実行できるようになると思います。</p>
<h3>欠点</h3>
<h4>破綻しやすい</h4>
<p>CSS はすぐに、無計画にルールセットを増やしたことによるファイルサイズの肥大化、スタイルの思いもよらぬ上書き (それに伴う !important 地獄)、必要ないルールセットの放置などが発生します。</p>
<p>Grunt も、無計画にタスクを増やしたことによるファイルサイズの肥大化、必要ないタスクの放置が発生しやすいと感じます。</p>
<p>ファイルサイズの肥大化については、CSS・Grunt ともにファイルを分割すれば良いという話ですが、CSS は @import を使うと CSS ファイルの読み込みが並列でおこなわれないため、全ての CSS ファイルを読み込むための時間がかかってしまう問題を抱えています。</p>
<p>また、Grunt も loadTasks() を使えば別ファイルに分割したタスクを読み込むことはできます。しかし、定義されているタスクの一覧性が悪くなるということと、読み込んだタスクが何をやっているのかを見るのが若干面倒という問題を抱えています。</p>
<h4>手法が複数ある</h4>
<p>CSS は MindBEMding だったり、SUIT CSS だったり、セレクタの設計手法が複数あります。</p>
<p>また、画像置換の手法についても、昔ながらの <code>text-indent: -9999px;</code> とする手法から、<a href="http://www.zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement/"><code>text-indent</code> <code>white-space</code> <code>overflow</code> を組み合わせる手法</a>、<a href="http://nicolasgallagher.com/css-image-replacement-with-pseudo-elements/">擬似要素を使う手法</a>など複数あります。</p>
<p>Grunt も例えば Sass を CSS にコンパイルしたいといった時に、<a href="https://github.com/gruntjs/grunt-contrib-sass">gruntjs/grunt-contrib-sass</a> を使えば良いのか、<a href="https://github.com/sindresorhus/grunt-sass">sindresorhus/grunt-sass</a> を使えば良いのか、分からなくなると思います。</p>
<p>複数ある手法から最適解を求めたいところですが、そこに至るまでの時間が長くなりがちで、それがだるさに繋がるのかなと思います。</p>
<h2>CSS が gulp から学べる点はなんなのか?</h2>
<p>と、書いてみたものの、特に思い浮かばないので、ここは任せました。</p>
少し主語を大きく書いてしまいましたが、\*.css と gruntfile.js についての話です。
2015-11-12T00:00:00.000Z
2022-06-21T06:22:54.000Z
fs.exists()がdeprecatedになった理由
tag:blog.kubosho.com,2015-09-20:entry://why-deprecated-of-fs-exists
<p><a href="https://github.com/wearefractal/vinyl-fs">wearefractal/vinyl-fs</a> の <code>dest(folder, [opt])</code> が出力先のディレクトリが無い場合でも、そのディレクトリを作ってくれないということで、自分で「ディレクトリの有無を確認して、無い場合はディレクトリを作る」という処理を作る必要がでてきました。</p>
<p>そこで <a href="https://nodejs.org/api/fs.html">File System Node.js v4.1.0 Manual & Documentation</a> を見て、ディレクトリの有無を確認するのに使えそうな <a href="https://nodejs.org/api/fs.html#fs_fs_exists_path_callback">fs.exists()</a> という API を見つけたのですが、「Deprecated: Use fs.stat or fs.access instead.」ということで、他の API を使うように書かれていました。</p>
<p>「ファイルの有無を確認する API が deprecated になるのはなぜ?」と思い、これは何かあると思って少し調べてみたのでまとめておこうと思います。</p>
<h2>本題</h2>
<p>まず <code>fs.exists()</code> ですが、ドキュメントを見ると以下のようなコードが載っています。</p>
<pre class="language-javascript"><code class="language-javascript">fs<span class="token punctuation">.</span><span class="token method function property-access">exists</span><span class="token punctuation">(</span><span class="token string">'/etc/passwd'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">exists</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span>exists <span class="token operator">?</span> <span class="token string">"it's there"</span> <span class="token operator">:</span> <span class="token string">'no passwd!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<p>この中の callback 関数を見ると、引数として、与えられたパスが存在しているかどうかを示す真偽値が入っていますが、この引数の形式が他の File System の API のように <code>err</code> が第一引数になっていないため、規則に沿っていないということで、<a href="https://github.com/nodejs/node-v0.x-archive/issues/8369#issuecomment-55559828">fs.exists does not follow node conventions · Issue #8369 · nodejs/node-v0.x-archive</a> という issue が作られています。</p>
<p>しかし、二つ目のコメントで事態が変化しています。</p>
<p><a href="https://github.com/nodejs/node-v0.x-archive/issues/8369#issuecomment-55559828">fs.exists does not follow node conventions · Issue #8369 · nodejs/node-v0.x-archive</a></p>
<p>この二つ目のコメントについては id:yosuke_furukawa のツイートを見たほうがどういうことか分かりやすいかもしれません。</p>
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/kubosho_">@kubosho_</a> exists はrace condition に沿わないのでdeprecatedですね。存在チェックした後で消されたらどうするのっていう。普通に読み書きしたエラーでいいはずだし、どうしてもチェックしたかったらaccessかstatを使うというのが通例ですね。</p>— Yosuke FURUKAWA (@yosuke_furukawa) <a href="https://twitter.com/yosuke_furukawa/status/645260394592759808">2015, 9月 19</a></blockquote>
<p>このツイートの「存在チェックした後で消されたらどうするの」というのを処理の流れに落としこむと、<code>fs.exists()</code> で与えられたパスが存在しているか確認し、<code>fs.exists()</code> の callback 関数内で <code>fs.unlinkSync(path)</code> としてファイルを削除した後に、callback 関数の <code>exists</code> 引数を使って <code>exists</code> が true だったら、ファイルを開くというソースコードを書いて実行すると <code>no such file or directory</code> のエラーが出力されます。</p>
<p>実際のソースコードは以下の通りとなります。これなら <code>fs.open(path, "r", callback)</code> として、callback 関数内でファイルの有無によって、処理を分けたほうが入れ子が浅くなりそうで良さそうです。</p>
<script src="https://gist.github.com/kubosho/c19c2267bf4715ba80d2.js"></script>
<p>話を「Node の規則に沿っていないという issue が作られた」というところに戻すと、issue でやりとりがあった後、<a href="https://github.com/nodejs/node-v0.x-archive/pull/8418">fs: deprecate exists() and existsSync() by cjihrig · Pull Request #8418 · nodejs/node-v0.x-archive</a> という Pull Request が作られます。</p>
<p>この Pull Request は元のタイトルが「 fs: add errback style support to exists()」とあるように、<a href="https://github.com/cjihrig/node/commit/aeb381ccf6f72546e4ad1a3615d29f52f49dacf4">互換性を保ちつつ、callback 関数の第一引数に error が入るようにしたもの</a>がコミットされていました。</p>
<p>Pull Request 内でコードレビューがおこなわれ、<a href="http://jsperf.com/function-length-performance/8">Function.length のパフォーマンスが悪い</a>という指摘があったりしたのですが、それらの指摘を踏まえて Pull Request を open した cjihrig 氏は<a href="https://github.com/nodejs/node-v0.x-archive/pull/8418#discussion_r17825801">いくつか提案をしています</a>(何もしない、互換性がある、または壊す形で第一引数の <code>err</code> をサポートする)。</p>
<p>しかし、再び事態が変わります。<a href="https://github.com/nodejs/node-v0.x-archive/pull/8418#discussion_r17825997"><code>fs.exists()</code> を deprecate にして代わりに <code>fs.access()</code> を使うようにする</a>というコメントがされました。</p>
<p>そして、そのコメントが流れを変えて、<code>fs.exists()</code> は第一引数の <code>err</code> がサポートされることなく deprecated になりました。</p>
<p>それが、以下のツイートに繋がるのではと思います。</p>
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/kubosho_">@kubosho_</a> そうですね。その例の他にもNodeと無関係な全く別なプロセスからファイルが削除される事もあるから、exists => read みたいな事やろうとするのって筋悪なんですよね。突き詰めていくとexists自体の必要性が怪しくて、deprecatedっていう。</p>— Yosuke FURUKAWA (@yosuke_furukawa) <a href="https://twitter.com/yosuke_furukawa/status/645276523625234433">2015, 9月 19</a></blockquote>
<h2>まとめ</h2>
<p>ということで、「ディレクトリの有無を確認して、無い場合はディレクトリを作る」という処理を作る必要が出てきて、その有無の確認のために <code>fs.exists()</code> を使おうとしたら deprecated になっていて、なぜだろうと思っていろいろと調べたら、なんとなく <code>fs.exists()</code> が deprecated になった経緯が分かって勉強になったという話でした。</p>
<p>また、これを通じて「ディレクトリの有無を確認して、無い場合はディレクトリを作る」という処理は「ディレクトリを作るように試み、既に存在したら(エラーになったら)作らない」という処理になりました。</p>
<p>具体的なソースコードとしては、最初は <code>fs.exists()</code> を使っていたため、以下のようなソースコードになっていました。</p>
<script src="https://gist.github.com/kubosho/d4052651a1c8b8153a5b.js"></script>
<p>ですが、これを「ディレクトリを作るように試み、既に存在したら(エラーになったら)作らない」という考え方で書き換えて以下のようにしました。</p>
<script src="https://gist.github.com/kubosho/d26ef7da6c399c318365.js"></script>
<p>結果的に、<code>fs.exists()</code> という deprecated になった API を使う必要がなくなり、また入れ子も浅くなりソースコードも短くなりました。</p>
wearefractal/vinyl-fs の dest(folder, \[opt]) が出力先のディレクトリが無い場合でも、そのディレクトリを作ってくれないということで、自分で「ディレクトリの有無を確認して、無い場合はディレクトリを作る」という処理を作る必要がでてきました。
2015-09-20T00:00:00.000Z
2022-11-28T15:34:34.000Z
MindBEMding の Modifier は元のクラス名と一緒に指定するべきか否か
tag:blog.kubosho.com,2015-05-11:entry://extend-base-ruleset-vs-define-base-class-and-modifier-class-in-html
<p>MindBEMding の Modifier を定義する際、単一のクラスセレクタで書く方法と、複数のクラスセレクタで書く方法があると思います。</p>
<p>実際の HTML で示すと以下のような感じです。</p>
<h2>複数クラス</h2>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>table</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>mod-table-01 mod-table-01--line-color-green<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>th</span><span class="token punctuation">></span></span>foo<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>th</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>th</span><span class="token punctuation">></span></span>bar<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>th</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>td</span><span class="token punctuation">></span></span>baz<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>td</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>td</span><span class="token punctuation">></span></span>foobar<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>td</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>table</span><span class="token punctuation">></span></span>
</code></pre>
<h2>単一クラス</h2>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>table</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>mod-table-02--line-color-green<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>th</span><span class="token punctuation">></span></span>foo<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>th</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>th</span><span class="token punctuation">></span></span>bar<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>th</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>td</span><span class="token punctuation">></span></span>baz<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>td</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>td</span><span class="token punctuation">></span></span>foobar<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>td</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>table</span><span class="token punctuation">></span></span>
</code></pre>
<p><code>multiple class</code> とコメントで書かれているほうでは、クラス名は <code>mod-table-01</code> と <code>mod-table-01--line-color-green</code> の二つが指定されています。</p>
<p><code>single class</code> とコメントで書かれているほうでは、クラス名は <code>mod-table-02--line-color-green</code> のみ指定されています。</p>
<p>上記の HTML に対し、CSS でルールセットを書く場合は以下のようになると思います。</p>
<h2>複数クラス</h2>
<pre class="language-css"><code class="language-css"><span class="token selector"><span class="token class">.mod-table-01</span></span> <span class="token punctuation">{</span>
<span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token unit">px</span> solid <span class="token color">black</span><span class="token punctuation">;</span>
<span class="token property">border-collapse</span><span class="token punctuation">:</span> collapse<span class="token punctuation">;</span>
<span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">10</span><span class="token unit">px</span> auto<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector"><span class="token class">.mod-table-01--line-color-green</span></span> <span class="token punctuation">{</span>
<span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token unit">px</span> solid <span class="token color">green</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<h2>単一クラス</h2>
<pre class="language-css"><code class="language-css"><span class="token selector"><span class="token class">.mod-table-02</span><span class="token punctuation">,</span>
<span class="token class">.mod-table-02--line-color-green</span></span> <span class="token punctuation">{</span>
<span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token unit">px</span> solid <span class="token color">black</span><span class="token punctuation">;</span>
<span class="token property">border-collapse</span><span class="token punctuation">:</span> collapse<span class="token punctuation">;</span>
<span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">10</span><span class="token unit">px</span> auto<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector"><span class="token class">.mod-table-02--line-color-green</span></span> <span class="token punctuation">{</span>
<span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token unit">px</span> solid <span class="token color">green</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>この二つの指定方法のうち、果たしてどちらが良いのかというのを考えたので、以下に利点と欠点を書いていきます。</p>
<h2>HTML に単一のクラス名を指定する際の利点と欠点</h2>
<h3>利点</h3>
<p><strong>複数のクラスを指定するより、若干簡潔になる</strong></p>
<p>MindBEMding の考えでセレクタに名前を付けた場合は名前が長くなりがちです。複数のクラス名を指定した場合は、上記で示した HTML の例を見ると分かるように冗長感が否めません。</p>
<p>その一方、単一のクラス名で指定した場合は、HTML 側の指定は複数のクラス名指定より、簡潔になります。</p>
<h3>欠点</h3>
<p><strong>スタイル定義が複雑になる</strong></p>
<p>下記の JSFiddle の例を見ると分かるのですが、単一のクラス名を指定するほうが、複数のクラス名を指定するより、スタイル定義が複雑になっています。</p>
<iframe width="100%" height="300" src="//jsfiddle.net/aempn99y/2/embedded/result,html,css" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<p>これは例えば、後からプロジェクトに入ってきた人が CSS ファイルで定義されている内容を見た時に、理解を妨げる原因になるのではという考えがあります。</p>
<p><strong>CSS のファイルサイズが大きくなりがち</strong></p>
<p><a href="http://www.luft.co.jp/cgi/str_counter.php">文字数 カウント(文字バイト数チェック)</a>で測ると分かるのですが、単一のクラス名を HTML 側で指定してスタイル定義をしていく場合、複数のクラス名を HTML 側で指定するより、CSS のファイルサイズが大きくなります。</p>
<h2>HTML に複数のクラス名を指定する際の利点と欠点</h2>
<h3>利点</h3>
<p><strong>スタイル定義の見通しが良くなる</strong></p>
<p>再び先ほどの JSFiddle の例を引っ張り出しますが、複数のクラス名を指定する場合、単一のクラス名を指定するより CSS のルールセット定義が簡潔になっています。</p>
<iframe width="100%" height="300" src="//jsfiddle.net/aempn99y/2/embedded/result,html,css" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<h3>欠点</h3>
<p><strong>HTML 上でのクラス名の指定が単一のクラスを指定するより若干冗長になる</strong></p>
<p>単一のクラス名を定義する時は HTML では <code>prefix-table-01--line-color-green</code> とだけ class 属性の値に書けばよかったですが、複数のクラスを定義する場合は <code>prefix-table-01 prefix-table-01--line-color-green</code> と若干冗長になります。</p>
<h2>結果どちらを使ったほうが良いのか</h2>
<p>単一のクラス名を指定するほうは HTML 側が少し簡潔になりますが、複数のクラス名を指定するのと比べ CSS 側が複雑になりがちというのは先ほど書いたとおりです。</p>
<p>その複雑になりがちというのが自分ではあまり許容できなかったので、複数のクラス名を HTML の class 属性の値として指定して、スタイル定義をしていくのが良いかなと思いました。</p>
<h2>他の参考記事</h2>
<p>マルチクラス設計について物申している記事もあるので、よかったらこちらも参考にしてみてください。</p>
<p><a href="http://morishitter.hatenablog.com/entry/2014/11/28/004234">CSSプリプロセッサーの<code>extend</code>の悪いところ - morishitter blog</a></p>
MindBEMding の Modifier を定義する際、単一のクラスセレクタで書く方法と、複数のクラスセレクタで書く方法があると思います。
2015-05-11T00:00:00.000Z
2022-06-21T06:22:12.000Z
GitHub の Contributions を Ingress の Resistance 色にする Chrome 拡張を作った
tag:blog.kubosho.com,2015-04-06:entry://change-ingress-registance-color-of-github-contributions
<p>GitHub の Contributions を眺めていて「これって Enlightened の色だよね」と思ったので、Resistance の色に置き換えるような Chrome 拡張を作ってみました。</p>
<p><a href="https://chrome.google.com/webstore/detail/resistance-contributions/codbppehieinnfafggcefkipfajcapep">Resistance Contributions - Chrome ウェブストア</a></p>
<p>ソースはこちらにあります。</p>
<p><a href="https://github.com/kubosho/resistance-contributions">kubosho/resistance-contributions</a></p>
<p>ちなみに自分は Enlightened です。</p>
GitHub の Contributions を眺めていて「これって Enlightened の色だよね」と思ったので、Resistance の色に置き換えるような Chrome 拡張を作ってみました。
2015-04-06T00:00:00.000Z
2022-11-28T15:38:52.000Z
編集しやすいCSSにするために自分が心がけている事
tag:blog.kubosho.com,2015-02-23:entry://mindful-of-coding-css
<p>CSS は、書くのが怖いと自分は感じます。</p>
<p>例えば、ある程度運用したサービスやアプリとなると、自分が変更した点が思いもよらぬところに反映されてしまい「しまった」と思った事はあると思います。</p>
<p>とはいえ、運用していく上で、何も変更しないというのはありえません。なので、そういった恐怖からなるべく解放されるために自分が心がけている事を書いていきます。</p>
<h2>コメントを書く</h2>
<p>自分の場合は、そのセレクタがどこで使われているかという情報を書く事が非常に多いです。例としては以下のような感じです。</p>
<pre class="language-sass"><code class="language-sass"><span class="token comment">//------------------------------------------------------------------------</span>
<span class="token comment">// Common: サイト上部のヘッダー</span>
<span class="token comment">//------------------------------------------------------------------------</span>
<span class="token selector">.prefix-global-header {</span>
<span class="token property-line"> <span class="token property">background</span><span class="token punctuation">:</span> #000;</span>
<span class="token selector">}</span>
</code></pre>
<p>このようにする事で区切りが分かりやすくなると思っています。また、ルールセットがどう書かれているかが、より頭の中に入ってくると自分は感じています。</p>
<p>ちなみに上記の区切りは、Sass や LESS でしか使えない(コメントアウトに <code>//</code> を使っているため)ので、CSS でも区切りを付けたい場合は、<a href="https://github.com/csswizardry/inuit.css">inuit.css</a>の以下の区切りが良いなと自分は感じています。</p>
<pre class="language-css"><code class="language-css"><span class="token comment">/*------------------------------------*\
はうはう
\*------------------------------------*/</span>
</code></pre>
<h2>class 名や id 名を意味のある名前にする</h2>
<p>極端な例ですが、以下のように「要素名をそのまま繰り返しただけの class 名」というのは意味が無いと思います(以下の例では、いっそ要素型セレクタでスタイル指定したほうがいいのではと思います)。</p>
<p><a class="jsbin-embed" href="http://jsbin.com/vibejoqaka/4/embed?html,css,output">JS Bin</a><script src="http://static.jsbin.com/js/embed.js"></script></p>
<p>では、自分はどのように名付けるかという話ですが、今は<a href="http://blog.kubosho.com/entry/2014/12/09/valhalla-gate-css-architecture">神獄のヴァルハラゲートの CSS 設計</a>でも書いたように、MindBEMding を使った命名にするかなという感じです。</p>
<p>例えば <code>.header</code> としているところなら、<code>.prefix-global-header</code> になるかもしれないですし <code>.prefix-top-header</code> になるかもしれません。</p>
<h2><code>!important</code> を使う時は注意深く使う</h2>
<p>CSS を書いていく上で、どうしても <code>!important</code> を使いたくなる時があると思います。そんな時は <code>!important</code> を使わないように CSS を書き直すよりも <code>!important</code> を使ったほうが、時間がかからなかったり複雑にならない可能性が高いと感じています。</p>
<p>とはいえ、<code>!important</code> は乱用するものではありません。改修に時間がかからなそうだったり複雑にならなそうであれば、使わないほうが良いです。</p>
<p>なお自分が <code>!important</code> を使う時は、なぜ <code>!important</code> を使うのかというコメントを絶対書いています。それは以下の理由です。</p>
<ul>
<li>意味が書いてない <code>!important</code> は消すのが怖いため
<ul>
<li>消したらどこかに悪影響が出るのではという恐怖が生まれる</li>
</ul>
</li>
<li>将来 CSS を書き直した時に消せるようになるかもしれないため
<ul>
<li>上記でも書いたように、なるべく使わないようにしたい</li>
</ul>
</li>
</ul>
<h2>style 属性を使う時は注意深く使う</h2>
<p><code>!important</code> と同じく、乱用すべきものではないですが、かといって、ある機能に関するページが 10 ページくらいあったとして、そのうち 1 ページでしか使わない(かつスタイルを適用させたいところも少ない)となると、CSS ファイル内でスタイル指定をするよりも、style 属性でスタイル指定をしたほうが、時間がかからなかったり複雑にならない可能性が高いと感じています。</p>
<p>それ以外では、style 属性を使わないほうが良いと思います。</p>
<h2>最後に</h2>
<p>ここまで、CSS を書く際に心がけている事を書いてきましたが、こういう心がけは以下の思いから心がけようとしています。</p>
<p><a href="https://twitter.com/kubosho_/status/569730148536164352">ドキュメント残しておかないと、身軽になれないし、あとは気をつけていても病気とか事故にあって長期離脱という可能性は 0 ではないので、そうなった時に引き継いだ人が積むし、自分への恨みが起こると思うので、ドキュメントは出来るだけ残しておきたいと自分は考えている。</a></p>
CSS は、書くのが怖いと自分は感じます。
2015-02-23T00:00:00.000Z
2022-11-28T15:23:50.000Z
background-imageは仕様上アニメーションを適用できない
tag:blog.kubosho.com,2015-01-15:entry://background-image-is-not-animatable
<p>CSSで <code>@keyframes</code> に <code>background-image</code> プロパティを指定してクロスフェード効果で背景画像の表示が切り替わるという動作を実装しようとしました。</p>
<p>実際にChromeでは期待通りの動作をしました。ただFirefoxとAndroid Browserではアニメーションどころか画像自体が表示されずなぜそうなるのか謎でした。</p>
<p><a href="http://jsfiddle.net/csmt3fyn/3/">クロスフェードされないコードを確認するためのJSFiddle</a></p>
<h2>そもそもbackground-imageはアニメーション不可能</h2>
<blockquote class="twitter-tweet" lang="ja"><p><a href="https://twitter.com/o_ti">@o_ti</a> <a href="https://twitter.com/kubosho_">@kubosho_</a> background-image はアニメーション不可能なプロパティでだからではないですか?</p>— xl1blue (@xl1blue) <a href="https://twitter.com/xl1blue/status/555695483037822977">2015, 1月 15</a></blockquote>
<p>!?</p>
<blockquote class="twitter-tweet" lang="ja"><p><a href="https://twitter.com/kubosho_">@kubosho_</a> <a href="https://twitter.com/xl1blue">@xl1blue</a> ホントだ。Animatable: no だった。<a href="http://t.co/JopFQtOO5F">http://t.co/JopFQtOO5F</a></p>— 越智 (@o_ti) <a href="https://twitter.com/o_ti/status/555696632675594240">2015, 1月 15</a></blockquote>
<p>なん……だと……?</p>
<p>background-imageは仕様上アニメーション不可能なプロパティですが、Chromeが仕様に準拠していませんでした。</p>
<p>なので仕様に沿う形で書き直しました。</p>
<h2>各ブラウザーでクロスフェードされるように書き直したコード</h2>
<h3>HTML</h3>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>test-01<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://picsum.photos/id/0/400/200<span class="token punctuation">"</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://picsum.photos/id/1/400/200<span class="token punctuation">"</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
</code></pre>
<h3>CSS</h3>
<pre class="language-css"><code class="language-css"><span class="token selector"><span class="token class">.test-01</span></span> <span class="token punctuation">{</span>
<span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector"><span class="token class">.test-01</span> img<span class="token pseudo-class">:first-child</span></span> <span class="token punctuation">{</span>
<span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
<span class="token property">animation</span><span class="token punctuation">:</span> crossfade <span class="token number">5</span><span class="token unit">s</span> linear <span class="token number">0</span><span class="token unit">s</span> infinite alternate<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token atrule"><span class="token rule">@keyframes</span> crossfade</span> <span class="token punctuation">{</span>
<span class="token selector">0%</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token selector">100%</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a href="http://jsfiddle.net/ts2qu35b/20/">クロスフェードされるコードを確認するためのJSFiddle</a></p>
CSSで @keyframes に background-image プロパティを指定してクロスフェード効果で背景画像の表示が切り替わるという動作を実装しようとしました。
2015-01-15T00:00:00.000Z
2022-12-01T05:47:05.000Z
神獄のヴァルハラゲートの CSS 設計
tag:blog.kubosho.com,2014-12-09:entry://valhalla-gate-css-architecture
<p><a href="http://www.adventar.org/calendars/337">CSS Architecture Advent Calendar 2014</a> 9 日目の記事になります。</p>
<p><a href="http://grani.jp/product/valhalla-gate/">神獄のヴァルハラゲート</a>の CSS 設計方法について振り返りつつ、こうしているということや、上手くいったところ、改善したいところを書いていこうと思います。</p>
<h2>アプリの規模</h2>
<p>ASP.NET MVC を使っていて、View 側は Razor テンプレートを使っているのですが、Razor のファイルを検索してみると以下の量となります。</p>
<pre class="language-shell"><code class="language-shell"><span class="token function">find</span> ./ -name <span class="token string">"*.cshtml"</span> <span class="token operator">|</span> <span class="token function">wc</span> -l
<span class="token number">1674</span>
</code></pre>
<p>実際には、これにフィーチャーフォン向けのファイルや、部分的な View ファイルも含まれています。</p>
<p>なので、実際 CSS を適用しているファイルの量は、この検索結果よりは格段に減りますが、それでも、約 600 ファイルはあると思います。</p>
<p>ちなみに、今年のはじめに同僚の<a href="https://twitter.com/mayuki">@mayuki</a>が、<a href="https://speakerdeck.com/mayuki/sosiyarugemufalsehurontoendotoasp-dot-net-mvc-lite">ソーシャルゲームのフロントエンドと ASP.NET MVC (Lite)</a>というタイトルで、<a href="http://partake.in/events/a531c0be-e8dd-46fe-a73c-e51d8ad7a69b">めとべや東京#3 (Room metro Tokyo #3)</a>にて発表したのですが、そこには「View 数は 400 超」と書いてあるので、1 年間の運用で約 200 ファイル増えたことになります。</p>
<h2>対応端末、ブラウザー</h2>
<p>スマートフォンでは、以下の環境でアクセスされることを想定して対応しています。</p>
<h3>OS</h3>
<ul>
<li>iOS 6 or later</li>
<li>Android 2.3.x
<ul>
<li>重要な機能だったら、Android 2.2.x にも対応することも…</li>
</ul>
</li>
<li>Android 4.0 or later</li>
</ul>
<h3>ブラウザー</h3>
<ul>
<li>iOS
<ul>
<li>Safari</li>
<li>WebView</li>
</ul>
</li>
<li>Android
<ul>
<li>Android Browser</li>
<li>Google Chrome</li>
<li><a href="https://gist.github.com/uupaa/b25c9cf47bbeedea5a7f">S Browser</a></li>
</ul>
</li>
</ul>
<p>iOS 6 や Android 2 系はそろそろ対応端末から外したいなと思っています。来年の今頃は対応しなくて良くなってたらいいですね。</p>
<h2>命名規則</h2>
<p><a href="https://en.bem.info/method/naming-convention/">BEM</a>を採用しています。ただし、セレクタの命名規則は以下のように変えています。</p>
<pre class="language-css"><code class="language-css"><span class="token selector"><span class="token attribute"><span class="token punctuation">[</span><span class="token attr-name">prefix</span><span class="token punctuation">]</span></span>-<span class="token attribute"><span class="token punctuation">[</span><span class="token attr-name">block</span><span class="token punctuation">]</span></span>_<span class="token attribute"><span class="token punctuation">[</span><span class="token attr-name">element</span><span class="token punctuation">]</span></span>-[<span class="token attribute"><span class="token punctuation">[</span><span class="token attr-name">Modifier-Key</span><span class="token punctuation">]</span></span>-<span class="token attribute"><span class="token punctuation">[</span><span class="token attr-name">Modifiler-Value</span><span class="token punctuation">]</span></span>]</span> <span class="token punctuation">{</span>
// <span class="token property">property</span><span class="token punctuation">:</span> value<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a href="http://geckotang.tumblr.com/post/104065014321/css">今年のネーミングルール #CSS 設計 - < /gecko ></a>とだいたい同じですが、以下の点が異なります。</p>
<ul>
<li>Block と Element の区切り文字は「_(アンダースコア)」</li>
<li>複数の単語を連結する場合は「-(ハイフン)」を使う</li>
<li>Modifier は CamelCase を使う。例は以下の通り
<ul>
<li>foo-Bar-Baz ([block]-[Modifier-Key]-[Modifier-Value])</li>
<li>foo<em>bar-Baz ([block]</em>[element]-[Modifier-Value])</li>
</ul>
</li>
<li>prefix は、共通で使うルールセットはプロジェクトのコードネーム、各機能のみで使うルールセットはその機能名を使う
<ul>
<li>ガチャなら prefix は<code>gacha</code>という感じ</li>
</ul>
</li>
</ul>
<p>あとは、<a href="https://github.com/hiloki/flocss#mindbemding">hiloki/flocss</a>の MindBEMding の章にあるように、JavaScript で操作されるような「状態」を表すような Modifier については、SMACSS の State パターンの命名のように、<code>is-*</code>プレフィックスを付けて<code>.is-active</code>という感じにしています。</p>
<p><code>.is-active</code>には直接スタイル指定をすることを禁止しています。</p>
<pre class="language-sass"><code class="language-sass"><span class="token comment">// これはOK</span>
<span class="token selector">.block_element.is-active {</span>
<span class="token property-line"> <span class="token property">display</span><span class="token punctuation">:</span> block;</span>
<span class="token selector">}</span>
<span class="token comment">// これはNG</span>
<span class="token selector">.is-active {</span>
<span class="token property-line"> <span class="token property">display</span><span class="token punctuation">:</span> block;</span>
<span class="token selector">}</span>
</code></pre>
<h3>良いところ</h3>
<ul>
<li><code>--</code>や<code>__</code>という区切り文字より、セレクタ名が醜くならない(個人の主観です)</li>
</ul>
<p>あとは構造が分かりやすいだったり、class 名が衝突するということが少ないという、BEM や MindBEMding を採用した人ならだいたい感じることでしょうか。</p>
<h3>改善したいところ</h3>
<ul>
<li>prefix のところで世代管理をしなかったのは間違いだった
<ul>
<li><a href="http://geckotang.tumblr.com/post/104065014321/css">今年のネーミングルール #CSS 設計 - < /gecko ></a>を読んで気づいた…</li>
<li>古いセレクタ名と、上記の命名規則を適用したセレクタ名が混ざっていて、辛くなることがある</li>
</ul>
</li>
<li>Modifier を使っている class 名で、Modifier-Key がない class 名というのは、分かりにくいのではと思った
<ul>
<li>この章を書いて気づいた…</li>
</ul>
</li>
</ul>
<h2>ディレクトリ構成</h2>
<p><a href="https://github.com/hiloki/flocss">hiloki/flocss</a> に基本は準拠しています。「基本は」と書いたのは以下のディレクトリ名を自分の好みで変えているからです。</p>
<ul>
<li>foundation -> base</li>
<li>object/project -> object/page</li>
</ul>
<h2>使っている CSS プリプロセッサーやライブラリー</h2>
<ul>
<li>LESS</li>
<li>Normalize.css</li>
</ul>
<p>LESS な理由ですが、<a href="https://speakerdeck.com/mayuki/sosiyarugemufalsehurontoendotoasp-dot-net-mvc-lite?slide=7">ソーシャルゲームのフロントエンドと ASP.NET MVC (Lite)</a>の 7 ページにも書いてあるように、Visual Studio との相性が良かった(新規ファイル作成時に*.less 形式でのみファイルが作れた)ことが要因です。</p>
<p>とはいえ、MSDN Blogs の<a href="http://blogs.msdn.com/b/webdev/archive/2014/02/25/announcing-new-web-features-in-visual-studio-2013-update-2-ctp2.aspx">Announcing new Web Features in Visual Studio 2013 Update 2 CTP2</a>にも書かれているように、Visual Studio 2013 Update 2(ちなみに今は Update 4 が最新)から公式に Sass(*.scss 形式)のファイルも新規作成できるようになったので、Visual Studio ユーザーでも好みで LESS か Sass かを選べるようになったと言えます。</p>
<p>ライブラリーは Normalize.css くらいしか使っていないです。これはやはり同僚の@mayuki が入社したての頃に、汎用 class をゴリッと書いてくれたので、ライブラリーを使う理由があまり無くなったという感じです。</p>
<h2>CSS プリプロセッサーの機能について</h2>
<h3>extend</h3>
<p><a href="https://github.com/hiloki/flocss#css%E3%83%97%E3%83%AA%E3%83%97%E3%83%AD%E3%82%BB%E3%83%83%E3%82%B5%E3%81%AEextend">CSS プリプロセッサの Extend - hiloki/flocss</a>に書かれているように、モジュールで完結する extend は許容し、それ以外は禁止しています。むやみに extend を多用すると、どこにそのルールセットが書かれているか分からなくなり破綻する、というのが大きな理由です。</p>
<h3>ルールセットの入れ子</h3>
<p>CSS プリプロセッサーのほとんど(全て?)はルールセットの入れ子がおこなえますが、入れ子の深さは二段階までと定めています。具体例としては以下のコードです。</p>
<pre class="language-sass"><code class="language-sass"><span class="token selector">.foo {</span>
<span class="token property-line"> <span class="token property">border</span><span class="token punctuation">:</span> 1px solid #003760;</span>
<span class="token property-line"> <span class="token property">color</span><span class="token punctuation">:</span> #000;</span>
<span class="token property-line"> <span class="token property">background</span><span class="token punctuation">:</span> rgba(0, 0, 0, 0.5);</span>
<span class="token selector">.nest-01 {</span>
<span class="token property-line"> <span class="token property">font-weight</span><span class="token punctuation">:</span> bold;</span>
<span class="token selector">.nest-02 {</span>
<span class="token property-line"> <span class="token property">color</span><span class="token punctuation">:</span> #f00;</span>
<span class="token selector">}</span>
<span class="token selector">}</span>
<span class="token selector">}</span>
</code></pre>
<p>なぜ、二段階までに抑えているのかというと、制限がなかった場合、出力後の CSS のセレクタ部分がとても長くなってしまう可能性があるということが挙げられます。</p>
<p>具体例を書くと、以下のような LESS のコードがあったとします。</p>
<pre class="language-sass"><code class="language-sass"><span class="token comment">// Uuuugly!</span>
<span class="token selector">.foo {</span>
<span class="token selector">.nest-01 {</span>
<span class="token selector">.nest-02 {</span>
<span class="token selector">.nest-03 {</span>
<span class="token selector">.nest-04 {</span>
<span class="token selector">.nest-05 {</span>
<span class="token property-line"> <span class="token property">color</span><span class="token punctuation">:</span> #333;</span>
<span class="token selector">}</span>
<span class="token selector">}</span>
<span class="token selector">}</span>
<span class="token selector">}</span>
<span class="token selector">}</span>
<span class="token selector">}</span>
</code></pre>
<p>上記のコードを CSS にコンパイルした場合、以下のようになるでしょう。非常に長くて醜いです。</p>
<pre class="language-css"><code class="language-css"><span class="token selector"><span class="token class">.foo</span> <span class="token class">.nest-01</span> <span class="token class">.nest-02</span> <span class="token class">.nest-03</span> <span class="token class">.nest-04</span> <span class="token class">.nest-05</span></span> <span class="token punctuation">{</span>
<span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode color">#333</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>また、実際に挙動を確かめられていないですが、多くのサイトで「ブラウザーのセレクターの解釈として、右から左に解釈される」と書かれています。</p>
<p>とすると、上記の CSS は「.nest-05 -> .nest-04 -> .nest-03 -> .nest-02 -> .nest-01 -> .foo」と解釈されることになります。「.nest-01 -> .foo」という構造よりも解釈に時間がかかりそうです。</p>
<p>ちなみに、古い記事(2011 年)ですが、<a href="http://developers.linecorp.com/blog/?p=178">CSS セレクタによる高速化、実際のところ « LINE Engineers' Blog</a>に実際の計測結果が掲載されており、そこには以下のように書かれています。</p>
<blockquote>
・スタイルを当てる要素にはできるだけclass又はIDを指定する<br>
・子孫セレクタは重いのできるだけ減らす<br>
という施策に一定の効果はあるようですが、その効果が如実に現れるのはHTML、CSSのコードが非常に大きいページに限られるようです。<br>
そのなかでも、子孫セレクタを減らす施策よりも、スタイルを当てる要素にはできるだけclass名を指定する施策のほうが、効果があるようです。
</blockquote>
<p>ということで、MindBEMding の考え方を適用し、ある Block の中でスタイルを当てたい要素には、.block_element だったり、.block_element-Key-Value という感じで class 名を指定し、スタイルを適用しています。</p>
<h2>まとめ</h2>
<p>ソーシャルゲームというのは、最初から機能が数十種類あったり、View のファイル数が数百ファイルを超えるということは珍しくないと思います。</p>
<p>そんな中で、CSS を書く上での指針がないと、時間が経つにつれ運用が苦痛になってきます。</p>
<p>例えば新しい人が入ってきたり、自分に何かあって他の人が一時的にプロジェクトに入ってきた場合、CSS を書く上での指針が無いと、どのように CSS を書いていけばいいのか、理解に時間がかかることになります。</p>
<p>なので、CSS を書く上での指針を定め、かつ、それを GitHub の Wiki など、プロジェクトのメンバーが目に入る場所に残しておくのが重要と、自分は考えています。</p>
<p>明日は、<a href="http://www.adventar.org/users/9">越智</a>さんです。</p>
<h2>記事内で紹介した GitHub のリポジトリや記事</h2>
<ul>
<li><a href="https://github.com/hiloki/flocss">hiloki/flocss</a></li>
<li><a href="https://speakerdeck.com/mayuki/sosiyarugemufalsehurontoendotoasp-dot-net-mvc-lite">ソーシャルゲームのフロントエンドと ASP.NET MVC (Lite)</a></li>
<li><a href="http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/">MindBEMding – getting your head ’round BEM syntax – CSS Wizardry – CSS, OOCSS, front-end architecture, performance and more, by Harry Roberts</a></li>
<li><a href="http://blogs.msdn.com/b/webdev/archive/2014/02/25/announcing-new-web-features-in-visual-studio-2013-update-2-ctp2.aspx">Announcing new Web Features in Visual Studio 2013 Update 2 CTP2 - .NET Web Development and Tools Blog - Site Home - MSDN Blogs</a></li>
<li><a href="http://developers.linecorp.com/blog/?p=178">CSS セレクタによる高速化、実際のところ « LINE Engineers' Blog</a></li>
</ul>
CSS Architecture Advent Calendar 2014 9 日目の記事になります。
2014-12-09T00:00:00.000Z
2022-11-28T15:23:32.000Z
colgroup 要素や col 要素は適用できる CSS のプロパティに制限がある
tag:blog.kubosho.com,2014-12-01:entry://restrict-css-property-of-colgroup-col
<h2>やりたかったこと</h2>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>table</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>colgroup</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>1<span class="token punctuation">"</span></span> <span class="token special-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value css language-css"><span class="token property">padding</span><span class="token punctuation">:</span><span class="token number">10</span><span class="token unit">px</span><span class="token punctuation">;</span> <span class="token property">background</span><span class="token punctuation">:</span><span class="token hexcode color">#66c</span><span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span><span class="token hexcode color">#fff</span><span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>tbody</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>td</span><span class="token punctuation">></span></span>10<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>td</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>td</span><span class="token punctuation">></span></span>foo<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>td</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>td</span><span class="token punctuation">></span></span>20<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>td</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>td</span><span class="token punctuation">></span></span>bar<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>td</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>td</span><span class="token punctuation">></span></span>30<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>td</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>td</span><span class="token punctuation">></span></span>baz<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>td</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>tr</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>tbody</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>table</span><span class="token punctuation">></span></span>
</code></pre>
<p>という HTML を書いた際に、縦 1 列目に padding, background, color, text-align の指定が適用される想定でした。</p>
<h2>問題</h2>
<p><a href="http://jsbin.com/xaleva/4/edit?html,output">上記の HTML を書いた JS Bin</a>を見ると分かるように、background の指定以外は適用されていません。なぜ?</p>
<h2>分かったこと</h2>
<p><a href="http://www.w3.org/TR/CSS21/tables.html#columns">W3C の CSS 2.1 の仕様書内にある Tables 17.3 Columns</a>を見ると分かるのですが、table-column や table-column-group のプロパティが指定されている要素(col 要素と colgroup 要素)には、下記 4 つのプロパティのみ指定できるようです。</p>
<ul>
<li>border
<ul>
<li>table 要素に<code>border-collapse: collapse;</code>が指定されている時のみ適用される</li>
</ul>
</li>
<li>background</li>
<li>width</li>
<li>visibility</li>
</ul>
<h2>まとめ</h2>
<p>自分が適用したかったスタイルは colgroup 要素や col 要素では適用できないことが分かったので、colgroup 要素や col 要素は使わないことにしました。</p>
<p>その代わりに、縦 1 列目に class を指定して、その class に適用したかったスタイルを指定することにしました。</p>
やりたかったこと
2014-12-01T00:00:00.000Z
2022-11-28T15:17:46.000Z
カラーコードを正規表現を使って判定する
tag:blog.kubosho.com,2014-06-15:entry://color-code-regexp
<p>カラーコードを判定するための正規表現を書きました。</p>
<pre><code>^#([\da-fA-F]{6}|[\da-fA-F]{3})$
</code></pre>
<p>カラーコードの正規表現が合っているかどうかの検証に使った文字列は次の通りです。</p>
<pre><code>// match
#339
#251
#aaa
#fff
#AAA
#cdf
#Abc3Fc
#F9012b
#afdcbf
#987345
// mismatch
#9af#f6f
339
621345
af89f8
#ggg
#fgf
#delcmi
#3r9
#-12345
#jjjjjj
#aaaaaaa
jkhfng
ff8iju
</code></pre>
<p>matchに挙げた文字列はカラーコードと判定されることを確認しています。またmismatchに挙げた文字列はカラーコードと判定されないことを確認してます。</p>
<h2>正規表現の検証に使ったページ</h2>
<p><a href="https://regex101.com/">regex101: build, test, and debug regex</a></p>
<h2>参考にしたページ</h2>
<ul>
<li><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions">正規表現 - JavaScript | MDN</a></li>
<li><a href="https://userweb.mnet.ne.jp/nakama/">サルにもわかる正規表現入門</a></li>
</ul>
カラーコードを判定するための正規表現を書きました。
2014-06-15T00:00:00.000Z
2022-11-28T13:39:59.000Z