23622


marqueeタグは廃止されるそうですが、CSSで代替できると聞きました。  
下記のソースコードにあるような『方向』や『速度』などをCSSに置き換えるには、  
どのようにしたらいいのでしょうか。ご教示ください。

[code]

    <style>
    .DIRECTION {
      color: white;
      background: black;
    }
    
    .BLINK {
      animation: blink 1s step-end infinite normal;
    }
    @keyframes blink {
      0% { color: red; }
      50% { color: transparent; }
    }
    </style>
    
    <SCRIPT type="text/javascript">
    <!--
    function marLeft() {
    
        myMarquee.direction='left';
    　　document.getElementById('myMarquee').start(); 
        document.getElementById("blinkL").classList.add("BLINK");
        document.getElementById("blinkR").classList.remove("BLINK");
    }
    
    function marRight() {
        myMarquee.direction='right';
    　　document.getElementById('myMarquee').start(); 
        document.getElementById("blinkR").classList.add("BLINK");
        document.getElementById("blinkL").classList.remove("BLINK");
    }
    
    
    function marSpeed(opt){
    　　var selectedIndex = opt.selectedIndex;
    
    　　　　document.getElementById('myMarquee').setAttribute('scrollamount', 6, 0);
      　　  document.getElementById('blinkL').disabled=false;
      　　  document.getElementById('blinkR').disabled=false;
    if(selectedIndex==0){
    　　　　document.getElementById('myMarquee').setAttribute('scrollamount', 12, 0);
    　  　}
    else if(selectedIndex==2){
    　　　　document.getElementById('myMarquee').setAttribute('scrollamount', 1, 0);
    　　　}
    else if(selectedIndex==3){
    　　　　document.getElementById('blinkL').disabled=true;
    　　　　document.getElementById('blinkR').disabled=true;
            document.getElementById('blinkL').classList.remove("BLINK");
    　　　　document.getElementById('blinkR').classList.remove("BLINK");
    　　　　document.getElementById('myMarquee').stop();
    　　　}
    else if(selectedIndex==4){
        var oldMarquee = document.querySelector('#myMarquee');
        oldMarquee.parentNode.insertBefore(oldMarquee.cloneNode(true), oldMarquee);
        oldMarquee.parentNode.removeChild(oldMarquee);
    
        myMarquee.direction='left';
        document.getElementById("blinkL").classList.add("BLINK");
        document.getElementById("blinkR").classList.remove("BLINK");
        document.getElementById('marSpeed').value="Normal Speed";
         }
    }
    // -->
    </SCRIPT>
    
    <marquee scrollamount="6" id="myMarquee">
    
    <p>How to replace marquee with CSS.</p>
    
    </marquee>
    
    
      <input id="blinkL" type="button" class="DIRECTION BLINK" onclick="marLeft();" value="←"> 
           ☆
    <select id='marSpeed' name="speedSelector" onchange='marSpeed(this)'>
      <option  value='Faster'>&nbsp;&nbsp;&nbsp;Faster</option>
      <option  value='Normal Speed' selected>&nbsp;&nbsp;&nbsp;(Speed)</option>
      <option  value='Slower'>&nbsp;&nbsp;&nbsp;Slower</option>
      <option  value='Stop'>―STOP―</option>
      <option  value='Reset'>&nbsp;&nbsp;&nbsp;RESET</option>
    </select>
           ☆
      <input id="blinkR" type="button" class="DIRECTION" onclick="marRight();" value="→"> 
    
[/code]


CC BY-SA 3.0
2016-03-28T08:50:11.507
23539
2019-12-13T19:18:44.180
2016-03-28T08:59:02.143
9359
9359
question
javascript html css
marqueeをCSSに代替するには。


CSS Animation のことでしょうか。

CSS
Animationは、アニメーション一回にかける時間を決めたうえで、n%時間が経過したときにCSSプロパティの値をどうするか、という形で指定を行います。例えばテキストが右に流れるアニメーションは、

  * 最初は左にはみ出している
  * 最後は右にはみ出している
  * その間を10秒かけてアニメーションさせる

といった指定をすることになります。

[code]

    .marquee {
      /* 画面外に出てもスクロールバーを出さずに隠す */
      overflow-x: hidden;
    }
    .marquee-inner {
      /* marqueeという名前のキーフレームを参照 */
      animation-name: marquee;
      /* 10秒かけてアニメーション */
      animation-duration: 10s;
      /* 緩急をつけず、線形に変化させる */
      animation-timing-function: linear;
      /* 無限に繰り返す */
      animation-iteration-count: infinite;
    }
    
    @keyframes marquee {
      from { transform: translate(-100%); }
      to   { transform: translate(100%); }
    }
[/code]

[code]

    <div class="marquee">
      <div class="marquee-inner">
        <p>How to replace marquee with CSS.</p>
      </div>
    </div>
[/code]

横位置をどうやって指定するか、どうやって画面外にはみ出させるかは様々な方法がありますから、ググったり試したりしてみてください。また上のサンプルではベンダープレフィックスを一切付けていませんが、ブラウザによっては必要です。

  * [マーキー作成で学ぶ、CSS3アニメーション超入門 | 小棹(こさお)制作所](http://cosao.net/archives/6839)
  * [【CSS3】全ブラウザ対応！ CSS3 で作る marquee の実装。 - ONZE](http://on-ze.com/archives/648)

なお、一時期 `-webkit-marquee` などをはじめとする [CSS Marquee
Module](https://www.w3.org/TR/2014/NOTE-css3-marquee-20141014/)
の策定が勧められていましたが、結局完成しないままに廃止されました。これを解説した日本語の記事もいくつか見つかりますが、現在のChromeではプレフィックス付きでも動きません。

参考 [CSS3 marquee - CSS3ウェブブラウザ実装メモ - 血統の森
web実験小屋](http://momdo.s35.xrea.com/web-html-test/CSS3-memo/marquee.html)

* * *

プロパティを変更すれば動的に方向や速度を変更できるのではと踏んでいましたが、そんな甘くはなさそうですね。どうやら途中で指定を変更すると、最初からその設定だったものとして「開始から累計何秒経ったか」を元に計算されるようです。

例えば、キーフレームやdirectionを変更すると動きを反転させることができますが、右方向の序盤で方向転換させれば左方向の序盤、つまり右側に瞬間移動します。同じく、durationを変えることで（結果的に）アニメーションの速度が変えられますが、その場で速度が変わるわけではなく、最初からそのdurationだったとした時の位置に瞬間移動します。

テスト色々 <https://jsfiddle.net/q1jb6xxp/1/>

[code]

    $('.pause').click(function() {
      $(this).siblings('div').toggleClass('pause');
    });
    $('.reverse').click(function() {
      $(this).siblings('div').toggleClass('reverse');
    });
    $('.speed').click(function() {
      $(this).siblings('div').toggleClass('fast');
    });
    $('.reset').click(function() {
      var target = $(this).siblings('div');
      target.removeClass('marquee-inner');
      setTimeout(function() {
        target.addClass('marquee-inner');
      }, 0);
    });
[/code]

[code]

    .marquee {
      overflow-x: hidden;
    }
    
    .marquee-inner {
      animation-name: marquee;
      animation-duration: 8s;
      animation-timing-function: linear;
      animation-iteration-count: infinite;
      border: 1px solid gray;
    }
    
    .pause {
      animation-play-state: paused;
    }
    
    .reverse {
      animation-direction: reverse;
    }
    
    .fast {
      animation-duration: 5s;
    }
    
    @keyframes marquee {
      from {
        transform: translate(-100%);
      }
      to {
        transform: translate(100%);
      }
    }
[/code]

[code]

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
    <div class="marquee">
      <div class="marquee-inner">
        <p>How to replace marquee with CSS.</p>
      </div>
      <button class="pause">pause</button>
      <button class="reverse">reverse</button>
      <button class="speed">speed</button>
      <button class="reset">reset</button>
    </div>
    <div class="marquee">
      <div class="marquee-inner">
        <p>How to replace marquee with CSS.</p>
      </div>
      <button class="pause">pause</button>
      <button class="reverse">reverse</button>
      <button class="speed">speed</button>
      <button class="reset">reset</button>
    </div>
[/code]

単純なmarqueeはCSSでも再現できるというだけで、`<marquee>` タグの全ての機能が簡単に置き換えられるわけではありません。それでもCSS
Animationで頑張るというなら、仕組みをご自身でしっかり理解された方がいいように思います。

なお、[jquery.marquee.js](https://github.com/aamirafridi/jQuery.Marquee)というライブラリもあるようです。前述の問題を解決するわけではありませんが、Javascriptから簡単に操作でき、対応していない環境ではJSへのフォールバックもしてくれるようです。


CC BY-SA 4.0
2016-03-28T10:34:50.447
23544
2019-12-13T19:18:44.180
2019-12-13T19:18:44.180
32986
8000
23539
answer


こんな感じでしょうか。

[code]

    <DOCTYPE! html>
    <html>
    <head>
    <meta charset="UTF-8">
    <style>
    .marquee {
        overflow: -webkit-marquee;
        white-space: nowrap;
    }
    .right {
        -webkit-marquee-direction: right;
    }
    .fast {
        -webkit-marquee-speed: fast;
    }
    </style>
    </head>
    <body>
        <div class="marquee">
            <p>The quick brown fox jumps over the lazy dog.</p>
        </div>
        <div class="marquee right">
            <p>The quick brown fox jumps over the lazy dog.</p>
        </div>
        <div class="marquee fast">
            <p>The quick brown fox jumps over the lazy dog.</p>
        </div>
    </body>
    </html>
    
[/code]

こちらのサイトを参考にしました。  
[【CSS3】わずか2行の CSS3 でmarqueeを再現する方法。](http://on-ze.com/archives/80)

廃止予定で非推奨のはずのmarqueeタグがほとんど全ての最新ブラウザで使えるのに対し、[サポート状況](http://www.w3schools.com/cssref/css3_browsersupport.asp)は、かなりお寒い感じです。

(追記と訂正)  
…と思ったらunaristさんのコメント及び回答の追記部分にあるように仕様策定は中断されていたのですね。リンク先のドキュメントに「Note that a
somewhat similar effect of moving text can be achieved with generic CSS
animations」(似たようなテキスト移動の効果は一般性のあるCSSアニメーションで実現できるというのをお忘れなく)とありますから、そういうことなんでしょう。(Safariではまだ動きましたが、まぁ、使うべきではないですね。)


CC BY-SA 3.0
2016-03-28T12:14:20.017
23554
2016-03-28T21:34:29.573
2016-03-28T21:34:29.573
13972
13972
23539
answer


transitionによる例を下記スニペットに示しておきます。  
アニメーションの設定を変える時は、必ず一度止めてしまう事で面倒を回避しています。  
スムーズさは失なわれる事でしょう。

[code]

    function marquee(elm_or_event){
     "use strict";
     function current(){
      return Number(getComputedStyle(elm).transform.split(",")[4]) || 0;
     }
     function to(px, sec){
      elm.style.transform = "translateX(" + px + "px)";
      elm.style.transition = "transform " + sec + "s linear 0s";
     }
     function scroll(px){
      elm.addEventListener("transitionend", marquee, false);
      to(px, Math.abs((px - current())/right * elm.dataset.marqueeSec));
     }
     var elm = elm_or_event.target || elm_or_event;
     var right = elm.parentElement.getBoundingClientRect().width;
     var left = -elm.getBoundingClientRect().width;
    
     elm.removeEventListener("transitionend", marquee, false);
     to(current(), 0);
    
     if(elm.dataset.marquee == "stop"){
      return;
     }
     if(current()+1 >= right){
      to(left-1, 0);
     }
     else if(current()-1 <= left){
      to(right+1, 0);
     }
     scroll((elm.dataset.marquee == "left") ? left : right);
    }
    marquee(hello);
[/code]

[code]

    [data-marquee]{
     display: inline-block;
     transform: translateX(-100%);
    }
    .marquee_container { overflow-x: hidden; }
[/code]

[code]

    <div class="marquee_container">
     <span id="hello" data-marquee="left" data-marquee-sec="3">
      Hello marquee!
     </span>
    </div>
    <p>
    <button onClick="hello.dataset.marquee='left'; marquee(hello);">
     Left
    </button>
    <button onClick="hello.dataset.marquee='stop'; marquee(hello);">
     Stop
    </button>
    <button onClick="hello.dataset.marquee='right'; marquee(hello);">
     Right
    </button>
    </p>
                                                                       
    <p>
    <button onClick="hello.dataset.marqueeSec='10'; marquee(hello);">
     Slow
    </button>
    <button onClick="hello.dataset.marqueeSec='3'; marquee(hello);">
     Medium
    </button>
    <button onClick="hello.dataset.marqueeSec='1'; marquee(hello);">
     Fast
    </button>
    </p>
[/code]

（Webクライアントサイドはこんな物でも色々と考慮しなければならない事があり、しかも状況は日々変わるので、プログラミングの学習が目的でしたらあまり深入りしない方がよいかと思います）  
追記:  
上記の`marquee`関数は要素を動かす方向を要素の`data-marquee`属性で決定します。  
最初から左に動かすのならHTMLで`data-marquee="left"`としておけばよいです。  
その場合、要素の最初の位置が不自然と感じるでしょうからCSSで`transform:
translateX(-100%);`として見えない場所へ移動させています。  
（当初のコードでは手動で移動させる事は考慮していなかったので、判定がいいかげんで移動させられる位置が制限されていました。少しだけ堅牢なコードに直してあります。）


CC BY-SA 3.0
2016-03-30T09:22:30.307
23622
2016-04-01T11:27:18.417
2016-04-01T11:27:18.417
3054
3054
23539
answer