Skip to content

Instantly share code, notes, and snippets.

@rejas
Last active August 29, 2015 14:04
Show Gist options
  • Save rejas/bee6b7a39b8ef54f493a to your computer and use it in GitHub Desktop.
Save rejas/bee6b7a39b8ef54f493a to your computer and use it in GitHub Desktop.
less-mixin for input placeholders becoming input labels.
/**
* As seen on http://blog.circleci.com/adaptive-placeholders/
* featured on LittleBigDetails
* http://littlebigdetails.com/post/82478225432/
*/
// First, pass in the important variables.
.adaptive_placeholder(@height, @radius, @margin: 1em, @border: 1px) {
@borders: (@border * 2); // <- To avoid repeating below
box-sizing: border-box; // <- Important for accurate sizing
width: 100%; // <- Could be almost anything
// Our LESS version can't calculate following w/o 'calc'
height: ~"calc(@{height} + @{borders})";
margin: 0 0 @margin;
padding: @margin;
border: @border solid #ccc;
border-radius: @radius;
background: #fff;
resize: none; // <- For textareas
outline: none; // <- Because ugly
//
// Following block controls all the color change
//
&[required] {
&:focus {
border-color: #00bafa;
+ label {
&[placeholder] {
&:before {
color: #00bafa;
}
}
}
}
//
// Following block selects label directly adjacent to input
//
&:focus,
&:valid {
+ label {
&[placeholder] {
&:before {
transition-duration: .2s;
//
// Following lines move placeholder out of the way
//
transform: translate(0, (@margin * -1.5)) scale(.9, .9);
}
}
}
}
//
// Following block injects string from label's 'alt' attr.
// It comes before the other 'content' property so I can
// override it. Uses "invalid" pseudo-selector to know
// when to do that.
//
&:invalid {
+ label {
&[placeholder] {
&[alt] {
&:before {
content: attr(alt); // Content property 1 of 2
}
}
}
}
}
+ label {
&[placeholder] {
display: block;
pointer-events: none; // Allows clicking thru label
line-height: @margin;
// Following pulls label into position
margin-top: ~"calc(-@{height} - @{borders})";
// Following offsets that above
margin-bottom: ~"calc((@{height} - @{margin}) + @{borders})";
//
// Following ':before' is needed to switch between
// different strings.
//
&:before {
content: attr(placeholder); // Content property 2 of 2
display: inline-block;
margin: 0 ~"calc(@{margin} + @{borders})";
padding: 0 2px;
color: #898989;
white-space: nowrap;
transition: .3s ease-in-out;
//
// Following lines lets me use solid color as bkg img.
// This lets me size bkg to something more sublte
//
background-image: linear-gradient(to bottom, #fff, #fff);
background-size: 100% 5px;
background-repeat: no-repeat;
background-position: center;
}
}
}
}
}
//
// Following block is how I call the above function
//
input {
@height: 3em;
&[type="text"] {
.adaptive_placeholder(@height, (@height / 2));
}
}
//
// For Demo Only
//
html {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
// HAML
// %form
// %input{type: "text", required: ""}
// %label{placeholder: "Adaptive Placeholder", alt: "Placeholder"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment