Discord Search Bar

by Sebastian Kay

HTML

<div class="row">
      <div class="box"></div>
      <div class="box"></div>

      <div class="search-wrapper">
        <input class="input" type="search" placeholder="Search" />
        <svg
          xmlns="http://www.w3.org/2000/svg"
          fill="none"
          viewBox="0 0 24 24"
          class="search-icon"
        >
          <path
            fill="currentColor"
            fill-rule="evenodd"
            d="M15.62 17.03a9 9 0 1 1 1.41-1.41l4.68 4.67a1 1 0 0 1-1.42 1.42l-4.67-4.68ZM17 10a7 7 0 1 1-14 0 7 7 0 0 1 14 0Z"
            clip-rule="evenodd"
          ></path>
        </svg>
        <button class="x-icon">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            fill="none"
            viewBox="0 0 24 24"
          >
            <path
              fill="currentColor"
              d="M17.3 18.7a1 1 0 0 0 1.4-1.4L13.42 12l5.3-5.3a1 1 0 0 0-1.42-1.4L12 10.58l-5.3-5.3a1 1 0 0 0-1.4 1.42L10.58 12l-5.3 5.3a1 1 0 1 0 1.42 1.4L12 13.42l5.3 5.3Z"
            ></path>
          </svg>
        </button>
      </div>

      <div class="box"></div>
    </div>

CSS

:root {
  --bg-color: hsl(223, 6.7%, 20.6%);
  --bg-color-dark: hsl(225, 6.3%, 12.5%);
  --foreground-color: hsl(210, 9.1%, 87%);
  --foreground-color-dark: hsl(214, 8.1%, 61.2%);
  --outline-color: hsl(200, 100%, 50%);
}

body {
  background-color: var(--bg-color);
  color: var(--foreground-color);
  font-family: Helvetica, Arial, sans-serif;
  margin: 0;
}

.row {
  display: flex;
  gap: 1rem;
  margin: 1rem;
  margin-top: 2rem;
}

.box {
  width: 30px;
  background-color: var(--foreground-color-dark);
}

.input {
  background-color: var(--bg-color-dark);
  color: var(--foreground-color);
  border: none;
  width: 9em;
  transition: width 0.25s;
  outline: none;
  border-radius: 0.25em;
  padding: 0.375em;
  font-size: 0.875em;
}

@media (prefers-reduced-motion: reduce) {
  .input {
    transition: none;
  }
}

.input::placeholder {
  color: var(--foreground-color-dark);
}

.input:focus-visible,
button:focus-visible {
  box-shadow: 0 0 0 0.25rem var(--outline-color);
}

.input:focus,
.input:not(:placeholder-shown) {
  width: 15em;
}

.search-wrapper {
  position: relative;
}

.search-icon,
.x-icon {
  position: absolute;
  width: 1rem;
  height: 1rem;
  right: 0.25rem;
  top: 50%;
  translate: 0 -50%;
  color: var(--foreground-color-dark);
  opacity: 0;
  rotate: 90deg;
  pointer-events: none;
  visibility: hidden;
  border-radius: 0.25rem;
  transition-behavior: discrete;
  transition-property: opacity, rotate, visibility;
  transition-duration: 0.15s;
}

.search-wrapper:has(.input:placeholder-shown) .search-icon,
.search-wrapper:has(.input:not(:placeholder-shown)) .x-icon {
  opacity: 1;
  pointer-events: all;
  rotate: 0deg;
  visibility: visible;
}

button {
  all: unset;
  cursor: pointer;
}

/* clears the ‘X’ from Internet Explorer */
input[type="search"]::-ms-clear,
input[type="search"]::-ms-reveal {
  appearance: none;
  width: 0;
  height: 0;
}

/* clears the ‘X’ from Chrome...