# Logo Wall Sycle

> A logo grid that cycles partners with blurred dissolve swaps — premium social-proof walls that stay alive.

**Definition:** Logo Wall Sycle is a components UI animation from collections.html. It is built with HTML, CSS, JavaScript, and GSAP, ships with a live preview, and is free to copy into personal and commercial projects.

## Facts
- Category: Components
- Stack: HTML, CSS, JavaScript, and GSAP
- Added: 2026-08-04
- Canonical page: https://html.bosconvertpro.com/collection/logo-wall-sycle
- Full-page preview: https://html.bosconvertpro.com/collection/logo-wall-sycle/full
- Live demo: https://html.bosconvertpro.com/demos/logo-wall-sycle/index.html
- Markdown mirror: https://html.bosconvertpro.com/collection/logo-wall-sycle/index.md
- License: https://html.bosconvertpro.com/terms

## How to use
1. Open https://html.bosconvertpro.com/collection/logo-wall-sycle/full to preview the animation in full screen.
2. Copy index.html, styles.css, and script.js from the code tabs on https://html.bosconvertpro.com/collection/logo-wall-sycle.
3. Paste the files into your project and adjust timing, easing, and content as needed.

## FAQ
### What is Logo Wall Sycle?

Logo Wall Sycle is a components UI animation from collections.html. A logo grid that cycles partners with blurred dissolve swaps — premium social-proof walls that stay alive.

### What is Logo Wall Sycle built with?

Logo Wall Sycle is built with HTML, CSS, JavaScript, and GSAP. The source for every file is shown on the animation page and can be copied straight into your project.

### How do I use Logo Wall Sycle in my project?

Open the animation page (https://html.bosconvertpro.com/collection/logo-wall-sycle), preview it live, then copy index.html, styles.css, and script.js from the code tabs. Paste the files into your project and adjust timing, easing, and content as needed. A standalone demo runs at https://html.bosconvertpro.com/demos/logo-wall-sycle/index.html.

### Is Logo Wall Sycle free to use?

Yes. The Logo Wall Sycle demo code may be used in personal and commercial projects. You may not resell or redistribute the collection itself as a competing template pack. Full terms: https://html.bosconvertpro.com/terms.

## Source — index.html
````html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Logo Wall Cycle</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <section class="section-resource">
      <div class="section-resource__max-width">
        <!--
          data-logo-wall-shuffle="false" keeps the first visible logos in DOM order.
          Set to "true" (or remove the attr) to shuffle the initial front set as well.
        -->
        <div
          data-logo-wall-shuffle="false"
          data-logo-wall-cycle-init
          class="logo-wall"
        >
          <div class="logo-wall__collection">
            <div data-logo-wall-list class="logo-wall__list">
              <!-- Visible slots: first 8 on desktop (4×2), first 6 on tablet (3×2).
                   Extra items stay in the cycle pool and rotate in over time. -->
              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370ea9d37fbceb3be49cb_logo-webflow.svg"
                      alt="Webflow"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370ea48d4fb0c708dd1dc_logo-microsoft.svg"
                      alt="Microsoft"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370ea9ba384ff47fa5d51_logo-asana.svg"
                      alt="Asana"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370eaec918fbd4a0acc12_logo-snapchat.svg"
                      alt="Snapchat"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370ea155a551c08692a03_logo-google.svg"
                      alt="Google"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370eafdf2b295d65f9450_logo-bluesky.svg"
                      alt="Bluesky"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370ea68a433ee5808ed90_logo-codepen.svg"
                      alt="CodePen"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370ea2ebc0415055d04f3_logo-linkedin.svg"
                      alt="LinkedIn"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <!-- Pool logos (hidden via CSS, cycled into the wall) -->
              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370ea7699561e6f9f008f_logo-android.svg"
                      alt="Android"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370ea753f2afe2f6b036f_logo-apple.svg"
                      alt="Apple"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370eabec1e0c00348b5ed_logo-twitter.svg"
                      alt="X / Twitter"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.simpleicons.org/figma/ffffff"
                      alt="Figma"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370ea36c91584afe43e2d_logo-medium.svg"
                      alt="Medium"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370ea87b05cdce0387084_logo-eventbrite.svg"
                      alt="Eventbrite"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370eaf4465d763c2f9b2a_logo-behance.svg"
                      alt="Behance"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>

              <div data-logo-wall-item class="logo-wall__item">
                <div data-logo-wall-target-parent class="logo-wall__logo">
                  <div class="logo-wall__logo-before"></div>
                  <div data-logo-wall-target class="logo-wall__logo-target">
                    <img
                      class="logo-wall__logo-img"
                      src="https://cdn.prod.website-files.com/68836e3f51ac98fec14ceed2/688370eaec1d445957d7e3a1_logo-chatgpt.svg"
                      alt="ChatGPT"
                      width="100"
                      loading="lazy"
                    />
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>

    <script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/ScrollTrigger.min.js"></script>
    <script src="script.js"></script>
  </body>
</html>
````

## Source — styles.css
````css
/* --------------------------------------------------------------------------
   Logo Wall Cycle — premium bordered cells + blurred logo swaps
   Dark logos on a soft light surface
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  color: #131313;
  background-color: #e8e6e3;
  font-family: Inter, system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img {
  display: block;
  max-width: 100%;
  -webkit-user-drag: none;
  user-select: none;
}

/* Full-viewport stage */
.section-resource {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  padding: 5vw;
}

.section-resource__max-width {
  width: 100%;
  max-width: 60em;
}

/* --------------------------------------------------------------------------
   Logo wall grid — separated cells with borders
   -------------------------------------------------------------------------- */

.logo-wall {
  display: flex;
  justify-content: center;
  width: 100%;
}

.logo-wall__collection {
  width: 100%;
  border: 1px solid rgba(19, 19, 19, 0.12);
  overflow: hidden;
  background: transparent;
}

.logo-wall__list {
  display: flex;
  flex-flow: row wrap;
  /* Outer edges of the grid lines live on the collection;
     each cell draws right + bottom borders only */
}

.logo-wall__item {
  width: 25%; /* 4 columns desktop */
  position: relative;
  border-right: 1px solid rgba(19, 19, 19, 0.1);
  border-bottom: 1px solid rgba(19, 19, 19, 0.1);
  background: transparent;
}

/* Kill outer-edge double lines so the collection border stays clean */
.logo-wall__item:nth-child(4n) {
  border-right: none;
}

/* Row 2 ends the visible wall on desktop (8 items) — drop bottom border */
.logo-wall__item:nth-child(n + 5):nth-child(-n + 8) {
  border-bottom: none;
}

/* Hide overflow slots: desktop shows 8 (4×2), rest feed the pool */
[data-logo-wall-list] [data-logo-wall-item]:nth-child(n + 9) {
  display: none;
}

/* Cell shell — aspect ratio + clip for the premium swap */
.logo-wall__logo {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

/* 3:2 aspect ratio spacer */
.logo-wall__logo-before {
  width: 100%;
  padding-top: 66.66%;
  pointer-events: none;
}

/* Logo layer — blur is applied here so img can keep its dark invert */
.logo-wall__logo-target {
  position: absolute;
  z-index: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 66.66%;
  height: 40%;
  /* Unitless px amount — GSAP animates this cleanly */
  --logo-blur: 0;
  filter: blur(calc(var(--logo-blur) * 1px));
  will-change: transform, opacity, filter;
  transform-origin: center center;
  backface-visibility: hidden;
}

.logo-wall__logo-img {
  width: 100%;
  height: 100%;
  max-height: 100%;
  object-fit: contain;
  object-position: center;
  /*
    CDN logos are often white SVGs.
    Invert them to dark ink on the light surface.
  */
  filter: brightness(0) saturate(100%);
  opacity: 0.9;
}

/* --------------------------------------------------------------------------
   Breakpoints
   -------------------------------------------------------------------------- */

/* Tablet: 3 columns, show 6 logos */
@media screen and (max-width: 991px) {
  .logo-wall__item {
    width: 33.333%;
  }

  /* Reset desktop edge rules */
  .logo-wall__item:nth-child(4n) {
    border-right: 1px solid rgba(19, 19, 19, 0.1);
  }

  .logo-wall__item:nth-child(n + 5):nth-child(-n + 8) {
    border-bottom: 1px solid rgba(19, 19, 19, 0.1);
  }

  /* 3-col: every 3rd has no right border */
  .logo-wall__item:nth-child(3n) {
    border-right: none;
  }

  /* Bottom row of 6 (items 4–6) */
  .logo-wall__item:nth-child(n + 4):nth-child(-n + 6) {
    border-bottom: none;
  }

  [data-logo-wall-list] [data-logo-wall-item]:nth-child(n + 7) {
    display: none;
  }
}

/* Phone: 2 columns, show 6 logos */
@media screen and (max-width: 479px) {
  .logo-wall__item {
    width: 50%;
  }

  .logo-wall__item:nth-child(3n) {
    border-right: 1px solid rgba(19, 19, 19, 0.1);
  }

  .logo-wall__item:nth-child(n + 4):nth-child(-n + 6) {
    border-bottom: 1px solid rgba(19, 19, 19, 0.1);
  }

  /* 2-col: even items no right border */
  .logo-wall__item:nth-child(2n) {
    border-right: none;
  }

  /* Bottom row of 6 (items 5–6) */
  .logo-wall__item:nth-child(n + 5):nth-child(-n + 6) {
    border-bottom: none;
  }

  [data-logo-wall-list] [data-logo-wall-item]:nth-child(n + 7) {
    display: none;
  }

  .logo-wall__logo-target {
    width: 58%;
    height: 36%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .logo-wall__logo-target {
    will-change: auto;
  }
}
````

## Source — script.js
````javascript
/**
 * Logo Wall Cycle — premium bordered cells + blurred logo swaps
 *
 * How it works:
 * 1. Collect every logo target (visible + CSS-hidden pool).
 * 2. Place the first N into visible grid cells.
 * 3. On a loop, pick the next cell from a shuffled pattern and swap with a
 *    premium motion: vertical drift + fade + scale + gaussian blur dissolve.
 * 4. Outgoing logo returns to the pool so the wall cycles forever.
 * 5. Pauses when off-screen or when the tab is hidden.
 */

gsap.registerPlugin(ScrollTrigger);

function initLogoWallCycle() {
  const loopDelay = 1.65; // stillness between swaps
  const duration = 1.05; // premium swap duration
  const blurAmount = 18; // px peak blur during the handoff

  document.querySelectorAll("[data-logo-wall-cycle-init]").forEach((root) => {
    const list = root.querySelector("[data-logo-wall-list]");
    if (!list) return;

    const items = Array.from(list.querySelectorAll("[data-logo-wall-item]"));
    const shuffleFront = root.getAttribute("data-logo-wall-shuffle") !== "false";

    const originalTargets = items
      .map((item) => item.querySelector("[data-logo-wall-target]"))
      .filter(Boolean);

    let visibleItems = [];
    let visibleCount = 0;
    let pool = [];
    let pattern = [];
    let patternIndex = 0;
    let tl;

    function isVisible(el) {
      return window.getComputedStyle(el).display !== "none";
    }

    function shuffleArray(arr) {
      const a = arr.slice();
      for (let i = a.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [a[i], a[j]] = [a[j], a[i]];
      }
      return a;
    }

    /** Clear blur / motion props so pooled logos re-enter cleanly */
    function resetTarget(node) {
      gsap.set(node, {
        yPercent: 0,
        xPercent: 0,
        autoAlpha: 1,
        scale: 1,
        rotate: 0,
        "--logo-blur": 0,
      });
    }

    function setup() {
      if (tl) {
        tl.kill();
        tl = null;
      }

      items.forEach((item) => {
        item.querySelectorAll("[data-logo-wall-target]").forEach((node) => {
          gsap.killTweensOf(node);
        });
      });

      visibleItems = items.filter(isVisible);
      visibleCount = visibleItems.length;

      pattern = shuffleArray(Array.from({ length: visibleCount }, (_, i) => i));
      patternIndex = 0;

      items.forEach((item) => {
        item.querySelectorAll("[data-logo-wall-target]").forEach((old) => old.remove());
      });

      pool = originalTargets.map((n) => n.cloneNode(true));

      let front;
      let rest;

      if (shuffleFront) {
        const shuffledAll = shuffleArray(pool);
        front = shuffledAll.slice(0, visibleCount);
        rest = shuffleArray(shuffledAll.slice(visibleCount));
      } else {
        front = pool.slice(0, visibleCount);
        rest = shuffleArray(pool.slice(visibleCount));
      }

      pool = front.concat(rest);

      for (let i = 0; i < visibleCount; i++) {
        const parent =
          visibleItems[i].querySelector("[data-logo-wall-target-parent]") ||
          visibleItems[i];
        const target = pool.shift();
        resetTarget(target);
        parent.appendChild(target);
      }

      tl = gsap.timeline({
        repeat: -1,
        repeatDelay: loopDelay,
      });
      tl.call(swapNext);
      tl.play();
    }

    function swapNext() {
      const nowCount = items.filter(isVisible).length;
      if (nowCount !== visibleCount) {
        setup();
        return;
      }

      if (!pool.length) return;

      const idx = pattern[patternIndex % visibleCount];
      patternIndex += 1;

      const container = visibleItems[idx];
      const parent =
        container.querySelector("[data-logo-wall-target-parent]") ||
        container.querySelector("*:has(> [data-logo-wall-target])") ||
        container;

      const existing = parent.querySelectorAll("[data-logo-wall-target]");
      if (existing.length > 1) return;

      const current = parent.querySelector("[data-logo-wall-target]");
      const incoming = pool.shift();

      // Alternate subtle drift direction per swap for a more organic feel
      const dir = patternIndex % 2 === 0 ? 1 : -1;

      // Incoming starts soft-focused, slightly offset, smaller
      gsap.set(incoming, {
        yPercent: 42 * dir,
        autoAlpha: 0,
        scale: 0.88,
        "--logo-blur": blurAmount,
      });
      parent.appendChild(incoming);

      // Outgoing: dissolve with blur bloom + gentle scale
      if (current) {
        gsap.to(current, {
          yPercent: -38 * dir,
          autoAlpha: 0,
          scale: 1.08,
          "--logo-blur": blurAmount,
          duration,
          ease: "power3.inOut",
          onComplete: () => {
            current.remove();
            resetTarget(current);
            pool.push(current);
          },
        });
      }

      // Incoming: sharpen into place — slight delay for a continuous handoff
      gsap.to(incoming, {
        yPercent: 0,
        autoAlpha: 1,
        scale: 1,
        "--logo-blur": 0,
        duration,
        delay: 0.12,
        ease: "power3.out",
      });
    }

    setup();

    ScrollTrigger.create({
      trigger: root,
      start: "top bottom",
      end: "bottom top",
      onEnter: () => tl && tl.play(),
      onLeave: () => tl && tl.pause(),
      onEnterBack: () => tl && tl.play(),
      onLeaveBack: () => tl && tl.pause(),
    });

    document.addEventListener("visibilitychange", () => {
      if (!tl) return;
      document.hidden ? tl.pause() : tl.play();
    });

    let resizeTimer;
    window.addEventListener("resize", () => {
      clearTimeout(resizeTimer);
      resizeTimer = setTimeout(() => {
        const nowCount = items.filter(isVisible).length;
        if (nowCount !== visibleCount) {
          setup();
        }
      }, 150);
    });
  });
}

document.addEventListener("DOMContentLoaded", () => {
  initLogoWallCycle();
});
````
