SPB Git

Repository Public

password-eye-blink.html 4.9 KB 141 lines html

1<!--2  ============================================================3  SVGarden — https://www.svgarden.dev4  Author : Simon-Pierre Boucher5  Contact: contact@spboucher.ai6  File   : snippets/interactive/password-eye-blink.html7  Desc   : Show/hide password field whose eye icon blinks when toggled8  ============================================================9-->10<!--svgarden11title: Password eye blink12slug: password-eye-blink13category: interactive14tags: [interactive, password, toggle, checkbox, form]15difficulty: intermediate16techniques: [":checked", sibling-combinator, scaleY-blink, crossfade, ":focus-visible"]17how_it_works: >18  A hidden checkbox placed *before* the field holds the shown/hidden state, so19  everything after it is reachable with the general sibling combinator — the20  CSS-only pattern for "one control drives many elements". The field stacks21  two spans (dots and plain text) and :checked crossfades between them, while22  the slash over the eye fades away. The blink is the fun part: the eye group23  runs a scaleY squeeze keyframe that only exists under the :checked selector,24  and because the selector starts matching at the moment you toggle, the25  animation restarts precisely then — CSS animations as event handlers.26customizable:27  - { var: "--sg-color",    label: "Accent", type: color, default: "#7F77DD" }28  - { var: "--sg-size",     label: "Width",  type: range, min: 180, max: 380, default: 250, unit: px }29  - { var: "--sg-duration", label: "Speed",  type: range, min: 0.15, max: 0.9, step: 0.05, default: 0.4, unit: s }30created: 2026-08-1031-->32<div class="sg-password-eye-blink" style="--sg-color:#7F77DD; --sg-size:250px; --sg-duration:0.4s;">33  <input type="checkbox" id="sg-password-eye-blink-cb" class="sg-password-eye-blink-cb" />34  <div class="sg-password-eye-blink-field">35    <span class="sg-password-eye-blink-text">36      <span class="sg-password-eye-blink-dots" aria-hidden="true">••••••••</span>37      <span class="sg-password-eye-blink-plain">hunter2!</span>38    </span>39    <label for="sg-password-eye-blink-cb" class="sg-password-eye-blink-eye" aria-label="Show password">40      <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">41        <g class="sg-password-eye-blink-ball">42          <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" />43          <circle cx="12" cy="12" r="3.2" />44        </g>45        <line class="sg-password-eye-blink-slash" x1="4.5" y1="19.5" x2="19.5" y2="4.5" />46      </svg>47    </label>48  </div>49</div>50<style>51  .sg-password-eye-blink {52    width: var(--sg-size);53    font-family: inherit;54  }55  .sg-password-eye-blink-cb {56    position: absolute;57    opacity: 0;58    width: 1px;59    height: 1px;60  }61  .sg-password-eye-blink-field {62    display: flex;63    align-items: center;64    gap: 0.6rem;65    border: 1px solid rgba(128, 128, 128, 0.45);66    border-radius: 10px;67    padding: 0.6rem 0.75rem;68  }69  .sg-password-eye-blink-text {70    position: relative;71    flex: 1;72    font-family: ui-monospace, Menlo, monospace;73    font-size: 0.95rem;74    letter-spacing: 0.06em;75    min-height: 1.3em;76  }77  .sg-password-eye-blink-dots,78  .sg-password-eye-blink-plain {79    position: absolute;80    left: 0;81    top: 50%;82    translate: 0 -50%;83    transition: opacity var(--sg-duration) ease, translate var(--sg-duration) ease;84  }85  .sg-password-eye-blink-plain {86    opacity: 0;87    translate: 0 calc(-50% + 5px);88  }89  .sg-password-eye-blink-eye {90    width: 1.5em;91    cursor: pointer;92    display: block;93    flex: none;94  }95  .sg-password-eye-blink-eye svg {96    display: block;97    width: 100%;98    overflow: visible;99  }100  .sg-password-eye-blink-ball {101    transform-box: fill-box;102    transform-origin: center;103  }104  .sg-password-eye-blink-ball path {105    fill: none;106    stroke: rgba(128, 128, 128, 0.8);107    stroke-width: 1.8;108  }109  .sg-password-eye-blink-ball circle {110    fill: var(--sg-color);111  }112  .sg-password-eye-blink-slash {113    stroke: rgba(128, 128, 128, 0.8);114    stroke-width: 1.8;115    stroke-linecap: round;116    transition: opacity var(--sg-duration) ease;117  }118  .sg-password-eye-blink-cb:checked ~ .sg-password-eye-blink-field .sg-password-eye-blink-dots {119    opacity: 0;120    translate: 0 calc(-50% - 5px);121  }122  .sg-password-eye-blink-cb:checked ~ .sg-password-eye-blink-field .sg-password-eye-blink-plain {123    opacity: 1;124    translate: 0 -50%;125  }126  .sg-password-eye-blink-cb:checked ~ .sg-password-eye-blink-field .sg-password-eye-blink-slash {127    opacity: 0;128  }129  .sg-password-eye-blink-cb:checked ~ .sg-password-eye-blink-field .sg-password-eye-blink-ball {130    animation: sg-password-eye-blink-wink calc(var(--sg-duration) * 1.4) ease;131  }132  .sg-password-eye-blink-cb:focus-visible ~ .sg-password-eye-blink-field {133    outline: 2px solid var(--sg-color);134    outline-offset: 2px;135  }136  @keyframes sg-password-eye-blink-wink {137    0%, 100% { transform: scaleY(1); }138    45%      { transform: scaleY(0.08); }139  }140</style>141
Files main
Menu

Theme