<div class="search-outer">
  <div class="search-inner">
    <div class="draggable"></div>
    <div class="avatars">
      <figure class="avatar">
        <img
             src="https://pbs.twimg.com/profile_images/953658232517652480/Xp0NB-TL.jpg"
             alt="Silvio Bompan"
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://images.pexels.com/photos/412840/pexels-photo-412840.jpeg?h=350&auto=compress&cs=tinysrgb"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://pbs.twimg.com/profile_images/984678118509109248/_lKShg6s.jpg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://images-na.ssl-images-amazon.com/images/M/MV5BMjA5MjI0MzY2MF5BMl5BanBnXkFtZTcwMzM3ODM3OA@@._V1_UX172_CR0,0,172,256_AL_.jpg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://images-na.ssl-images-amazon.com/images/M/MV5BMTMzNDY3NDQ3MV5BMl5BanBnXkFtZTcwODI3MTkyMQ@@._V1_UX172_CR0,0,172,256_AL_.jpg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://randomuser.me/api/portraits/women/79.jpg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://randomuser.me/api/portraits/women/39.jpg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://randomuser.me/api/portraits/women/84.jpg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://randomuser.me/api/portraits/women/99.jpg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://randomuser.me/api/portraits/women/20.jpg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://randomuser.me/api/portraits/women/71.jpg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://pbs.twimg.com/profile_images/1068045383606005761/VxDQx_gA.jpg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://randomuser.me/api/portraits/women/2.jpg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://tinyfac.es/data/avatars/B0298C36-9751-48EF-BE15-80FB9CD11143-500w.jpeg"
             alt=""
             />
      </figure>
      <figure class="avatar">
        <img
             src="https://pbs.twimg.com/profile_images/1056600329662459904/ukegoVAy.jpg"
             alt=""
             />
      </figure>
    </div>
  </div>
</div>
*,
*::after,
*::before {
  box-sizing: border-box;
}

:root {
  --search-box-height: 54px;
  --avatar-size: 44px;
  --bg-color: #d8d8d8;
  --color-white: #ffffff;
  --shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
}

body {
  background: var(--bg-color);
}

.search-outer {
  max-width: 500px;
  height: var(--search-box-height);
  margin: 100px auto 0 auto;
  position: relative;
  overflow-x: hidden;
  background: #fff;
  box-shadow: var(--shadow);
  border-radius: var(--search-box-height);
}

.search-inner {
  position: relative;
  top: 0;
  height: 100%;
  width: -moz-fit-content;
  width: fit-content;
}

.avatars {
  width: -moz-fit-content;
  width: fit-content;
  height: 100%;
  display: flex;
  align-items: center;
  position: relative;
  pointer-events: none;
}

.avatar {
  margin: 0px 5px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.avatar > img {
  width: var(--avatar-size);
  height: var(--avatar-size);
  border-radius: 100%;
  object-fit: cover;
}

.draggable {
  height: var(--search-box-height);
  top: calc(50% - calc(var(--search-box-height) / 2));
  width: 100%;
  position: absolute;
  cursor: grab;
}

.draggable:active {
  cursor: grabbing;
}
/* Inspired from:  https://github.com/codrops/DraggableImageStrip */

const lineEq = (y2, y1, x2, x1, currentVal) => {
  const m = (y2 - y1) / (x2 - x1),
    b = y1 - m * x1;
  return m * currentVal + b;
};

const lerp = (a, b, n) => (1 - n) * a + n * b;

class Avatars {
  constructor(el) {
    this.DOM = { el: el };
    this.DOM.avatars = this.DOM.el.querySelector(".avatars");
    this.DOM.draggable = this.DOM.el.querySelector(".draggable");
    this.containerWidth = this.DOM.el.offsetWidth;
    this.avatarsWidth = this.DOM.avatars.offsetWidth;
    this.draggableWidth = this.DOM.draggable.offsetWidth;
    this.maxDrag =
      this.avatarsWidth < this.containerWidth
        ? 0
        : this.avatarsWidth - this.containerWidth;
    // The current amount (in pixels) that was dragged
    this.dragPosition = 0;
    this.position = { previous: 0, current: 0 };
    this.draggie = new Draggabilly(this.DOM.draggable, { axis: "x" });
    this.initEvents();
    console.log("maxDrag", this.maxDrag);
    requestAnimationFrame(() => this.render());
  }

  render() {
    this.position.previous = lerp(
      this.position.previous,
      this.position.current,
      0.11
    );

    this.DOM.avatars.style.transform = `matrix(1, 0, 0, 1, ${this.position.previous}, 0)`;
    requestAnimationFrame(() => this.render());
  }

  initEvents() {
    this.onDragMove = (event, pointer, moveVector) => {
      if (this.draggie.position.x >= 0) {
        this.dragPosition = lineEq(
          0.5 * this.containerWidth,
          0,
          this.containerWidth,
          0,
          this.draggie.position.x
        );
      } else if (this.draggie.position.x < -1 * this.maxDrag) {
        this.dragPosition = lineEq(
          0.5 * this.containerWidth,
          0,
          this.maxDrag + this.containerWidth,
          this.maxDrag,
          this.draggie.position.x
        );
      } else {
        this.dragPosition = this.draggie.position.x;
      }
      this.position.current = this.dragPosition;
    };

    this.onDragEnd = () => {
      if (this.draggie.position.x > 0) {
        this.dragPosition = 0;
        this.draggie.setPosition(this.dragPosition, this.draggie.position.y);
      } else if (this.draggie.position.x < -1 * this.maxDrag) {
        this.dragPosition = -1 * this.maxDrag;
        this.draggie.setPosition(this.dragPosition, this.draggie.position.y);
      }
      this.position.current = this.dragPosition;
    };

    this.draggie.on("pointerDown", this.onDragStart);
    this.draggie.on("dragMove", this.onDragMove);
    this.draggie.on("pointerUp", this.onDragEnd);
  }
}

new Avatars(document.querySelector(".search-outer"));
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/draggabilly/2.3.0/draggabilly.pkgd.min.js