Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
そのデザイントークン、Flutterでも同じ見た目になりますか?
Search
nakamizu
October 29, 2026
Programming
58
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
そのデザイントークン、Flutterでも同じ見た目になりますか?
FlutterKaigi 2026 Day1 の登壇資料です。
Webとアプリで同じデザイントークンを使っているのに、文字間だけ見た目がそろわなかった話と、その解決策を紹介します。
nakamizu
October 29, 2026
Other Decks in Programming
See All in Programming
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
380
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
AI-Powered Domain-Driven Design
ziobrando
0
330
AIがコードを書いてくれる時代、我々は何を確かめるのか
yosuke_furukawa
PRO
12
4.7k
Jetpack Compose Mechanisms
skydoves
3
880
Kotlinの15年とServer-Side Kotlin
n_takehata
1
170
Web Framework Benchmark Battle 2026, Any%
a_matsuda
3
3k
Lambda durable functionsでHuman in the Loopを楽に…楽に……
har1101
2
200
AI時代のTerminal環境を UNIX哲学で設計・運用する
yasunori0418
1
270
AI時代のIaC入門 〜なぜインフラをコードで管理したいのか?〜 / Introduction to IaC in the AI Era
akihisaikeda
4
690
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
5
850
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Kaigi on Rails 2026, Tokyo, Japan
marcoroth
2
350
Featured
See All Featured
Technical Leadership for Architectural Decision Making
baasie
3
610
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
77k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.7k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
510
My Coaching Mixtape
mlcsv
0
360
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
540
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
350
Deep Space Network (abreviated)
tonyrice
0
380
StorybookのUI Testing Handbookを読んだ
zakiyama
31
7k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
470
Joys of Absence: A Defence of Solitary Play
codingconduct
1
550
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Transcript
そのデザイントークン、 Flutterでも同じ見た目になりますか? FlutterKaigi 2026 Day1 株式会社アサイン 中水優輝 この発表のスライドはこちら 01
自己紹介 中水 優輝 Yuki Nakamizu 株式会社アサイン / Webフロントエンジニア デザインシステムの構築を担当 Webフロントエンド歴
7年目 2ヶ月目 Flutter歴 X この発表のスライドはこちら 02
今日の話 Webとアプリで 同じデザイントークンを使っているのに、 見た目がそろわないところがあった話 ©ASSIGN Inc. All Rights Reserved. 03
WebとFlutterへ配布するデザイントークン 背景 › 課題 › 解決策 › 結果 › まとめ
WebとFlutterのアプリで見た目をそろえるため、同じデザイントークンを配布している デザインシステム アプリ Web向けのスタイルとlint import Flutter向けのスタイルとlint import デザイントークン ©ASSIGN Inc. All Rights Reserved. 04
デザイントークンとは 背景 › 課題 › 解決策 › 結果 › まとめ
デザイントークンは、UIの細かい見た目を決める、デザインの最小単位 デザイントークン Aa 部品 色 タイポグラフィ 余白 角丸 影 グラデーション 線 アニメーション ©ASSIGN Inc. All Rights Reserved. 画面 05
トークンの種類 背景 › 課題 › 解決策 › 結果 › まとめ
配布しているデザイントークンは、色、タイポグラフィ、余白、角丸の4種類 色 ©ASSIGN Inc. All Rights Reserved. Aa タイポグラフィ 余白 角丸 06
トークンの種類 背景 › 課題 › 解決策 › 結果 › まとめ
色、余白、角丸と違い、タイポグラフィは見た目がそろわなかった 色 ©ASSIGN Inc. All Rights Reserved. Aa タイポグラフィ 余白 角丸 07
Webとアプリの見比べ 背景 › 課題 › 解決策 › 結果 › まとめ
同じデザイントークンを使っても、Webとアプリでテキストの詰まり方が違う Web アプリ https://xxx.jp ©ASSIGN Inc. All Rights Reserved. 08
文字間の書き方 背景 › 課題 › 解決策 › 結果 › まとめ
ほかの3つと違い、文字間はFlutterでは比率で指定できない フォントサイズ font-size: 20px; fontSize: 20 太さ font-weight: 600; fontWeight: FontWeight.w600 行間 line-height: 1.5; height: 1.5 文字間 letter-spacing: 0.05em; letterSpacing: ? ©ASSIGN Inc. All Rights Reserved. 09
Flutterの文字間 背景 › 課題 › 解決策 › 結果 › まとめ
Flutterの文字間は、ピクセルの値でしか指定できない /// The amount of space (in logical pixels) to add between each letter. final double? letterSpacing; 出典:Flutter SDK 3.38.2 packages/flutter/lib/src/painting/text_style.dart ©ASSIGN Inc. All Rights Reserved. 10
比率をそのまま渡した場合 背景 › 課題 › 解決策 › 結果 › まとめ
フォントサイズの5%のつもりで0.05を渡しても、文字間は0.05ピクセルになる letterSpacing: 1.0 letterSpacing: 0.05 ©ASSIGN Inc. All Rights Reserved. 11
Webとの違い 背景 › 課題 › 解決策 › 結果 › まとめ
比率で書けないので、フォントサイズごとに長さへ直す必要がある 1つ書けば、ブラウザが計算する CSS letter-spacing: 0.05em; ©ASSIGN Inc. All Rights Reserved. サイズごとに、自分で計算して書く Dart TextStyle(fontSize: 16, letterSpacing: 0.8) TextStyle(fontSize: 20, letterSpacing: 1.0) 12
換算の関数 背景 › 課題 › 解決策 › 結果 › まとめ
トークンは比率のままWebと共有し、Flutterへ渡す直前にピクセルへ換算する Web letter-spacing: 0.05em; デザイントークン 0.05(フォントサイズの5%) Flutterへ渡す直前に換算 換算の関数 文字間 = 比率 × フォントサイズ static double px(double em, double fontSize) => em * fontSize; Flutter letterSpacing: 1.0 フォントサイズ20pxのとき ©ASSIGN Inc. All Rights Reserved. 13
テキストスタイルの関数 背景 › 課題 › 解決策 › 結果 › まとめ
テキストスタイルごとに関数を用意し、その中でフォントサイズと文字間を一緒に決める abstract final class DsTextStyles { static TextStyle display20W6({…}) { … } static TextStyle display24W6({…}) { … } … static TextStyle textNormal14W4({…}) { … } static TextStyle textNormal16W6({…}) { … } … } ©ASSIGN Inc. All Rights Reserved. 14
文字間が決まる流れ 背景 › 課題 › 解決策 › 結果 › まとめ
20と0.05が関数に渡り、計算されて、文字間は1ピクセルになる 1. フォントサイズが20の関数 static TextStyle display20W6({double Function(double value)? scale}) { final fontSize = (scale ?? _spScale)(DsFontSize.s20); return TextStyle( fontSize: fontSize, fontWeight: DsFontWeight.semibold, letterSpacing: DsLetterSpacing.px(DsLetterSpacing.normalEm, fontSize), height: DsLineHeight.normal, … ); } ©ASSIGN Inc. All Rights Reserved. 15
文字間が決まる流れ 背景 › 課題 › 解決策 › 結果 › まとめ
20と0.05が関数に渡り、計算されて、文字間は1ピクセルになる 2. fontSizeに20、normalEmに0.05が入る static TextStyle display20W6({double Function(double value)? scale}) { final fontSize = (scale ?? _spScale)(DsFontSize.s20); return TextStyle( fontSize: 20, fontWeight: DsFontWeight.semibold, letterSpacing: DsLetterSpacing.px(0.05, 20), height: DsLineHeight.normal, … ); } ©ASSIGN Inc. All Rights Reserved. 16
文字間が決まる流れ 背景 › 課題 › 解決策 › 結果 › まとめ
20と0.05が関数に渡り、計算されて、文字間は1ピクセルになる 3. 関数で計算される static TextStyle display20W6({double Function(double value)? scale}) { final fontSize = (scale ?? _spScale)(DsFontSize.s20); return TextStyle( fontSize: 20, fontWeight: DsFontWeight.semibold, letterSpacing: 1.0, height: DsLineHeight.normal, … ); } ©ASSIGN Inc. All Rights Reserved. 17
Lintルール 背景 › 課題 › 解決策 › 結果 › まとめ
TextStyleにフォントサイズや文字間を数字で書くと、Lintルールが警告する name_label.dart return const Text( '私の名前は中水優輝です', style: TextStyle(fontSize: 20, letterSpacing: 0.05), ); ターミナル $ dart run custom_lint lib/name_label.dart:10:34 • Typography値を直書きしないでください。Typographyトークンを使用してください。 • avoid_raw_typography • WARNING lib/name_label.dart:10:53 • Typography値を直書きしないでください。Typographyトークンを使用してください。 • avoid_raw_typography • WARNING ©ASSIGN Inc. All Rights Reserved. 18
Webとアプリの見比べ 背景 › 課題 › 解決策 › 結果 › まとめ
Webとアプリで、同じテキストスタイルを選ぶだけで文字の見た目を統一できた Web 記事のタイトル https://xxx.jp ©ASSIGN Inc. All Rights Reserved. アプリ style: DsTextStyles.textNormal16W6(), 19
Webとアプリの見比べ 背景 › 課題 › 解決策 › 結果 › まとめ
Webとアプリで、同じテキストスタイルを選ぶだけで文字の見た目を統一できた Web 読了の目安 https://xxx.jp ©ASSIGN Inc. All Rights Reserved. アプリ style: DsTextStyles.textNormal14W4(), 20
まとめ 背景 › 課題 › 解決策 › 結果 › まとめ
トークンでは意味を共有し、Flutter向けの変換はデザインシステムに集約する 共有するのは意味 デザイントークン 意味:フォントサイズの5% ©ASSIGN Inc. All Rights Reserved. 変換はここに集約 デザインシステム 比率 × フォントサイズで換算 Lintで換算の漏れを防ぐ Web 0.05em のまま書ける Flutter ピクセルで受け取る 21
文字間以外の違い 背景 › 課題 › 解決策 › 結果 › まとめ
文字間のほかにも、Webと違うところがあった 項目 カラーコード #FF9000CC 透明度が最後 Color(0xCCFF9000) 余白 padding: 16px; Padding(padding: …, child: Text(…)) 影のぼかし box-shadow: 0 0 10px BoxShadow(blurRadius: 10) ©ASSIGN Inc. All Rights Reserved. 要素自身に書く ぼかしの標準偏差 5 透明度が最初 Textには余白の引数がなく、外から包む ぼかしの標準偏差 約6.27 22
おわりに 背景 › 課題 › 解決策 › 結果 › まとめ
Webとの違いを楽しみながら、 これからもFlutterを学習していく ©ASSIGN Inc. All Rights Reserved. 23