DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report

Using Placeholders and Input Fields

A popular pattern in web design uses the input field, a placeholder that slides up on focus or while a user is typing. However, this can bring some challenges.

Artem Deikun user avatar by
Artem Deikun
·
Nadia Beregova user avatar by
Nadia Beregova
·
Nov. 14, 16 · Tutorial
Like (2)
Save
Tweet
Share
10.54K Views

Join the DZone community and get the full member experience.

Join For Free

A popular pattern in web design uses the input field, a placeholder that slides up on focus or while a user is typing. Different frameworks that are based on material design implement it in different ways, but each of them uses JavaScript to handle changes in the input field. Can we solve this problem with no JS code?

With CSS4-Selectors, we are ready to implement it just with CSS. This solution can involve framework agnostics.

So, Let’s Hype!

…and style it with variables, Level 4 selectors, and Bootstrap 4 Alpha.

Note: This solution works well in Chrome.

Where can you use it right now?

  • Chrome extensions.

  • An application on Cordova with integrated Chromium webview.

  • Developing desktop application on Electron.

Another note: The demo and code are available free to use right now in CodePen.

HTML Markup for Element

It’s not very pretty, but we have to include a label after the input in HTML because we can get access to the next sibling element in CSS, but not to the previous.

<label class='material-form-group'>
    <input type='text' placeholder='M'>
    <label>Regular input field</label>
</label>

Also, we need to set a placeholder attribute that must have text. It will help if there's some text in the input (unfortunately, :empty does not apply to input tags).

To use Bootstrap, we need to wrap it in framework’s classes:

<label class="form-group material-form-group">
    <input type="text" placeholder="M" class="form-control">
    <label>Regular input field</label>
</label>

This solution will work in Bootstrap version 3 and 4 well. (Thanks to developers that save class names the same.)

Dive Into CSS Code

Define the variables in :root. Follow some name conventions to isolate our variables with the prefix "mi" (material input).

:root {
    --mi-animation-speed: 0.314s;
    --mi-label-default-color: rgba(0, 0, 0, 0.314);
    --mi-indent-top: 15px;
    --mi-indent-left:12px;

    --mi-label-focus-color: dodgerblue;
    --mi-invalid-color: firebrick;
    --mi-bg-color: white; /* should match parent container color */
}

This is the main container relative to building our layout. Reserve some space above the container for the rising up label.

.material-form-group {
    margin-top: var(--mi-indent-top);
    position: relative;
}

Default styles of the label will be positioned on the top. This will be OK for browsers that can't support our main solution. Disable selecting the text of this element because if a user selects text in the label, the focus will not handle it.

.material-form-group label {
    position: absolute;
    transform-origin: 0 150%;
    margin-left: var(--mi-indent-left);
    transition: var(--mi-animation-speed);
    -webkit-user-select: none;
    user-select: none;
    color: var(--mi-label-default-color);
}

The selector input:placeholder-shown will detect that placeholder in the input field is shown. Then, we choose label next sibling to it. (If we had the functionality to choose the previous sibling label, we shouldn’t put label after input; it could be more semantic.)

.material-form-group input:placeholder-shown + label {
    top: 50%;
    transform: scale(1, 1) translateY(-50%);
    background: transparent;
}

Align the label vertically to the relative element with technic translateY and top:50% and it will not depend on itself or container heights. We need to have a placeholder in the layout, but it should be invisible. Hide it with transparent colour.

.material-form-group input::-webkit-input-placeholder {
    color: transparent;
}

Focus on typing the highlight input field.

.material-form-group input:focus + label {
    color: var(--mi-label-focus-color);
}

Style active state means that the input is focused or has no placeholder (the placeholder should be declared above this code). Move the label to the top and make it smaller.

.material-form-group input:focus + label,
.material-form-group label {
    top: -100%;
    transform: scale(0.8, 0.8) translateY(100%);
    background: var(--mi-bg-color);
}

We can finish here, but let’s style the field when it is invalid. Content in styles is not good practice, but the main goal is to solve this task with CSS only.

.material-form-group input:invalid + label:after {
    color: var(--mi-invalid-color);
    content: "(invalid)";
    margin-left: 0.314rem;
}

Summary

With time, CSS has become more accurate, can describe behavior concisely, and looks very handsome. Unfortunately, we can’t use it worldwide. My dream is to have tools like Babel in JavaScript to transform new CSS to cross-browser, but I think we can’t do without artificial intelligence.

Label

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • What Are the Different Types of API Testing?
  • Cloud Performance Engineering
  • OpenVPN With Radius and Multi-Factor Authentication
  • MongoDB Time Series Benchmark and Review

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: