CSSだけで作る、文字が流れるお知らせ(マーキー)|コピペで使える5種類と、止めるボタンの付け方

文字が流れるお知らせをCSSだけで コピペで使える5種類と、使う・使わないの判断

「臨時休業のお知らせ」や「新メニュー始めました」が、細い帯の中を右から左へ流れていく。このお知らせの流れる帯(マーキー)は、同じ文を2回並べて、CSSのアニメーションで横に動かすだけで作れます。JavaScriptは使いません。

使いどころ

流れていても読まなくて困らない「ついで」の情報か、飾りの帯に使う。休業日や料金の変更など、全員に必ず読んでほしいことは、流さずに止めて書く。

使うのは、動きを決める @keyframes と animation、横に動かす translateX()、そして止めるための animation-play-state です。

トミー

連載「WEBの技術」の10回目です。
1回目のローディングと同じ「最初から動き続ける」部品ですが、今回は文字を読ませるものなので、配慮の話が少し多めです。

完成見本:流れるお知らせ5種類

下の5つは、ページを開いた時点から流れ続けています。マウスを乗せると止まり、離すと続きから流れます。5番目は「流れを止める」にチェックを入れると止まります。

お知らせ
10月20日(火)は臨時休業です秋の新メニューを始めましたご予約はお電話でも受け付けています
NEWS TICKER1. お知らせバー
WEBDESIGNSNSAIMARKETING
BIG TEXT2. 大きな文字の帯
010203040506
CARDS3. 写真やカードが流れる
#カフェ#ランチ#テイクアウト#焼き菓子#駅から3分
#ギフト#季節の限定#予約できます#Wi-Fiあり#ペット可
TWO WAY4. 2段で逆向きに流れる
10月20日(火)は臨時休業です秋の新メニューを始めましたご予約はお電話でも受け付けています
WITH PAUSE5. 止めるボタン付き

※ 見本のお知らせの内容は、架空のお店のものです。

※ スマホやパソコンで「動きを減らす」設定をオンにしている方には、流さずに、全部の文を折り返して表示しています。理由は後半の「見る人への配慮」で説明します。

コピペ用のコード

見本ごとに、HTMLとCSSを並べました。HTMLは流したい場所に、CSSはサイトのCSSファイルや、WordPressならテーマの「追加CSS」などに入れます。お知らせの文は書きかえてください。

CSSの前半にある .kd-mq から始まる部分は、5種類に共通する指定です。同じページで何種類か使うときは、1回だけ入れれば足ります。クラス名の頭の kd-mq- は、サイトのほかのデザインと名前がぶつからないようにするための目印です。

1. お知らせバー

左に「お知らせ」の札を置き、右側だけ文字が流れる形です。ページの上の細い帯として置くことが多い、いちばん基本の形です。

お知らせ
10月20日(火)は臨時休業です秋の新メニューを始めましたご予約はお電話でも受け付けています
再生中(マウスを乗せると止まる)
HTML
<div class="kd-mq-box kd-mq-news">
  <span class="kd-mq-label">お知らせ</span>
  <div class="kd-mq">
    <div class="kd-mq-track">
      <div class="kd-mq-group">
        <span class="kd-mq-item">10月20日(火)は臨時休業です</span>
        <span class="kd-mq-item">秋の新メニューを始めました</span>
        <span class="kd-mq-item">ご予約はお電話でも受け付けています</span>
      </div>
      <div class="kd-mq-group" aria-hidden="true">
        <span class="kd-mq-item">10月20日(火)は臨時休業です</span>
        <span class="kd-mq-item">秋の新メニューを始めました</span>
        <span class="kd-mq-item">ご予約はお電話でも受け付けています</span>
      </div>
    </div>
  </div>
</div>
CSS
/* 5種類に共通:流れる帯 */
.kd-mq-box {
  color: #0F172A;
}
/* 見える窓。はみ出した部分は隠す */
.kd-mq {
  overflow: hidden;
}
/* 流れる中身。同じ並びを2回くり返し、半分の長さだけ左へ動かすと、つなぎ目なくループする */
.kd-mq-track {
  display: flex;
  width: max-content;
  animation: kd-mq-flow 24s linear infinite;
}
.kd-mq-group {
  display: flex;
  flex-shrink: 0;
}
.kd-mq-item {
  flex-shrink: 0;
  padding-right: 40px;
  white-space: nowrap;
}
@keyframes kd-mq-flow {
  to {
    transform: translateX(-50%);
  }
}
/* マウスを乗せたとき・キーボードで中に入ったときは止める */
.kd-mq-box:hover .kd-mq-track,
.kd-mq-box:focus-within .kd-mq-track {
  animation-play-state: paused;
}
/* 「流れを止める」ボタン(チェックボックス)。チェックが入ったら止める */
.kd-mq-stop {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  padding: 4px 12px;
  border: 1px solid #9CC3DA;
  border-radius: 999px;
  font-size: 0.85em;
  cursor: pointer;
}
.kd-mq-stop input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: #0369A1;
}
.kd-mq-box:has(.kd-mq-stop input:checked) .kd-mq-track {
  animation-play-state: paused;
}
/* 動きを減らす設定の人には、流さずに折り返して全部見せる */
@media (prefers-reduced-motion: reduce) {
  .kd-mq-track {
    width: auto;
    animation: none;
  }
  .kd-mq-group {
    flex-wrap: wrap;
    flex-shrink: 1;
    gap: 8px 24px;
  }
  .kd-mq-item {
    flex-shrink: 1;
    padding-right: 0;
    white-space: normal;
  }
  .kd-mq-group[aria-hidden="true"],
  .kd-mq-stop {
    display: none;
  }
}
.kd-mq-news {
  display: flex;
  align-items: center;
  overflow: hidden;
  border: 1px solid #D8E6F0;
  border-radius: 12px;
  background: #F2F8FC;
}
.kd-mq-news .kd-mq-label {
  flex-shrink: 0;
  align-self: stretch;
  display: flex;
  align-items: center;
  padding: 8px 14px;
  background: #0369A1;
  color: #FFFFFF;
  font-weight: 700;
}
.kd-mq-news .kd-mq {
  flex: 1;
  min-width: 0;
  padding: 8px 0 8px 14px;
}

2. 大きな文字の帯

大きな英字を、帯のようにゆっくり流します。お知らせというより、ページの区切りに置く飾りです。1つおきに色を変えると、動いていても単語の切れ目が分かります。

WEBDESIGNSNSAIMARKETING
再生中(マウスを乗せると止まる)
HTML
<div class="kd-mq-box kd-mq-big">
  <div class="kd-mq">
    <div class="kd-mq-track">
      <div class="kd-mq-group">
        <span class="kd-mq-item">WEB</span>
        <span class="kd-mq-item">DESIGN</span>
        <span class="kd-mq-item">SNS</span>
        <span class="kd-mq-item">AI</span>
        <span class="kd-mq-item">MARKETING</span>
      </div>
      <div class="kd-mq-group" aria-hidden="true">
        <span class="kd-mq-item">WEB</span>
        <span class="kd-mq-item">DESIGN</span>
        <span class="kd-mq-item">SNS</span>
        <span class="kd-mq-item">AI</span>
        <span class="kd-mq-item">MARKETING</span>
      </div>
    </div>
  </div>
</div>
CSS
/* 5種類に共通:流れる帯 */
.kd-mq-box {
  color: #0F172A;
}
/* 見える窓。はみ出した部分は隠す */
.kd-mq {
  overflow: hidden;
}
/* 流れる中身。同じ並びを2回くり返し、半分の長さだけ左へ動かすと、つなぎ目なくループする */
.kd-mq-track {
  display: flex;
  width: max-content;
  animation: kd-mq-flow 24s linear infinite;
}
.kd-mq-group {
  display: flex;
  flex-shrink: 0;
}
.kd-mq-item {
  flex-shrink: 0;
  padding-right: 40px;
  white-space: nowrap;
}
@keyframes kd-mq-flow {
  to {
    transform: translateX(-50%);
  }
}
/* マウスを乗せたとき・キーボードで中に入ったときは止める */
.kd-mq-box:hover .kd-mq-track,
.kd-mq-box:focus-within .kd-mq-track {
  animation-play-state: paused;
}
/* 「流れを止める」ボタン(チェックボックス)。チェックが入ったら止める */
.kd-mq-stop {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  padding: 4px 12px;
  border: 1px solid #9CC3DA;
  border-radius: 999px;
  font-size: 0.85em;
  cursor: pointer;
}
.kd-mq-stop input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: #0369A1;
}
.kd-mq-box:has(.kd-mq-stop input:checked) .kd-mq-track {
  animation-play-state: paused;
}
/* 動きを減らす設定の人には、流さずに折り返して全部見せる */
@media (prefers-reduced-motion: reduce) {
  .kd-mq-track {
    width: auto;
    animation: none;
  }
  .kd-mq-group {
    flex-wrap: wrap;
    flex-shrink: 1;
    gap: 8px 24px;
  }
  .kd-mq-item {
    flex-shrink: 1;
    padding-right: 0;
    white-space: normal;
  }
  .kd-mq-group[aria-hidden="true"],
  .kd-mq-stop {
    display: none;
  }
}
.kd-mq-big .kd-mq {
  padding: 10px 0;
  border-top: 2px solid #0F172A;
  border-bottom: 2px solid #0F172A;
}
.kd-mq-big .kd-mq-item {
  font-size: 2em;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: 0.04em;
}
.kd-mq-big .kd-mq-item:nth-child(even) {
  color: #0284C7;
}
.kd-mq-big .kd-mq-track {
  animation-duration: 18s;
}

3. 写真やカードが流れる

写真や実績のカードを横に流す形です。見本は色の四角ですが、中に <img> を入れれば、写真がゆっくり流れるギャラリーになります。

010203040506
再生中(マウスを乗せると止まる)
HTML
<div class="kd-mq-box kd-mq-cards">
  <div class="kd-mq">
    <div class="kd-mq-track">
      <div class="kd-mq-group">
        <span class="kd-mq-item">01</span>
        <span class="kd-mq-item">02</span>
        <span class="kd-mq-item">03</span>
        <span class="kd-mq-item">04</span>
        <span class="kd-mq-item">05</span>
        <span class="kd-mq-item">06</span>
      </div>
      <div class="kd-mq-group" aria-hidden="true">
        <span class="kd-mq-item">01</span>
        <span class="kd-mq-item">02</span>
        <span class="kd-mq-item">03</span>
        <span class="kd-mq-item">04</span>
        <span class="kd-mq-item">05</span>
        <span class="kd-mq-item">06</span>
      </div>
    </div>
  </div>
</div>
CSS
/* 5種類に共通:流れる帯 */
.kd-mq-box {
  color: #0F172A;
}
/* 見える窓。はみ出した部分は隠す */
.kd-mq {
  overflow: hidden;
}
/* 流れる中身。同じ並びを2回くり返し、半分の長さだけ左へ動かすと、つなぎ目なくループする */
.kd-mq-track {
  display: flex;
  width: max-content;
  animation: kd-mq-flow 24s linear infinite;
}
.kd-mq-group {
  display: flex;
  flex-shrink: 0;
}
.kd-mq-item {
  flex-shrink: 0;
  padding-right: 40px;
  white-space: nowrap;
}
@keyframes kd-mq-flow {
  to {
    transform: translateX(-50%);
  }
}
/* マウスを乗せたとき・キーボードで中に入ったときは止める */
.kd-mq-box:hover .kd-mq-track,
.kd-mq-box:focus-within .kd-mq-track {
  animation-play-state: paused;
}
/* 「流れを止める」ボタン(チェックボックス)。チェックが入ったら止める */
.kd-mq-stop {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  padding: 4px 12px;
  border: 1px solid #9CC3DA;
  border-radius: 999px;
  font-size: 0.85em;
  cursor: pointer;
}
.kd-mq-stop input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: #0369A1;
}
.kd-mq-box:has(.kd-mq-stop input:checked) .kd-mq-track {
  animation-play-state: paused;
}
/* 動きを減らす設定の人には、流さずに折り返して全部見せる */
@media (prefers-reduced-motion: reduce) {
  .kd-mq-track {
    width: auto;
    animation: none;
  }
  .kd-mq-group {
    flex-wrap: wrap;
    flex-shrink: 1;
    gap: 8px 24px;
  }
  .kd-mq-item {
    flex-shrink: 1;
    padding-right: 0;
    white-space: normal;
  }
  .kd-mq-group[aria-hidden="true"],
  .kd-mq-stop {
    display: none;
  }
}
.kd-mq-cards .kd-mq-item {
  display: grid;
  place-items: center;
  width: 120px;
  height: 80px;
  margin-right: 12px;
  padding-right: 0;
  border-radius: 12px;
  background: linear-gradient(135deg, #0284C7, #7DD3FC);
  color: #FFFFFF;
  font-weight: 800;
}
.kd-mq-cards .kd-mq-item:nth-child(even) {
  background: linear-gradient(135deg, #0F172A, #33495B);
}
.kd-mq-cards .kd-mq-track {
  animation-duration: 20s;
}

4. 2段で逆向きに流れる

上の段は左へ、下の段は右へ流れます。2段目に animation-direction: reverse(逆再生)を付けただけです。タグやキーワードを、にぎやかに見せたいときの形です。

#カフェ#ランチ#テイクアウト#焼き菓子#駅から3分
#ギフト#季節の限定#予約できます#Wi-Fiあり#ペット可
再生中(マウスを乗せると止まる)
HTML
<div class="kd-mq-box kd-mq-two">
  <div class="kd-mq">
    <div class="kd-mq-track">
      <div class="kd-mq-group">
        <span class="kd-mq-item">#カフェ</span>
        <span class="kd-mq-item">#ランチ</span>
        <span class="kd-mq-item">#テイクアウト</span>
        <span class="kd-mq-item">#焼き菓子</span>
        <span class="kd-mq-item">#駅から3分</span>
      </div>
      <div class="kd-mq-group" aria-hidden="true">
        <span class="kd-mq-item">#カフェ</span>
        <span class="kd-mq-item">#ランチ</span>
        <span class="kd-mq-item">#テイクアウト</span>
        <span class="kd-mq-item">#焼き菓子</span>
        <span class="kd-mq-item">#駅から3分</span>
      </div>
    </div>
  </div>
  <div class="kd-mq">
    <div class="kd-mq-track">
      <div class="kd-mq-group">
        <span class="kd-mq-item">#ギフト</span>
        <span class="kd-mq-item">#季節の限定</span>
        <span class="kd-mq-item">#予約できます</span>
        <span class="kd-mq-item">#Wi-Fiあり</span>
        <span class="kd-mq-item">#ペット可</span>
      </div>
      <div class="kd-mq-group" aria-hidden="true">
        <span class="kd-mq-item">#ギフト</span>
        <span class="kd-mq-item">#季節の限定</span>
        <span class="kd-mq-item">#予約できます</span>
        <span class="kd-mq-item">#Wi-Fiあり</span>
        <span class="kd-mq-item">#ペット可</span>
      </div>
    </div>
  </div>
</div>
CSS
/* 5種類に共通:流れる帯 */
.kd-mq-box {
  color: #0F172A;
}
/* 見える窓。はみ出した部分は隠す */
.kd-mq {
  overflow: hidden;
}
/* 流れる中身。同じ並びを2回くり返し、半分の長さだけ左へ動かすと、つなぎ目なくループする */
.kd-mq-track {
  display: flex;
  width: max-content;
  animation: kd-mq-flow 24s linear infinite;
}
.kd-mq-group {
  display: flex;
  flex-shrink: 0;
}
.kd-mq-item {
  flex-shrink: 0;
  padding-right: 40px;
  white-space: nowrap;
}
@keyframes kd-mq-flow {
  to {
    transform: translateX(-50%);
  }
}
/* マウスを乗せたとき・キーボードで中に入ったときは止める */
.kd-mq-box:hover .kd-mq-track,
.kd-mq-box:focus-within .kd-mq-track {
  animation-play-state: paused;
}
/* 「流れを止める」ボタン(チェックボックス)。チェックが入ったら止める */
.kd-mq-stop {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  padding: 4px 12px;
  border: 1px solid #9CC3DA;
  border-radius: 999px;
  font-size: 0.85em;
  cursor: pointer;
}
.kd-mq-stop input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: #0369A1;
}
.kd-mq-box:has(.kd-mq-stop input:checked) .kd-mq-track {
  animation-play-state: paused;
}
/* 動きを減らす設定の人には、流さずに折り返して全部見せる */
@media (prefers-reduced-motion: reduce) {
  .kd-mq-track {
    width: auto;
    animation: none;
  }
  .kd-mq-group {
    flex-wrap: wrap;
    flex-shrink: 1;
    gap: 8px 24px;
  }
  .kd-mq-item {
    flex-shrink: 1;
    padding-right: 0;
    white-space: normal;
  }
  .kd-mq-group[aria-hidden="true"],
  .kd-mq-stop {
    display: none;
  }
}
.kd-mq-two .kd-mq + .kd-mq {
  margin-top: 8px;
}
.kd-mq-two .kd-mq + .kd-mq .kd-mq-track {
  animation-direction: reverse;
}
.kd-mq-two .kd-mq-item {
  margin-right: 8px;
  padding: 6px 14px;
  border: 1px solid #9CC3DA;
  border-radius: 999px;
  background: #FFFFFF;
}
.kd-mq-two .kd-mq-track {
  animation-duration: 26s;
}

5. 止めるボタン付き

流れの下に「流れを止める」ボタンを付けた形です。チェックを入れると止まり、外すと続きから流れます。文字のお知らせとして使うなら、KAKERUはこの形をすすめます(理由は後半で)。

10月20日(火)は臨時休業です秋の新メニューを始めましたご予約はお電話でも受け付けています
再生中(マウスを乗せると止まる)
HTML
<div class="kd-mq-box kd-mq-ctrl">
  <div class="kd-mq">
    <div class="kd-mq-track">
      <div class="kd-mq-group">
        <span class="kd-mq-item">10月20日(火)は臨時休業です</span>
        <span class="kd-mq-item">秋の新メニューを始めました</span>
        <span class="kd-mq-item">ご予約はお電話でも受け付けています</span>
      </div>
      <div class="kd-mq-group" aria-hidden="true">
        <span class="kd-mq-item">10月20日(火)は臨時休業です</span>
        <span class="kd-mq-item">秋の新メニューを始めました</span>
        <span class="kd-mq-item">ご予約はお電話でも受け付けています</span>
      </div>
    </div>
  </div>
  <label class="kd-mq-stop"><input type="checkbox">流れを止める</label>
</div>
CSS
/* 5種類に共通:流れる帯 */
.kd-mq-box {
  color: #0F172A;
}
/* 見える窓。はみ出した部分は隠す */
.kd-mq {
  overflow: hidden;
}
/* 流れる中身。同じ並びを2回くり返し、半分の長さだけ左へ動かすと、つなぎ目なくループする */
.kd-mq-track {
  display: flex;
  width: max-content;
  animation: kd-mq-flow 24s linear infinite;
}
.kd-mq-group {
  display: flex;
  flex-shrink: 0;
}
.kd-mq-item {
  flex-shrink: 0;
  padding-right: 40px;
  white-space: nowrap;
}
@keyframes kd-mq-flow {
  to {
    transform: translateX(-50%);
  }
}
/* マウスを乗せたとき・キーボードで中に入ったときは止める */
.kd-mq-box:hover .kd-mq-track,
.kd-mq-box:focus-within .kd-mq-track {
  animation-play-state: paused;
}
/* 「流れを止める」ボタン(チェックボックス)。チェックが入ったら止める */
.kd-mq-stop {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  padding: 4px 12px;
  border: 1px solid #9CC3DA;
  border-radius: 999px;
  font-size: 0.85em;
  cursor: pointer;
}
.kd-mq-stop input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: #0369A1;
}
.kd-mq-box:has(.kd-mq-stop input:checked) .kd-mq-track {
  animation-play-state: paused;
}
/* 動きを減らす設定の人には、流さずに折り返して全部見せる */
@media (prefers-reduced-motion: reduce) {
  .kd-mq-track {
    width: auto;
    animation: none;
  }
  .kd-mq-group {
    flex-wrap: wrap;
    flex-shrink: 1;
    gap: 8px 24px;
  }
  .kd-mq-item {
    flex-shrink: 1;
    padding-right: 0;
    white-space: normal;
  }
  .kd-mq-group[aria-hidden="true"],
  .kd-mq-stop {
    display: none;
  }
}
.kd-mq-ctrl .kd-mq {
  padding: 10px 14px;
  border-radius: 10px;
  background: #F2F8FC;
}

※ HTMLの kd-mq-group は、同じ中身を2回書いています。文を書きかえるときは、2か所とも同じように直してください。片方だけ直すと、つなぎ目で文が入れ替わって見えます。

仕組み:同じ文を2回並べて、半分だけ動かす

つなぎ目が出ない理由

流れる中身(.kd-mq-track)の中に、同じ文の並び(.kd-mq-group)を2つ続けて置いています。width: max-content(中身を折り返さない幅にする指定)で、2つ分の長さの1本の帯にします。

この帯を、translateX(-50%) で左へ動かします。translateX() の % は、動かす要素そのものの幅が基準です。帯の半分は、ちょうど1つ目の並びの長さなので、動き終わったとき、2つ目の並びが1つ目の最初の位置にぴったり来ます。そこでアニメーションが最初に戻っても、見た目は同じなので、つなぎ目が見えずに流れ続けます。

書いたもの意味
width: max-content中身を折り返さず、2つ分の長さの帯にする
translateX(-50%)帯の半分(=1つ目の並びの長さ)だけ左へ動かす
24s linear infinite24秒で1回、同じ速さで、ずっとくり返す
padding-right: 40px文と文のすき間。各文の右側に付けるので、つなぎ目も同じすき間になる

すき間を gap ではなく、文の右側の padding-right で作っているのは、並びの最後の文の後ろにもすき間を付けるためです。gap だと最後の文の後ろにすき間が付かないため、2つの並びのつなぎ目だけ詰まって見えます。

文が少ないときは、並びの中で文を増やす

1つの並びが、見える窓の幅より短いと、流れている途中で右側に何もない部分が見えてしまいます。お知らせが1つしかないときは、1つの並びの中に同じ文を2〜3回入れて、窓の幅より長くしておきます。

止める仕組み

animation-play-state: paused は、アニメーションをその場で止める指定です。MDNでは、再開すると止めたところから続く、と説明されています。見本では、マウスを乗せたとき(:hover)、キーボードで中に入ったとき(:focus-within)、「流れを止める」にチェックが入ったとき(:has(input:checked))の3つで止めています。

昔の <marquee> は使わない

文字を流すHTMLの部品として、昔は <marquee>(マーキー)という専用の書き方がありました。MDNでは、非推奨(新しく作るものでは使わないように)と案内されています。今は、この記事のようにCSSのアニメーションで作ります。

数値を変えるとどうなるか

「止めるボタン付き」と同じ見た目で、数値を1つずつ変えて並べました。どれも流れ続けています。

速さ:1周にかける秒数

10月20日(火)は臨時休業です秋の新メニューを始めましたご予約はお電話でも受け付けています
8秒で1周
10月20日(火)は臨時休業です秋の新メニューを始めましたご予約はお電話でも受け付けています
24秒で1周
(見本)
10月20日(火)は臨時休業です秋の新メニューを始めましたご予約はお電話でも受け付けています
60秒で1周

8秒だと、文字を目で追いかけるうちに、次の文が来てしまいます。60秒だと、動いているのか止まっているのか、ぱっと見では分かりにくくなります。注意したいのは、同じ秒数でも、文が長いほど速く流れることです。秒数は「1周の時間」なので、文を増やしたら秒数も増やして、速さをそろえます。

文と文のすき間

10月20日(火)は臨時休業です秋の新メニューを始めましたご予約はお電話でも受け付けています
すき間 8px
10月20日(火)は臨時休業です秋の新メニューを始めましたご予約はお電話でも受け付けています
すき間 40px
(見本)
10月20日(火)は臨時休業です秋の新メニューを始めましたご予約はお電話でも受け付けています
すき間 120px

すき間が8pxだと、どこで文が切れるのか分かりにくく、1つの長い文に見えます。120pxだと、窓の中に何も流れていない時間ができて、表示が消えたように見えます。窓の幅や文字の大きさにもよりますが、文字2〜3文字分から、窓の幅の半分くらいまでが扱いやすい範囲です。

スマホと、見る人への配慮

流れる文は、読み終わる前に消える

流れる文は、見る人が読む速さではなく、こちらが決めた速さで動きます。読むのに時間がかかる人や、途中から目に入った人は、最後まで読めないまま文が窓の外へ出てしまいます。だから、読み逃して困る情報は流さない、というのがこの部品の一番の注意点です。

止める手段を用意する

W3Cのアクセシビリティの基準(WCAG 2.2)には、「自動で始まり、5秒より長く続き、ほかの内容と一緒に表示される動き」には、止める・一時停止する・隠す手段を用意する、という項目があります。マウスを乗せると止まる仕組みは、スマホのように指で触る画面では使えません。文字のお知らせとして使うなら、5番目のように「流れを止める」ボタンを付けておくと、この基準に沿った形になります。

ボタンの見た目とCSSは5種類の共通部分に入れてあるので、ほかの見本でも、HTMLの最後に <label class="kd-mq-stop"> の1行を足せば同じように止められます。

2回目の文は、読み上げから隠す

つなぎ目を消すために書いた2つ目の並びには、aria-hidden="true"(読み上げソフトに読ませない指定)を付けています。付けないと、読み上げソフトで同じお知らせが2回続けて読まれます。

お知らせにリンクを入れるときは、2つ目の並びのリンクがキーボードで選べてしまう点に注意します。MDNでは、押せる要素に aria-hidden="true" を付けないよう案内されています。リンクを入れるなら、流れる帯の外に「お知らせ一覧」へのリンクを1つ置く形にするほうが、扱いやすくなります。

「動きを減らす」設定の人には、流さない

画面の動きが苦手な人は、スマホやパソコンで「動きを減らす」設定をオンにしていることがあります。CSSの prefers-reduced-motion を使うと、この設定の人にだけ別の見え方を出せます。見本では、流れを止め、2つ目の並びを隠し、文を折り返して全部が読めるようにしています。

トミー

流れる帯は、目に入りやすい分、ページの中で一番うるさい部品にもなります。
1ページに1つまで、と決めておくと、ほかの内容の邪魔をしにくくなります。

AIに頼むなら

同じような部品は、Claudeなどの生成AIに頼んでもすぐ作れます。そのときは、見た目だけでなく、作り方・数値・配慮まで伝えると、直す回数が減ります。

お店のお知らせ3件を、横に流れる帯にしたい。JavaScriptなし、<marquee>は使わない。
同じ並びを2回置いて translateX(-50%) でつなぎ目なくループ、24秒で1周。2回目の並びには aria-hidden="true"。
マウスを乗せると止まり、「流れを止める」チェックボックスでも止められるように。動きを減らす設定の人には流さず折り返して全部見せて。

AIが出したコードは、そのまま使う前に、次の3つを確かめます。

  • つなぎ目で、文が飛んだり詰まったりしないか。1周分(見本なら24秒)より長く眺めて、最後の文から最初の文へ移るところのすき間が、ほかと同じかを見ます
  • 止める手段があるか。マウスを乗せて止まるだけでは、スマホでは止められません。止めるボタンがあるか、押したら本当に止まるかを試します
  • スマホの幅で、ページ全体が横にずれないか。流れる帯の外側に overflow: hidden がないと、長い帯がはみ出して、ページ全体が横にスクロールしてしまいます。ブラウザの開発者ツールでスマホの幅にして、横に動かないかを確かめます

KAKERUならこう使う/使わない

最後に、作り手としての判断です。

使う場面

  • 「新メニュー」「ブログを更新しました」のような、読まれなくても困らないお知らせ。止めるボタン付きにして、ページの上に1本だけ置きます
  • トップページの区切りに置く、大きな文字の帯。会社の得意分野やキーワードを、飾りとしてゆっくり流します。読ませる文ではないので、短い単語だけにします
  • 施工例や作品の写真を、ゆっくり見せたいとき。写真の一覧ページへのリンクを、帯の外に必ず置きます

使わない場面

  • 休業日・料金や営業時間の変更など、全員に読んでほしいこと。流さずに、ページの上に止めた文で書きます
  • お知らせが長い文のとき。1文が窓の幅の2倍を超えるような文は、流れている間に読み切れません
  • 同じページに、もう動いている部品があるとき。スライドショーや動画の背景と並べると、どこを見ればいいか分からなくなります
トミー

「目立たせたいから流す」は、実は逆効果になりやすいです。
大事なことほど止めて書く、流すのは「ついで」と「飾り」だけ、と分けておくと迷いません。

まとめ

  • 流れるお知らせは、同じ並びを2回置いて translateX(-50%) で動かすと、つなぎ目なくループする
  • 文と文のすき間は、gap ではなく各文の右側の padding で作ると、つなぎ目も同じすき間になる
  • 秒数は「1周の時間」。文を増やしたら秒数も増やして、速さをそろえる
  • 5秒より長く動き続けるので、止めるボタンを付ける。マウスを乗せて止まるだけでは、スマホでは止められない
  • 2回目の並びは aria-hidden で読み上げから隠す。読み逃して困る情報は流さない

まずは「止めるボタン付き」のコードをコピーして、お知らせの文を自分のサイトのものに書きかえてみてください。CSSだけで流れて、止まるのが分かります。

参考にした資料

いずれも2026年10月15日に確認しました。ブラウザの対応状況は変わることがあります。最新の情報は各ページでご確認ください。

ふだんの制作の話や、作ったものの裏側は Instagram と X でも出しています。

関連記事

CSSだけで作るローディングアニメーション コピペで使える5種類と、見る人への配慮
押すと切り替わるタブをCSSだけで コピペで使える5種類と、使う・使わないの判断
グラデーションの文字をCSSだけで コピペで使える5種類と、読みやすさを守る使い方
文字が流れるお知らせをCSSだけで コピペで使える5種類と、使う・使わないの判断

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

CAPTCHA