切り取られたテキスト

This page is not available in the language you requested. You have been redirected to the English version of the page.
Link to this page copied to clipboard

静的テキストは、現在の状態やサイズ変更されても、表示内容が切り取られてはならない。

Not for use with personal data

WCAG 2.0 - 1.4.4 AA Impact - Serious

求めるポイント

静的テキスト要素の表示内容は、デフォルトの文字サイズでも、より大きなダイナミックタイプサイズでも切り取られてはならない。

失敗例 ❌

iOS app screen showing a heading and paragraph text clipped in a fixed-height container, with content cut off on the right side of the screen when Dynamic Type size is increased

固定された高さの制約がテキストコンテナの成長を防ぎ、内容に合わない

ユーザーがダイナミックタイプサイズを大きくすると、リサイズされたテキストがコンテナ境界で切り取られる

テキストは省略記号やスクロールバー、アクセス方法の表示もないまま切り取られる

成功例 ✅

iOS app screen showing a heading and paragraph text in a flexible-height container, text wraps across multiple lines and no content is clipped

柔軟な高さにより、テキストが複数行にわたって折り返されるとコンテナが垂直に成長する

どのダイナミックタイプサイズでも内容は切り取られない

大きな文字サイズに依存するユーザーもすべての情報を画面でアクセスできる

一目で分かる

  • このルールはユーザーに大きな影響を与える
  • このルールはiOS 17.0以降を必要とし、開発者が調整可能な表示された静的テキスト要素で実行される
  • 静的テキストは、現在の状態やサイズ変更されても、表示内容が切り取られてはならない
  • テキストを折り返したり成長させるよう修正:
    • numberOfLines = 0(UIKit)を設定する、または
    • .clipped()または.lineLimit()(SwiftUI)を削除する

ユーザーへの影響

視覚障害、認知障害のあるユーザーや、ダイナミックタイプでより大きな文字サイズを使用するユーザーは、クリップされた情報にアクセスできない可能性があります。WCAG 1.4.4(テキストのリサイズ)は、ユーザーがテキストを拡大してもテキストコンテンツが表示および使用可能であることを要求しています。このルールは、すでにクリップされているコンテンツや、ユーザーが文字サイズ設定を大きくするとクリップされる可能性のあるコンテンツを特定するのに役立ちます。

切り取られたテキストの問題を確認

  1. iOS 設定アクセシビリティを見つける
  2. 表示とテキストサイズを選択する
  3. 大きな文字パネルで最高のアクセシビリティテキストサイズを選択するように切り替える
  4. 画面上の変化を観察する:
    • アクセス不可能: コンテンツがこのビューによってクリップされる
    • アクセス可能: コンテンツが折り返される、垂直に成長する、またはスクロールしてアクセスできる

問題を解決

  • 開発者調整可能なテキストコンテナが、サポートしたい最大のダイナミックタイプサイズでも、完全なコンテンツを表示できる十分な幅と高さを持っていることを確認する
  • テキストが折り返されたり垂直に成長することを可能にするオートレイアウトの制約を使用する
  • テキストにnumberOfLinesプロパティをnumberOfLines = 0に設定する
  • スクロール可能なコンテンツに対しては、長いテキストが切り捨てられることなく表示にスクロールできるよう、スクロールビュー自体が正しくサイズされていることを確認する

UIKit

UIKitでこの問題を解決するには、通常、テキスト修正とレイアウト修正の両方が必要です。numberOfLinesを0に設定することでラベルを折り返すことができますが、ラベルやそのコンテナに固定された高さの制約があると、折り返されたテキストが切り取られてしまいます。コンテナが実際に成長できるように、可変の高さ制約greaterThanOrEqualToConstantを使用してください。

  • UILabel上にnumberOfLines = 0を設定して、複数行の折り返しを可能にする(テキスト修正)

    label.numberOfLines = 0
  • コンテナが折り返されたテキストに合わせて成長できるように、固定の高さのAuto Layout制約を>=に置き換えます

    label.heightAnchor.constraint(greaterThanOrEqualToConstant: minHeight).isActive = true

SwiftUI

SwiftUIのレイアウトシステムは、要素をその内容に合わせて自動的にサイズ変更します。固定されたframeclipped()プロパティを使用しないでください。.fixedSizeminHeightプロパティは、親要素がまだ独自のサイズ制約をテキストに課しているエッジケースでのみ必要です。

  • .clipped()プロパティや固定サイズのフレームを使用することが、テキストがクリップされる主な原因です。これらの制約を削除することで通常は解決します。

    // before
    Text("Long content that needs to wrap")
        .truncationMode(.tail)
        .clipped()
        .frame(width: 50, height: 20)
    // after
    Text("Long content that needs to wrap")
  • .lineLimit(1)を削除するか、nilに設定して、テキストを折り返すことをサポートする修正として

    Text("Your text here")
        .lineLimit(nil)
  • 親ビューがテキストサイズを制約している場合、.fixedSize(horizontal: false, vertical: true)を使用して垂直方向に拡張させます

    Text("Long content that needs to wrap")
        .fixedSize(horizontal: false, vertical: true)
  • オプションとして、minHeightをフレームに設定して、コンテンツと一緒に成長できるようにします

    Text("Content").frame(minHeight: minHeight)
  • ViewThatFits(iOS 16+)を使用して、より大きなサイズで配置を切り替えるアダプティブレイアウトを作成し、クリッピングを事前に防ぎます

    ViewThatFits {
        HStack { Text("Label"); Text("Value") }   // compact — fits on one row
        VStack { Text("Label"); Text("Value") }   // falls back to stacked if needed
    }

React Native

React Nativeでこの問題を防ぐためには、ビューが柔軟な高さを持つことを確認します。次のいずれかの方法を使用できます。

  • 高さを設定しないこと - コンテナはコンテンツに合わせて自動的にサイズを調整します。

    <View style={{ padding: 8 }}>
      <Text>{text}</Text>
    </View>
  • heightの代わりにminHeightプロパティを使用します。これにより短いコンテンツの基準が設定されますが、テキストが多い場合に容器が高さを増すことができます。

    <View style={{ minHeight: 30, padding: 8 }}>
      <Text>{text}</Text>
    </View>
  • コンテンツに合わせて成長し、自然なサイズを下回ることのないフレックスレイアウトを使用します。

    <View style={{ flexGrow: 1, flexShrink: 0, padding: 8 }}>
      <Text>{text}</Text>
    </View>
  • 固定の高さの代わりにパディングを使用する - テキストの本来のサイズとパディングの量がコンテナの高さを決定します。

    <View style={{ padding: 16 }}>
      <Text>{text}</Text>
    </View>
  • numberOfLines={0}を設定して、テキストが任意の行数に折り返せるようにし、垂直スペースを制御するために明示的なlineHeightと組み合わせます。

    <View style={{ padding: 8 }}>
      <Text numberOfLines={0} style={{ lineHeight: 30 }}>{text}</Text>
    </View>

Flutter

Flutterでこの問題を解決するには、通常、テキスト修正とレイアウト修正の両方が必要です。Textウィジェットはデフォルトで折り返しますが、固定高さの親や非柔軟なRow子があると、折り返されたテキストがクリップされるかもしれません。コンテナがその内容に合わせてサイズを調整できるようにし、Dynamic Typeがフォントをスケールできるようにシステムテキストスケーラーを尊重してください。

  • maxLinesを未設定のままにしておき、既定の設定であるsoftWrap: trueを維持しながら、Textを複数行に渡って折り返すことを許可します

    Text(
      longString,
      softWrap: true,
    )
  • テキストを包んでいるコンテナにパディングを使用して、ボックスがコンテンツとともに成長するようにします

    Container(
      padding: const EdgeInsets.all(8),
      child: Text(longString),
    )
  • Row内にある場合、TextExpandedまたはFlexibleでラップして、フォントがスケールするにつれて複数行に折り返すことができるようにします

    Row(
      children: [
        const Icon(Icons.info),
        Expanded(child: Text(longString)),
      ],
    )
  • 画面をスクロール可能にして、拡大されたテキストがビューポートを超えたときにもアクセスしやすいようにします

    SingleChildScrollView(       
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Text(longString),
      ),
    )

このルールを無視してもよいでしょうか?

クリップされたテキストはユーザーにとって重大な影響です。この問題をほぼすべてのケースで改善することをお勧めします。クリップされたテキストは単に読めないものであり、大きなDynamic Typeサイズに依存するユーザーにとって同等の回避策は存在しません。

まれなケースとして、クリップされた要素が装飾的または冗長である場合、結果を無視することを検討するかもしれません。たとえば、近くの他の要素や画像のアクセシビリティラベルで十分に伝えられている短いラベルなどです。ルールの無視について詳しく学びましょう。

リソース

Deque University コースページ

注: Deque University リソースへのフルアクセスにはサブスクリプションが必要です。

その他のリソース