
Android
イベント
マガジン
技術ブログ
はじめに はじめまして。株式会社タップルでサーバーサイドエンジニアをしている糸井一颯( Issa ) ...
はじめに 以前、Androidの開発者を確認するAndroid Developer Verificationという記事で、2026年に、Androidのアプリの提供方法に大きな変更が生じるというお話しをさせていただきました。 簡単にまとめますと、Androidにインストールするアプリには、Googleが定める開発者登録が義務付けられるというものでした。 昔からAndroidをご存じの方は、サイドローディングが可能という、その自由さを好まれてきた方もいらっしゃるかと思いますが、昨今のセキュリティ事情などを踏まえ、身元確認を行いインストールされるアプリの開発者の身元を特定することになりま
はじめに こんにちは、スタメンでプロダクトエンジニアをしている おしん ( @38Punkd ) です。 5月9日、ウインクあいちで開催された フロントエンドカンファレンス名古屋 2026 にLT枠で登壇させていただきました。 その発表内容をブログ形式でご紹介できればと思います。 WebViewの文字サイズ、固定されていませんか? この問題は、ネイティブとWebの境界に起因する「実装責務の曖昧さ」から生じがちです。 モバイルアプリ開発において、ユーザーのアクセシビリティへの配慮は不可欠です。特に、スマートフォンの設定で文字サイズを大きくしているユーザーにとって、アプリ内のテキストがその設定に追従するかどうかは、使いやすさに直結します。 私たちのアプリ TUNAG は、モバイルアプリではアプリネイティブとWebView(モバイルアプリでHTMLを表示できる機能)を併用しています。ネイティブUIはOSの文字サイズ設定に追従する一方で、アプリ内のWebViewだけが標準サイズのままでした。文字のリサイズが画面ごとに適用されたりされなかったりすると、ユーザーにとって読みにくいコンテンツになってしまうため、WebViewへの適用を本格的に開始しました。 本記事では、iOSとAndroidそれぞれのWebViewにおいて、OSの文字サイズ設定を適切に反映させるための具体的な実装方法と、その際の注意点について解説します。 文字サイズ設定は「特別対応」ではない 文字サイズ調整は、多くのユーザーが日常的に利用する標準機能です。ある調査によると、 モバイルユーザーの約33%が文字サイズ調整を有効化している というデータもあります *1 。iOSのDynamic Type *2 やAndroid 14以降の200%フォントスケーリング *3 など、OSもこの機能を重視しています。 結論としては、 ネイティブアプリ側のごくわずかな修正と、Web開発時のただ1点のポイントをおさえるだけ で、WebViewでもiOS, Android共に文字サイズ設定が反映されるようになります。 対応工数に対して UX改善のインパクトが大きい領域 であると言えそうです。 iOS WebView:JavaScript注入による動的なフォントサイズ反映 iOSのWebViewでDynamic Typeを反映させる最も柔軟で推奨される方法は、ネイティブ側でOSのフォントサイズを取得し、JavaScriptを介してWebViewに注入するアプローチです。 ① Swift:Dynamic Type 変更を検知してフォントサイズを JS で注入 NotificationCenter. default .addObserver( self , selector : #selector(dynamicTypeDidChange), name : UIContentSizeCategory.didChangeNotification , object : nil ) @objc private func dynamicTypeDidChange () { applyFontSize() } func webView (_ webView : WKWebView , didFinish navigation : WKNavigation! ) { applyFontSize() // ページロード完了時にも適用 } private func applyFontSize () { let size = UIFont.preferredFont(forTextStyle : .body).pointSize webView?.evaluateJavaScript( "document.documentElement.style.fontSize = ' \( size ) px'" , completionHandler : nil ) } UIContentSizeCategory.didChangeNotification を受信したら、Swift側でフォントサイズを取得し、 evaluateJavaScript でWebViewの :root 要素の font-size プロパティに直接書き込みます。この方式は リロードが不要で即時反映され、独自のスケールにも柔軟に対応できる 点が利点です。 ② CSS: font-size は rem 単位で指定 Swift側で :root の font-size を動的に書き換えるため、Webコンテンツ側では rem 単位でフォントサイズを指定することで、すべてのテキスト要素が連動してスケールするようになります。 : root { font-size : 17px ; /* フォールバック。Swift が evaluateJavaScript で上書きする */ } .title { font-size : 1.143rem ; } /* ✅ :root 基準でスケールする */ .description { font-size : 0.857rem ; } /* ✅ :root 基準でスケールする */ 参考:よりシンプルな代替案( -apple-system-body ) CSSに :root, body { font: -apple-system-body; } を指定し、Dynamic Typeの変更検知時に webView.reload() を呼ぶ方法もあります。この方法は手軽ですが、 WebViewのリロードが発生する 点と、 Apple提供のスケールに固定される 点がデメリットです。 Android WebView:「対応できている風」に注意 AndroidのWebViewでは、iOSとは異なる挙動と注意点があります。特に「文字サイズ設定に対応できているように見えるが、実は問題がある」ケースに注意が必要です。 見た目 実際に起きていること 文字が大きく見える Activity再生成によりWebViewが作り直される 全体が拡大される 文字だけでなく画像・余白もズームされる場合がある 設定変更後に戻る スクロール位置・入力中状態が失われる可能性がある android:configChanges に fontScale が含まれていない場合、OSのフォントスケール変更時にActivityが再生成され、WebView全体がズームされます。これは文字以外の要素も拡大し、レイアウト崩れや状態喪失の原因となります。 文字だけを適切に反映できているか を見極める必要があります。 AndroidはOS値をJSで橋渡しする Androidで文字サイズ設定をWebViewに適切に反映させるには、ネイティブ側でOSのフォントスケール値を取得し、JavaScriptを介してWebViewに伝えるアプローチが有効です。 ① AndroidManifest: fontScale を configChanges に追加 <activity android : configChanges = "fontScale|uiMode|density" ... /> AndroidManifest.xml の <activity> タグに android:configChanges="fontScale" を追加し、フォントスケール変更時のActivity再生成を防ぎます。 ② Kotlin:フォントスケール変化を検知して WebSettings.setTextZoom(int) で反映 // 起動時の初期化 applyFontScale(resources.configuration.fontScale) // フォントスケール変化を検知(iOS の didChangeNotification に相当) override fun onConfigurationChanged(newConfig: Configuration) { super .onConfigurationChanged(newConfig) applyFontScale(newConfig.fontScale) } private fun applyFontScale(fontScale: Float ) { // fontScale 1.0 → 100(標準), 2.0 → 200(200%) // px・em 問わず WebView 内のテキスト全体をスケールする webView.settings.textZoom = (fontScale * 100 ).roundToInt() } onConfigurationChanged で newConfig.fontScale を取得し、 WebSettings.setTextZoom(int) でWebViewのテキストズームレベルを設定します。 ③ CSS:テキストは単位を問わずスケールされる WebSettings.setTextZoom(int) はレンダリングエンジンレベルで適用されるため、HTML/JS の変更は不要です。 px 、 em 、 rem のいずれの単位で指定されたテキストもスケールされます。ただし、非テキスト要素はスケールされないため、Web側で柔軟な設計が必要です。 共通の考慮事項:拡大しても壊れないレイアウトにする OSの文字サイズ設定をWebViewに反映させるだけでなく、Webコンテンツ側で、文字が拡大されてもレイアウトが崩れないような柔軟な設計が求められます。 避けたい実装 推奨する実装 固定高さ 内容量に応じて伸びる高さ 1行前提 折り返し・複数行を許容 アイコンと文字の密結合 gap・flex-wrap・min-widthで逃がす 文字サイズ対応の本質は、値の反映だけでなく「拡大を許容するUI」を構築すること にあります。 まとめ 本記事では、iOSおよびAndroidのWebViewにおいて、OSの文字サイズ設定を適切に反映させるための具体的な実装方法と、その際の注意点について解説しました。 iOSでは、Swift側でDynamic Typeのフォントサイズを取得し、JavaScriptでWebViewの :root 要素の font-size を動的に書き換えるアプローチが最も柔軟です。これにより、リロードなしで即時反映が可能となります。Androidでは、 AndroidManifest で fontScale の変更を検知し、 WebSettings.setTextZoom(int) でWebView全体のテキストズームレベルを設定します。 そして、iOSとAndroidの両方でWebView内のテキストをOSの文字サイズ設定に追従させるための共通の鍵となるのが、 CSSでの rem 単位の活用 です。 デフォルトの文字サイズ 拡大した文字サイズ OSではJavaScriptによる :root 操作と連動させるために rem 指定が 必須 となります。一方で、Androidの setTextZoom は単位を問わず追従してくれます。つまり、Web側の実装をiOSに合わせて rem に統一しておけば、Android側でも一切の不都合なく自然に拡大縮小が行われ、両OSに矛盾なく対応できるのです。 スマートフォンのOS設定を尊重し、より多くのユーザーに読みやすいWebコンテンツを届けることは、ユーザーの満足度向上に繋がりやすく重要です。本記事が参考になりましたら幸いです。 サンプルリポジトリ 本記事で紹介した実装の詳細は、以下のサンプルリポジトリでご確認いただけます。 iOSアプリ : GitHub - iOS WebView Dynamic Type Sample Androidアプリ : GitHub - Android WebView Font Scale Sample herp.careers *1 : Ian Savchenko, “Designing for Accessibility: How Text Resizing Works in Different Web Browsers,” PayPal Technology Blog. https://medium.com/paypal-tech/designing-for-accessibility-how-text-resizing-works-in-different-web-browsers-bed9e424e071 *2 : Apple Developer Documentation, “Scaling fonts automatically.” https://developer.apple.com/documentation/uikit/scaling-fonts-automatically *3 : Android Developers, “Features and APIs Overview — Non-linear font scaling to 200%.” https://developer.android.com/about/versions/14/features





















