Skip to content

Instantly share code, notes, and snippets.

@kogakure
Created December 28, 2016 21:31
Show Gist options
  • Save kogakure/c4a536ed52666a3d9341c17ed71c251a to your computer and use it in GitHub Desktop.
Save kogakure/c4a536ed52666a3d9341c17ed71c251a to your computer and use it in GitHub Desktop.
Inline SVG Demo 2
<main class="Demo bg-image">
<div class="Modal">
<h2>Sign In</h2>
<form class="Form">
<label class="Label">
<input class="Input" type="text"
placeholder="Username" name="username"
required minlength="4">
<svg viewBox="0 0 20 20" class="Icon">
<path d="M0 0 L10 10 L0 20"></path>
</svg>
<svg class="Line" viewBox="0 0 40 2"
preserveAspectRatio="none">
<path d="M0 1 L40 1"/>
<path d="M0 1 L40 1" class="focus"/>
<path d="M0 1 L40 1" class="invalid"/>
<path d="M0 1 L40 1" class="valid"/>
</svg>
</label>
<label class="Label">
<input class="Input" type="password"
placeholder="Password" name="password"
required minlength="8">
<svg viewBox="0 0 20 20" class="Icon">
<path d="M0 0 L10 10 L0 20"></path>
</svg>
<svg class="Line" viewBox="0 0 40 2"
preserveAspectRatio="none">
<path d="M0 1 L40 1"/>
<path d="M0 1 L40 1" class="focus"/>
<path d="M0 1 L40 1" class="invalid"/>
<path d="M0 1 L40 1" class="valid"/>
</svg>
</label>
<button class="Button" type="submit">
Sign in
</button>
</form>
</div>
</main>
/* Delay visual feedback for invalid form items
until initial submit or blur event */
Array.from(document.querySelectorAll('.Form input')).forEach(i => {
i.addEventListener('invalid', () => {
i.dataset.touched = true
})
i.addEventListener('blur', () => {
if (i.value !== '') i.dataset.touched = true
})
})
.Form {
display: flex;
flex-direction: column;
align-items: center;
}
h2 {
margin: 0 0 1rem;
line-height: 1;
}
.Form > * + * {
margin-top: 1.5rem;
}
.Button {
font-size: 1rem;
background: none;
border: 1px solid #ccc;
padding: 0.5em 1em;
border-radius: 0.25rem;
cursor: pointer;
}
.Button:focus {
outline: none;
border-color: black;
box-shadow: 0 0 12px -4px black;
}
.Label {
width: 100%;
max-width: 20em;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.Input {
flex-grow: 1;
box-sizing: border-box;
font-size: 1rem;
font-weight: 300;
display: block;
margin: 0;
border: none;
padding: 0.5em 0;
line-height: 1;
transition: border-color 0.2s;
}
.Input:focus {
outline: none;
}
.Icon {
width: 1rem;
order: -1;
transition: all 0.2s;
stroke-dasharray: 0, 20;
stroke-dashoffset: -14.142;
}
.Icon path {
stroke: black;
stroke-width: 2px;
fill: none;
}
.Input:focus + .Icon {
stroke-dasharray: 28.284, 20;
stroke-dashoffset: 0;
}
.Line {
width: 100%;
height: 2px;
stroke: hsl(0, 0%, 75%);
stroke-width: 2px;
margin-left: 1rem;
}
.Line .focus,
.Line .valid,
.Line .invalid {
transition: all 0.2s;
stroke-dasharray: 0, 20;
stroke-dashoffset: -20;
}
.Line .focus {
stroke: black;
}
.Line .valid {
stroke: hsl(166, 72%, 40%);
}
.Line .invalid {
stroke: hsl(0, 100%, 40%);
}
.Input:focus ~ .Line .focus,
.Input:valid ~ .Line .valid,
.Input[data-touched]:invalid ~ .Line .invalid {
stroke-dasharray: 40, 0;
stroke-dashoffset: 0;
}
<link href="http://codepen.io/geelen/pen/BzgkEw" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment