Skip to content

Gallery / interactive / Password eye blink

Password eye blink

Show/hide password field whose eye icon blinks when toggled

interactive intermediate interactivepasswordtogglecheckboxform
Live preview

Techniques: :checked · sibling-combinator · scaleY-blink · crossfade · :focus-visible

Customizeupdates preview, code & clipboard
#7F77DD
250px
0.4s
Code snippets/interactive/password-eye-blink.html
<!--
  ============================================================
  SVGarden — https://www.svgarden.dev
  Author : Simon-Pierre Boucher
  Contact: contact@spboucher.ai
  File   : snippets/interactive/password-eye-blink.html
  Desc   : Show/hide password field whose eye icon blinks when toggled
  ============================================================
-->
<div class="sg-password-eye-blink" style="--sg-color:#7F77DD; --sg-size:250px; --sg-duration:0.4s;">
  <input type="checkbox" id="sg-password-eye-blink-cb" class="sg-password-eye-blink-cb" />
  <div class="sg-password-eye-blink-field">
    <span class="sg-password-eye-blink-text">
      <span class="sg-password-eye-blink-dots" aria-hidden="true">••••••••</span>
      <span class="sg-password-eye-blink-plain">hunter2!</span>
    </span>
    <label for="sg-password-eye-blink-cb" class="sg-password-eye-blink-eye" aria-label="Show password">
      <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <g class="sg-password-eye-blink-ball">
          <path d="M2.5 12 C 6.5 5.5, 17.5 5.5, 21.5 12 C 17.5 18.5, 6.5 18.5, 2.5 12 Z" />
          <circle cx="12" cy="12" r="3.2" />
        </g>
        <line class="sg-password-eye-blink-slash" x1="4.5" y1="19.5" x2="19.5" y2="4.5" />
      </svg>
    </label>
  </div>
</div>
<style>
  .sg-password-eye-blink {
    width: var(--sg-size);
    font-family: inherit;
  }
  .sg-password-eye-blink-cb {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
  }
  .sg-password-eye-blink-field {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    border: 1px solid rgba(128, 128, 128, 0.45);
    border-radius: 10px;
    padding: 0.6rem 0.75rem;
  }
  .sg-password-eye-blink-text {
    position: relative;
    flex: 1;
    font-family: ui-monospace, Menlo, monospace;
    font-size: 0.95rem;
    letter-spacing: 0.06em;
    min-height: 1.3em;
  }
  .sg-password-eye-blink-dots,
  .sg-password-eye-blink-plain {
    position: absolute;
    left: 0;
    top: 50%;
    translate: 0 -50%;
    transition: opacity var(--sg-duration) ease, translate var(--sg-duration) ease;
  }
  .sg-password-eye-blink-plain {
    opacity: 0;
    translate: 0 calc(-50% + 5px);
  }
  .sg-password-eye-blink-eye {
    width: 1.5em;
    cursor: pointer;
    display: block;
    flex: none;
  }
  .sg-password-eye-blink-eye svg {
    display: block;
    width: 100%;
    overflow: visible;
  }
  .sg-password-eye-blink-ball {
    transform-box: fill-box;
    transform-origin: center;
  }
  .sg-password-eye-blink-ball path {
    fill: none;
    stroke: rgba(128, 128, 128, 0.8);
    stroke-width: 1.8;
  }
  .sg-password-eye-blink-ball circle {
    fill: var(--sg-color);
  }
  .sg-password-eye-blink-slash {
    stroke: rgba(128, 128, 128, 0.8);
    stroke-width: 1.8;
    stroke-linecap: round;
    transition: opacity var(--sg-duration) ease;
  }
  .sg-password-eye-blink-cb:checked ~ .sg-password-eye-blink-field .sg-password-eye-blink-dots {
    opacity: 0;
    translate: 0 calc(-50% - 5px);
  }
  .sg-password-eye-blink-cb:checked ~ .sg-password-eye-blink-field .sg-password-eye-blink-plain {
    opacity: 1;
    translate: 0 -50%;
  }
  .sg-password-eye-blink-cb:checked ~ .sg-password-eye-blink-field .sg-password-eye-blink-slash {
    opacity: 0;
  }
  .sg-password-eye-blink-cb:checked ~ .sg-password-eye-blink-field .sg-password-eye-blink-ball {
    animation: sg-password-eye-blink-wink calc(var(--sg-duration) * 1.4) ease;
  }
  .sg-password-eye-blink-cb:focus-visible ~ .sg-password-eye-blink-field {
    outline: 2px solid var(--sg-color);
    outline-offset: 2px;
  }
  @keyframes sg-password-eye-blink-wink {
    0%, 100% { transform: scaleY(1); }
    45%      { transform: scaleY(0.08); }
  }
</style>

More interactive