Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

119
Vistas
How to make each current element in loop centered in container
  1. As the container slides to the left, I want each tab to be centered for a brief moment in the container.
  2. Before the animation begins, I want the very first tab to be centered in the container on page load before the animation begins. I know I need to divide each element's offsetWidth by 2 so that it is calculated to be centered but I'm not sure where/how to do that.

Link to JS Fiddle: https://jsfiddle.net/nb5a92x3/

window.onload = function() {
    
    const tabsContainer = document.querySelector('.tabsContainer');
    const tabs = tabsContainer.querySelectorAll('.tab');

    function animate(target) {
        let siblings = [];
        let elm = target;
        let keyframes = [];
        let offset;
    
        // Push the widths of each previous element to an array
        while (elm = elm.previousElementSibling) {
            siblings.push(elm.offsetWidth);
        }
        
        // Add the sum of all previous elements
        offset = siblings.reduce((prev, current) => prev + current, 0);

        // Animate the container to the left
        setTimeout(function() {
            tabsContainer.style.left = `calc(50% - ${offset}px)`;
        }, i * 800);
    }
    
    // Run the code
    for (i = 0; i < tabs.length; i++) {
        animate(tabs[i]);
    }
  }
body {
    background: #ccc;
}

section {
    text-align: center;
    width: 375px;
    background: white;
    margin: 0 auto;
    padding: 16px;
    position: relative;
    display: flex;
    overflow: hidden;
}

.tabsContainer {
    display: flex;
    position: relative;
    margin: 0;
    padding: 0;
    list-style: none;
    gap: 0 16px;
    transition: left 0.2s ease;

    .tab {
        border-radius: 25px;
        background: gray;
        text-align: center;
        height: 34px;
        display: inline-flex;
        align-items: center;
        padding: 0 16px;
    }
}
<section>
  <ul class="tabsContainer">
    <li class="tab">TAB ONE</li>
    <li class="tab">ANOTHER TAB HERE</li>
    <li class="tab">A REALLY LONG TAB HERE</li>
    <li class="tab">LAST TAB</li>
  </ul>
</section>
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

If you set in CSS your container to margin-left: 50%
than all you need is x = EL_curr.offsetLeft + EL_curr.offsetWidth / 2
and apply that x value to the slider-container CSS translateX (which is far more performant than animating the CSS left property, since transform can be hardware accelerated).

// Utility functions:

const EL  = (sel, par) => (par || document).querySelector(sel);
const ELS = (sel, par) => (par || document).querySelectorAll(sel);

// Tabs animator:

const tabsAnimator = (EL_slider) => {
  const ELS_items = ELS(".tab", EL_slider);
  const tot = ELS_items.length;
  let curr = 0;
  let tOut;

  const anim = () => {
    const EL_curr = ELS_items[curr];
    const x = EL_curr.offsetLeft + EL_curr.offsetWidth / 2;
    EL_slider.style.transform = `translateX(-${x}px)`;
    curr += 1; // Increment counter
    if (curr > tot - 1) curr = 0; // Reset counter
    tOut = setTimeout(anim, 1500);
  };

  anim(); // Init!
};

ELS(".tabsContainer").forEach(tabsAnimator);
* {
  margin: 0;
  box-sizing: border-box;
}

.tabsWrapper {
  width: 375px;
  margin: 20px auto;
  padding: 16px 0;
  position: relative;
  overflow: hidden;
  background: #ccc;
  border-radius: 3em;
}

.tabsContainer {
  position: relative;
  padding: 0;
  display: inline-flex;
  list-style: none;
  gap: 0 15px;
  transition: transform 0.3s;
  margin-left: 50%;
}

.tabsContainer .tab {
  border-radius: 25px;
  background: gold;
  white-space: nowrap;
  padding: 5px 15px;
}
<section class="tabsWrapper">
  <ul class="tabsContainer">
    <li class="tab">5 OFF FRIDAY</li>
    <li class="tab">10 OFFSUMMER</li>
    <li class="tab">SAVE MORE</li>
    <li class="tab">HALF OFF EVERYTHING</li>
  </ul>
</section>

<section class="tabsWrapper">
  <ul class="tabsContainer">
    <li class="tab">JavaScript</li>
    <li class="tab">HTML</li>
    <li class="tab">CSS</li>
  </ul>
</section>

  • don't use horizontal paddings on the wrapper or container slider.
  • don't just use section as a selector. It's too common. Use rather a specific class like .tabsWrapper on the wrapper parent.

Additionally, if you'd like to pause the animation on "mouseenter", use clearTimeout(tOut); — and just anim() in the "mouseleave" Event.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda