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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
nakamizu
October 29, 2026
Programming
60
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
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Kaigi on Rails 2026, Tokyo, Japan
marcoroth
2
350
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
1.5k
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
430
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
240
조합이폭발하는디자인시스템이걸눈으로도테스트하라고요
giljongyu
0
600
golang-bob.pdf
iwatsukayura
0
140
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
210
AI時代のTerminal環境を UNIX哲学で設計・運用する
yasunori0418
1
270
ChromeでローカルLLM
ryu1013
0
160
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1k
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
240
dotNET_vulnclicker_intro.pdf
deka_morita
0
150
Featured
See All Featured
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
350
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
950
Done Done
chrislema
187
17k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
ラッコキーワード サービス紹介資料
rakko
4
5.5M
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
540
Building the Perfect Custom Keyboard
takai
2
920
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