Modern browsers use a Shadow DOM to facilitate input of dates and datetimes. As a result, placeholder text is not shown unless the browser chooses to fallback to a text
input for whatever reason. You can accommodate both scenarios with the following logic:
::-webkit-calendar-picker-indicator {
@apply hidden; /* hide native picker icon */
}
input[type^='date']:not(:placeholder-shown) {
@apply before:content-[attr(placeholder)];
@apply sm:after:content-[attr(placeholder)] sm:before:hidden;
}
input[type^='date']::after,
input[type^='date']::before {
@apply text-gray-500;
}
I've used Tailwind CSS syntax because it's easy to grok. Let's break it down piece by piece:
::-webkit-calendar-picker-indicator {
@apply hidden; /* hide native picker icon */
}
Hide native picker icon (generally a calendar) using its Shadow DOM pseudo-element selector.
input[type^='date']:not(:placeholder-shown) {
@apply before:content-[attr(placeholder)];
@apply sm:after:content-[attr(placeholder)] sm:before:hidden;
}
Select all date
and datetime-local
inputs where placeholder is not shown and:
- Show the input
placeholder
text using the ::before
pseudo-element by default
- On small screens and above switch to using the
::after
pseudo-element instead
input[type^='date']::after,
input[type^='date']::before {
@apply text-gray-500;
}
Style the ::before
and ::after
pseudo-elements.