1. ホーム
  2. Web プログラミング
  3. CSS/HTML

CSS可変幅オーバーフロー テキスト適応スクロールの説明

2022-01-19 08:28:13

ホバー時のポップアップボックスのヒント

テキストボックスにカーソルを置くと、全文が表示されるようにすることも可能ですが、最も簡単な方法は、textタグの下にtitle属性を追加し、必要な内容を入力することです。

<ul>
    <li title="Overflow Text 1 Overflow Text 2 Overflow Text 3 Overflow Text 4">Overflow Text 1 Overflow Text 2 Overflow Text 3 Overflow Text 4</li>
</ul>

もちろん、この方法はシンプルですが、少しユーザーエクスペリエンスに欠けるかもしれません。

今回は、テキストの長さが不確かで、コンテナの長さも不確かな場合に、任意の長さのテキストをホバーし、左から右にスクロールしてテキストの終わりまで行き、また最初の位置までスクロールして戻る、というような方法を簡単に説明します。

コンテナ固定幅、テキスト可変幅

ここで、コンテナの幅は固定で、各テキストの幅は固定でないと仮定してみましょう。

このようなものです。

<div class="wrap">
    <p title="My width is normal width">My width is normal width</p>
    <p class="scroll" title="My width is overflowing by a small amount">My width is overflowing by a small amount</p>
    <p class="scroll" title="My width is overflowing by a large margin">My width is overflowing by a large margin</p>
</div>

.wrap {
    position: relative;
    width: 150px;
    overflow: hidden;
}
 
p {
     white-space: nowrap;
}

実際のテキストの幅を取得するためにinline-blockを使用します。

alt;p>タグの幅は親要素の100%なので、そうなると以下のようにするのは難しいです。まずは実際のテキストの幅を取得する必要がありますが、ここではCSSで改良したinline-blockの機能でそれを実現します。

p {
 + display: inline-block;
    white-space: nowrap;
}

こうすることで、現在の <p> タグの実際の幅は、実際にはテキスト要素全体の幅になります。

Tips: ここではp要素を下にスクロールさせる必要があるため、display: inlineは使用していませんが、transformはインライン要素では使用できません。詳しくは仕様書をご覧ください:transformable要素

スクロールの距離を計算し、スクロールを行う

こうして、親要素の幅150pxとテキストの幅が揃いました。そうすると、スクロールさせる必要のある距離を求めるのは簡単です。

スクロールする距離S = はみ出したテキスト要素の幅 - 親要素の幅

このように、表現可能で現在の文字幅が可変な値を見つければよいのです。つまり、-transoformです。

変位にtransform: translate()を使用する場合、パーセント表現を使用すると、パーセントの基準となる要素は要素そのものなので、transform: translate(100%, 0) とすると、実際には要素自体の幅である右への距離を表現していることになります。

そして、アニメーションの中に埋め込まれた calc S --transform: translate(calc(-100% + 150px), 0) で、上のスクロールに必要な距離を非常に簡単に得ることができます。

p:hover {
    animation: move 1.5s infinite alternate linear;
}
 
@keyframes move {
    0% {
        transform: translate(0, 0);
    }
    100% {
        transform: translate(calc(-100% + 150px), 0);
    }
}

つまり、コンテナの幅を超えるテキストに対しては、簡単に上記のようなことができるのです。

可変幅テキストランナーによる前後スクロール -- 親コンテナ固定幅、子要素可変幅

親コンテナが固定幅でない

もちろん、まだ終わりではありません。

親コンテナの幅も固定でない場合、あるいはCalcの互換性の問題で上記の方法が使えない場合。その場合、現在の要素の幅と親コンテナの幅の両方をCSSの固定コードで移動させることになる。

たまたま、CSSは実際に上記のようなことをしているので、アニメーションのコードを適応してみましょう。

@keyframes move {
    0% {
        left: 0;
        transform: translate(0, 0);
    }
    100% {
        left: 100%;
        transform: translate(-100%, 0);
    }
}

  • transform: translate(-100%, 0) は、自分自身を幅の100%分だけ左に移動させることができます。
  • left: 100%は親コンテナをその幅の100%だけ右に移動させます。

left を margin-left に置き換えても同じことができ、パーセンテージを使った margin-left の移動も親要素の幅に基づきます。

これにより、親コンテナの幅とtext要素の幅に関係なく、オーバーフローテキストを適応的にスクロールさせることができます。

可変幅のテキストランナーが前後にスクロールする -- 親コンテナは可変幅、子要素は可変幅

いくつかの欠点

1. テキストの長さが親要素の幅を超えるかどうかがわからない

もちろん、上記の解決策は完全なものではありません。このテキストの長さがオーバーフローする場合、ホバーリング時のみスクロールしたい場合、これは純粋なCSSでは不可能です。

CSSで現在の要素の長さが親要素の長さより大きいかどうかを判断して、選択的にアニメーションさせることはできないのです。結局のところ、CSSはスタイルにのみ責任を持ち、動作には責任を持たないのです。ですから、実際には、JavaScriptで単純に判断し、クラスで制御する必要があるでしょう。

2. フリッカーのアニメーション化

親コンテナの幅が可変の場合、2つのプロパティを同時にアニメーションさせる必要があり、しかもシフト方向が逆なので、アニメーションが少しちらついた感じになります。これについては、特に良い解決策はまだ見つかっていません。

以上、CSSの不定幅オーバーフローテキスト適応スクロールについて詳しく解説しました。