Animated input
//
// Animated input
//
// Structure:
// <div>
// <input>
// <label>
// <svg>
// <span>
// <div.validation> (optional)
$label_offset: 2.6em;
$label_offset_small: 2.6em;
$label_scale: .81;
@mixin label__animated(
$size: 'large',
$color: $color_secondary,
$error_color: $color_primary
) {
// .input
display: inline-block;
@if $size == 'small' {
margin-bottom: 1.6em;
} @else {
margin-bottom: 2em;
}
position: relative;
vertical-align: top;
width: 100%;
z-index: 1;
&:last-of-type {
margin-bottom: 0;
}
&.is--disabled {
pointer-events: none;
}
&.is--filled {
label {
cursor: default;
pointer-events: none;
}
svg {
stroke-dashoffset: 0;
}
.label {
opacity: 1;
@if $size == 'small' {
@include vendor_prefix(
transform,
scale3d($label_scale, $label_scale, 1) translate3d(0, $label_offset_small, 0)
);
} @else {
@include vendor_prefix(
transform,
scale3d($label_scale, $label_scale, 1) translate3d(0, $label_offset, 0)
);
}
}
}
// .input__field
input {
background: transparent;
border: 0;
border-radius: 0;
color: $color;
display: block;
float: right;
@if $size == 'small' {
padding: .4em .8em;
} @else {
padding: .8em;
}
position: relative;
width: 100%;
// for iOS box shadows
-webkit-appearance: none;
// Not sure why this is needed...
&[type=email] {
width: calc(107.5% - 1.6em);
}
&:focus {
outline: none;
+ label {
cursor: default;
pointer-events: none;
// scss-lint:disable NestingDepth
svg {
stroke-dashoffset: 0;
}
.label {
opacity: 1;
@if $size == 'small' {
@include vendor_prefix(
transform,
scale3d($label_scale, $label_scale, 1) translate3d(0, $label_offset_small, 0)
);
} @else {
@include vendor_prefix(
transform,
scale3d($label_scale, $label_scale, 1) translate3d(0, $label_offset, 0)
);
}
}
// scss-lint:enable NestingDepth
}
}
}
// .input__label
label {
@include vendor_prefix(
user-select,
none
);
@include vendor_prefix(
touch-callout,
none
);
color: $color;
cursor: text;
display: inline-block;
height: 100%;
padding: 0 1em;
position: absolute;
text-align: left;
text-transform: capitalize;
width: 100%;
// scss-lint:disable VendorPrefix
-webkit-font-smoothing : antialiased;
-moz-osx-font-smoothing : grayscale;
// scss-lint:enable VendorPrefix
}
// .graphic
svg {
@include vendor_prefix(
transform,
scale3d(1, -1, 1)
);
@include vendor_prefix(
transition,
stroke-dashoffset .3s
);
pointer-events: none;
position: absolute;
left: 0;
top: 0;
fill: none;
stroke: $color;
stroke-width: 4px;
stroke-dasharray: 962;
stroke-dashoffset: 558;
}
// .input__label-content
.label {
@include vendor_prefix(
transform-origin,
0% 50%
);
@include custom_transition();
display: block;
opacity: .6;
@if $size == 'small' {
padding: .1em 0;
} @else {
padding: 1em 0;
}
position: relative;
width: 100%;
}
.validation {
color: $error_color;
font-size: 12px;
line-height: 1em;
padding: 0;
position: absolute;
right: 0;
top: calc(100% + 8px);
text-align: right;
p {
margin: 0;
}
}
}
<div
class="account__input--animated"
data-ng-class="{ 'is--filled': vm.newEmail.length > 0 }"
>
<input
id="email"
name="email"
type="email"
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
data-ng-model="vm.newEmail"
data-ng-change="vm.validateEmail(vm.newEmail)"
>
<label for="email">
<svg width="100%" height="100%" viewBox="0 0 404 77" preserveAspectRatio="none">
<path d="m0,0l404,0l0,77l-404,0l0,-77z"></path>
</svg>
<span class="label">Email address</span>
</label>
</div>