<div include="form-input-select()">
<select required>
<!--
This is how we can do "placeholder" options.
note: "required" attribute is on the select
-->
<option value=""
hidden
>Example Placeholder</option>
<!-- normal options -->
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
<option value="4">Option 4</option>
<option value="5">Option 5</option>
</select>
</div>
// Demo Colors
$demo-blue: #005BA6;
$demo-gray: #D6D6D6;
$demo-placeholder: #C7C7C7;
$demo-border: #E6E6E6;
$border-width: 3px;
// Select function
@mixin form-input-select(){
// see https://codepen.io/jnowland/pen/KzYQxp for reset function
@include _select-form-reset;
color: $demo-blue;
display: block;
border-radius: 0;
box-shadow: none;
font-size: 16px;
// padding: 11px 15px;
margin-top: 9px;
margin-bottom: 15px;
width: 100%;
&::before,
&::after {
content: '';
display: block;
position: absolute;
pointer-events: none; // Arrow clickable in some browsers
// triangle set up
border: 1px solid transparent; // reset all borders
width: 0;
height: 0;
right: 16px;
}
// top arrow
&::before {
bottom: 55%;
border-width: 0 6.5px 8px 6.5px;
border-bottom-color: $demo-gray;
}
// bottom arrow
&::after {
border-width: 8px 6.5px 0 6.5px;
border-top-color: $demo-gray;
top: 55%;
}
// firefox is outside the div
@-moz-document url-prefix() {
border-right: $border-width solid $demo-border;
&:hover {
border-right: $border-width solid $demo-blue;
}
}
&:hover {
select {
box-shadow: 0 2px 3px rgba($demo-blue, 0.1) inset;
border-color: $demo-blue;
// outline is critical but when we are hovering the div has the border already.
&:focus {
outline-color: transparent;
}
}
&::before {
border-bottom-color: $demo-blue;
}
&::after {
border-top-color: $demo-blue;
}
}
// Make sure you set all padding, borders on this select and not the parent div.
// this is mainly for :focus and tabbing.
select {
border: $border-width solid $demo-border;
border-radius: 0;
font-weight: 400;
color: inherit;
padding: 11px 15px;
line-height: normal;
transition: border-color 0.2s ease,
outline 0.2s ease;
// we really need this for the tabbers
// causes double borders though
&:focus {
box-shadow: 0 3px 4px rgba($demo-blue, 0.3) inset;
// outline is critical for usability
outline: $border-width solid $demo-blue;
outline-offset: -#{$border-width}; //offset vs width
}
&[disabled], &:disabled{
opacity: 0.4;
cursor: not-allowed;
}
// we use invalid like a placeholder
// 2019-03-05 added not selector for firefox and ie
&:not(:focus):invalid {
color: $demo-placeholder;
}
}
}
// Show the function
[include*="form-input-select()"] {
@include form-input-select();
}
body {
display: flex;
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
border: 1em solid $demo-blue;
div {
max-width: 16em;
}
}
// begin spec stuff up
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
// end stuff up
View Compiled
// cross browser native select that has a placeholder styling
// The include="" selecor is just a way of documenting what functions do in scss lib
This Pen doesn't use any external JavaScript resources.