アプリケーションにおけるマーキー — その概要、作成方法と設定方法

著者: IT Sectr 公開日: 2026-07-25 読了時間: 9 分

マーキー(marquee)は、テキストが制限された領域内で自動的に水平スクロールする視覚効果であり、長い文字列をコンパクトなコンテナに表示できます。歴史的には、この用語は1990年代にウェブで人気のあったHTMLタグ <marquee> に由来します。現代のモバイル開発では、scrolling textはプレーヤー、ニュースティッカー、ステータスバーで使用されています。Apple Human Interface GuidelinesとGoogle Material Designによると、マーキーは省略記号による静的な切り捨てがUXを損なう限られたシナリオでのみ許容されます。

重要なポイント

  • マーキー — 制限されたコンテナ内での長いテキストの自動水平スクロール。
  • AndroidではTextViewの android:ellipsize="marquee" で実装されます。
  • iOSでは Core Animation またはSwiftUIのオフセットアニメーションで手動で行います。
  • ウェブでは <marquee> タグは 非推奨 です。代わりにtranslateXを使用したCSSアニメーションを使います。
  • アクセシビリティのためには prefers-reduced-motion のサポートが必須です。

マーキーとは?

マーキーは、テキストが固定領域内を水平に移動し、コンテナに収まらないすべてのコンテンツをユーザーが読めるように循環スクロールするUI効果です。テキストの一部を隠すellipsizeとは異なり、marqueeはテキスト全体を動的に表示します。

マーキーという用語は、NetscapeおよびInternet Explorerブラウザの初期バージョンで追加されたHTMLタグ <marquee> により定着しました。このタグはJavaScriptやCSSなしでスクロールテキストを作成できましたが、HTML標準の一部になることはありませんでした。最新のブラウザは後方互換性のためにサポートを続けていますが、その使用は推奨されていません。

モバイル開発では、マーキーはコンパクトなコンテナ内の長いラベルの問題を解決します:プレーヤーのトラック名、為替ティッカー、TV画面のニュースティッカーなどです。ただし、アニメーションのためにアクセシビリティに負荷をかけ、ユーザーを悩ませる可能性があるため、選択的に使用されます。

Nielsen Norman Groupの調査(2023年)によると、動くテキストは読書速度を15〜20%低下させ、認知的負荷を増加させます。静的な切り捨て(ellipsize)が本当に受け入れられない場合にのみマーキーを使用してください。

TextViewを使ったAndroidでのマーキー

Androidでは、マーキーは TextView の組み込みメカニズムにより、android:ellipsize="marquee" 属性を通じて実装されます。これはテキストを切り捨てずにスクロールをアニメーション化する唯一のellipsizeモードです。

マーキーを有効にするには、singleLine="true"(またはmaxLines="1")、ellipsize="marquee"、コード内でsetSelected(true)の3つの条件を満たす必要があります。setSelected()を呼び出さないとアニメーションは開始されません。

xml
<!-- XML layout -->
<TextView
    android:id="@+id/marquee_text"
    android:layout_width="150dp"
    android:layout_height="wrap_content"
    android:singleLine="true"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit="marquee_forever" />

// Kotlin: activate marquee
textView.setSelected(true)
textView.isSingleLine = true

marqueeRepeatLimit 属性はアニメーションの繰り返し回数を指定します:marquee_forever(無限)または具体的な数値です。デフォルトはmarquee_foreverです。テキストがコンテナの幅より短い場合、アニメーションは開始されず、TextViewは静的なテキストを表示します。

重要な特徴:setSelected(true) はTextViewがフォーカスを持つか選択モードの場合にのみ機能します。RecyclerViewでは、これが問題を引き起こす可能性があります—アニメーションは1つのアイテムに対してのみ開始されます。解決策は、isFocused()をオーバーライドして常にtrueを返すカスタムMarqueeTextViewを作成することです。

Android 9(API 28)以降、Googleはマーキーの動作を改善しました—アニメーションはよりスムーズになり、リストのスクロール時にフリーズしなくなりました。ただし、古いデバイスでは、特に高いピクセル密度でマーキーが震えることがあります。

iOSでのスクロールテキストの実装

iOSにはandroid:ellipsize="marquee"の組み込み相当機能はありません。マーキーは Core Animation またはSwiftUIアニメーションを使用して手動で実装されます。最も一般的なアプローチは、クリッピングコンテナと組み合わせてlayer.positionをアニメーション化することです。

UIKitでは、マーキーは3つの要素で構築されます:clipsToBounds = trueのUILabelコンテナ、テキスト自体、およびX軸に沿ってテキストを無限に繰り返し移動させ、autoreverses = falseで一行が一方向にスクロールしてジャンプして戻るCABasicAnimationです。

swift
func startMarquee(for label: UILabel) {
    label.clipsToBounds = true
    label.numberOfLines = 1

    let textWidth = (label.text as? NSString)?
        .size(withAttributes: [.font: label.font as any]).width ?? 0

    guard textWidth > label.bounds.width else { return }

    let animation = CABasicAnimation(keyPath: "position.x")
    animation.fromValue = label.layer.position.x + label.bounds.width / 2
    animation.toValue = label.layer.position.x - textWidth - label.bounds.width / 2
    animation.duration = CFTimeInterval(textWidth / 60)
    animation.repeatCount = .infinity
    animation.autoreverses = false
    label.layer.add(animation, forKey: "marquee")
}

duration = textWidth / 60の計算により、約60ピクセル/秒の速度が得られます—快適な読書ペースです。速度が120 px/sを超えるとテキストが読めなくなります。30 px/s未満だとアニメーションが鈍く見えます。特定のシナリオに合わせて速度を調整してください。

SwiftUIでは、マーキーはより簡単に実装されます—反復可能なアニメーションを持つoffset()修飾子と.animation(.linear(duration:).repeatForever(autoreverses: false))を使用します。SwiftUIはアニメーションのライフサイクルを自動的に管理しますが、テキストの幅を決定するためにGeometryReaderが必要です。

marqueeタグの代わりとなるCSSアニメーション

ウェブでは、非推奨の <marquee> タグは 推奨されていません が、ブラウザはサポートを続けています。マーキーの現代的な実装は、キーフレームとtransform: translateXを使用したCSSアニメーションです。

CSSアプローチの利点:速度、一時停止、アニメーションカーブの完全な制御、アクセシビリティのためのprefers-reduced-motionのサポート、意味論的に不適切なタグの不在。

css
.marquee {
    overflow: hidden;
    white-space: nowrap;
    width: 300px;
}
.marquee-content {
    display: inline-block;
    animation: marquee 10s linear infinite;
}
@keyframes marquee {
    0%   { transform: translateX(0); }
    100% { transform: translateX(-100%); }
}

/* Pause on hover */
.marquee-content:hover {
    animation-play-state: paused;
}

重要なトリック:コンテンツに display: inline-block を指定すると、要素の幅がテキストの幅と等しくなり、translateX(-100%) がその幅だけ左に正確に移動します。コンテンツがdisplay: blockの場合、translateX(-100%) はテキストの幅ではなくコンテナの幅と等しくなり、アニメーションが壊れます。

アクセシビリティのために、@media (prefers-reduced-motion: reduce) { .marquee-content { animation: none; } } を追加してください—前庭障害を持つユーザーはスクロール機能付きの静的テキストを表示します。

使用するタイミングと避けるべきタイミング

マーキーは、ユーザーが自分でコンテナを拡張できず、完全なテキストが極めて重要なシナリオで 正当化されます:ロック画面のプレーヤーでの現在のトラック、TVパネルのニュースティッカー、ライドヘイリングアプリのマーキー(注文ステータス)。

マーキーはテーブル、リスト、フォーム、ダイアログでは 使用すべきではありません—ユーザーがインターフェースと積極的にやり取りするすべての場所です。アニメーションは目的から気をそらし、要素の検索時間を増やし、不快感を生み出します。WebAIM(2024年)によると、前庭障害を持つユーザーの3人に1人がアニメーションテキストを見たときに不快感を報告しています。

経験則:テキストを短縮したり次の行に折り返したりできるなら、そうしてください。マーキーは最後の手段であり、長いラベルのための普遍的な解決策ではありません。

アクセシビリティ:アニメーションと動きの軽減

マーキーはアクセシビリティの観点から最も 問題のある UIアニメーションの1つです。動くテキストは、前庭障害を持つ人々にめまい、吐き気、見当識障害を引き起こす可能性があります。WCAG 2.2によると、5秒以上続くアニメーションには一時停止または無効化のメカニズムが必要です。

iOSでは、UIAccessibility.isReduceMotionEnabled プロパティを使用してシステム設定を確認します。reduceMotionが有効な場合は、アニメーションを開始せず、ellipsize付きの静的テキストを表示します。

Androidでは、Settings.Global.ANIMATOR_DURATION_SCALE を介してシステムアニメーションを確認します。グローバルアニメーションが無効(duration scale = 0)の場合、マーキーを有効にするべきではありません。

ウェブでは、prefers-reduced-motion メディア機能を使用します:@media (prefers-reduced-motion: reduce) { .marquee-content { animation: none; } }。これはすべての最新ブラウザでサポートされている標準のCSS機能です。DevToolsで確認してください:prefers-reduced-motionのエミュレーションを有効にして、アニメーションがオフになることを確認します。

よくある質問

MarqueeとEllipsizeの違いは何ですか?

Ellipsize はテキストを切り捨てて省略記号を追加し、コンテンツの一部を隠します。Marqueeはテキスト全体をスクロールしますが、動的です。選択は優先順位によります:すべてを表示する(marquee)か静的表示を維持する(ellipsize)か。

Androidでマーキーの速度を速くしたり遅くしたりするには?

組み込みの android:ellipsize="marquee" では速度を変更できません—システムのScrollSpeedによって決まります。カスタム速度の場合は、AnimationまたはValueAnimatorを手動で使用します。

RecyclerViewでマーキーが機能しないのはなぜですか?

ビューの再利用のため、setSelected(true) がリセットされます。解決策:isFocused()をオーバーライドして常にtrueを返すカスタムMarqueeTextViewを作成するか、Adapter.onViewAttachedToWindow()でカスタムアニメーションを使用します。

垂直マーキーは作れますか?

はい、translateXの代わりに translateY を使用します。垂直マーキーはクレジットや垂直フィードのニュースティッカーに使用されます。原理は同じですが、アニメーションの軸が変わります。

フォーカス時にマーキーを停止するには?

CSSの場合::hover { animation-play-state: paused; }。Androidの場合:OnFocusChangeListenerでフォーカスを追跡し、setSelected(false)をリセットします。iOSの場合:layer.removeAnimation(forKey:)でアニメーションを削除します。

まとめ

  • マーキー — アニメーションによりコンテンツ全体を表示するテキストの水平スクロール。
  • Androidでは、組み込みの android:ellipsize="marquee" にはsetSelected(true)とsingleLine="true"が必要です。
  • iOSでは、CABasicAnimation を使用してposition.xキーパスで実装します。
  • ウェブでは、<marquee> タグは非推奨です。translateXを使用した CSS @keyframes を使用します。
  • マーキーはellipsizeが受け入れられない場合に のみ 使用します—プレーヤー、ティッカー、ステータスバーなど。
  • すべてのプラットフォームで prefers-reduced-motion のためにアニメーションを必ず無効にします。
  • アニメーション速度:約60 px/s — 読書に快適、120 px/s以上 — 読めません。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください