Tell me, please, how to make other buttons appear very smoothly when you click on the ellipsis? transition is not working ...

  var buttons = document.querySelectorAll('ul li'); for (var i = 3; i < buttons.length - 2; i++) { buttons[i].style.display = "none"; } var dots = document.querySelector('ul li span'); dots.onclick = function () { for (var i = 0; i < buttons.length; i++) { buttons[i].style.display = "inline"; } dots.style.display = 'none'; } 
  ul > li { display: inline; padding: 10px; background: #c7c7c7; } 
 <ul> <li><a href="">Следующая</a></li> <li><a href="">1</a></li> <li style="cursor: pointer"><span>...</span></li> <li><a href="">2</a></li> <li><a href="">3</a></li> <li><a href="">4</a></li> <li><a href="">6</a></li> <li><a href="">7</a></li> <li><a href="">Предыдущая</a></li> </ul> 

  • one
    The transition will not work with display: none; as an option - use opacity: 1 (visible) / 0 (hidden) instead of display, then transition will work - iKey
  • Thank you all for your help, now there is plenty to choose from - KvinT

4 answers 4

The transition property does not handle discrete values ​​(discontinuous, consist of individual values, for example, block , inline , inline-block ...), but only analog ones (for example, numbers, colors).

For example, let's make opacity: 0 , and when you click it will change it to opacity: 1 . Add transition: opacity 1s ease-in-out , but nothing works again, why? The answer is not so obvious, all because of the JavaScript processing engine, or rather its event-loop , it processes and changes the values ​​of css properties, but does not allow time for its rendering by the browser. You can solve this by wrapping our property change in setTimeout - setTimeout(() => buttons[i].style.opacity = 1, 0) . SetTimeout with zero value, sense? And the point is that between these functions there will be a transfer of control to the browser and it will draw our animation.

PS dots.style.display = 'none' , you need to assign it to the parent.

PPS You can find out more about the event-loop here.

 var buttons = document.querySelectorAll('ul li'); for (var i = 3; i < buttons.length - 2; i++) { buttons[i].style.display = "none"; buttons[i].style.opacity = 0; } var dots = document.querySelector('ul li span'); dots.onclick = function () { for (let i = 0; i < buttons.length; i++) { buttons[i].style.display = "inline"; setTimeout(() => buttons[i].style.opacity = 1, 0) } dots.parentElement.style.display = 'none'; } 
  ul > li { display: inline; padding: 10px; background: #c7c7c7; transition: opacity 1s ease-in-out } 
 <ul> <li><a href="">Следующая</a></li> <li><a href="">1</a></li> <li style="cursor: pointer"><span>...</span></li> <li><a href="">2</a></li> <li><a href="">3</a></li> <li><a href="">4</a></li> <li><a href="">6</a></li> <li><a href="">7</a></li> <li><a href="">Предыдущая</a></li> </ul> 

    So it turned out completely smooth appearance of the buttons

     var buttons = document.querySelectorAll('ul li'); for (var i = 3; i < buttons.length - 2; i++) { buttons[i].classList.add('hidden'); } var dots = document.querySelector('.d'); dots.onclick = function() { for (var i = 0; i < buttons.length; i++) { buttons[i].classList.remove('hidden'); } dots.style.display = 'none'; } 
     * { list-style: none; text-decoration: none; margin: 0; padding: 0; box-sizing: border-box; } html, body { font-family: Helvetica, sans; font-size: 1em; font-weight: 900; } ul { width: 600px; margin: 20px auto; text-align: center; display: flex; justify-content: center; } li { background: lightblue; width: 50px; overflow: hidden; border-radius: 6px; transition: all .3s linear; } a { color: #000; } li.hidden { visibility: hidden; transition: all .3s linear; opacity: 0; width: 0; } .d { line-height: 15px; } 
     <ul> <li><a href="">next</a></li> <li><a href="">1</a></li> <li><a href="">2</a></li> <li><a href="">3</a></li> <li><a href="">4</a></li> <li><a href="">5</a></li> <li><a href="">6</a></li> <li><a href="">7</a></li> <li><a href="">8</a></li> <li><a href="">9</a></li> <li class="d"><a href="/" onclick="event.preventDefault()">...</a></li> <li><a href="">prev</a></li> </ul> 

       // генерация разметки кнопок, для компактности примера let btnsHtml = (to => { let str = ''; for (let i = 2; i <= to; i++) str += `<li><a href="">${i}</a></li>\n\t`; return str; })(10); let list = document.querySelector('ul'); list.innerHTML = list.innerHTML.replace(/<\!--[\s\S]+-->/g, btnsHtml); // значимая часть примера начинается здесь var buttons = document.querySelectorAll('ul > li:nth-child(n+4):nth-last-child(n+3)'); for (let btn of buttons) btn.classList.add('collapse'); let dots = document.querySelector('ul > li:nth-child(3)'); dots.onclick = function () { for (let btn of buttons) btn.classList.remove('collapse'); this.classList.add('collapse'); }; 
       ul > li { display: inline-block; padding: 10px; background: #c7c7c7; font: 12px sans-serif; text-align: center; vertical-align: middle; } ul > li:nth-child(n+2):nth-last-child(n+2) { width: 2ch; overflow: hidden; transition: all 0.8s cubic-bezier(0.75, 0, 0.5, 1); } ul > li.collapse { width: 0 !important; padding: 10px 0; margin: 0 -2px; } ul > li a { text-decoration: none; } ul { margin: 0; padding: 0; } 
       <ul> <li><a href="">Следующая</a></li> <li><a href="">1</a></li> <li style="cursor: pointer"><span>...</span></li> <li><a href="">2</a></li> <!-- не обращайте внимания, кнопки создаются средствами JS --> <li><a href="">Предыдущая</a></li> </ul> 

      • 2
        good example ... better than my best answer ... - user33274
      • Thank you, @Maxim! - yar85
       var dots = document.querySelector('ul li span'); dots.onclick = function () { for (var i = 0; i < buttons.length; i++) { buttons[i].slideDown( 'slow' ); } dots.slideUp( 'slow' ); }