<div include="form-input-select()">
  <select required>
      This is how we can do "placeholder" options.
      note: "required" attribute is on the select
    <option value=""
    >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>

// 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%;

  &::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
Run Pen

External CSS

  1. https://codepen.io/jnowland/pen/KzYQxp.scss

External JavaScript

This Pen doesn't use any external JavaScript resources.