Skip to content

Gallery / hover / Card lift & border

Card lift & border

Card whose SVG border draws itself around it on hover

hover intermediate hovercardborderdraw
Live preview

Techniques: pathLength · stroke-dashoffset · transition-on-hover · preserveAspectRatio-none

Customizeupdates preview, code & clipboard
#7F77DD
220px
0.7s
Code snippets/hover/card-lift-border.html
<!--
  ============================================================
  SVGarden — https://www.svgarden.dev
  Author : Simon-Pierre Boucher
  Contact: contact@spboucher.ai
  File   : snippets/hover/card-lift-border.html
  Desc   : Card whose SVG border draws itself around it on hover
  ============================================================
-->
<div class="sg-card-lift-border" tabindex="0" style="--sg-color:#7F77DD; --sg-size:220px; --sg-duration:0.7s;">
  <svg viewBox="0 0 200 100" preserveAspectRatio="none" aria-hidden="true" focusable="false">
    <rect x="1" y="1" width="198" height="98" rx="8" pathLength="100" />
  </svg>
  <strong>Hover me</strong>
  <span>The border draws itself around the card, then un-draws on leave.</span>
</div>
<style>
  .sg-card-lift-border {
    position: relative;
    width: var(--sg-size);
    padding: 1.1rem 1.2rem;
    border-radius: 10px;
    background: rgba(127, 119, 221, 0.08);
    font-family: inherit;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    cursor: pointer;
    transition: transform var(--sg-duration) ease;
  }
  .sg-card-lift-border strong { font-size: 1rem; }
  .sg-card-lift-border span { font-size: 0.85rem; opacity: 0.75; }
  .sg-card-lift-border svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
  }
  .sg-card-lift-border rect {
    /* no non-scaling-stroke: Chromium computes dash patterns in screen space
       with it, which breaks the pathLength=100 normalization */
    fill: none;
    stroke: var(--sg-color);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-dasharray: 100 102;
    stroke-dashoffset: 101;
    transition: stroke-dashoffset var(--sg-duration) ease-in-out;
  }
  .sg-card-lift-border:hover,
  .sg-card-lift-border:focus-visible {
    transform: translateY(-4px);
  }
  .sg-card-lift-border:hover rect,
  .sg-card-lift-border:focus-visible rect {
    stroke-dashoffset: 0;
  }
</style>

More hover