Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

HTML

              
                <!-- Inspired to make http://nostyle.herokuapp.com/components more accessible (using autcomplete values to identify input purposes) and mobile friendly (using autocapitalize for proper nouns and postcodes) -->
<div class="pageContent">
  <h1>Personal details</h1>

  <!-- Avoid browser spell checking inputs (whose type attributes are in the Text, Search, URL, or E-mail states) with spellcheck="false" https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/spellcheck on individual input elements or inherit via setting in the parent form element -->
  <!-- Any field that expects a proper name (such as first, last, or city name) can also be problematic with autocorrect enabled. According to https://uxcellence.com/2014/tweaking-automatic-form-input this attribute can be set on input elements or for the whole form -->
  <form novalidate spellcheck="false" autocorrect="off">

    <div class="field">
      <label for="salutation">
        <span class="field-label">Title (optional)</span>
        <span class="field-hint" aria-hidden="true">eg Dr or Prof</span>
        <span class="sr-only">For example, Doctor or Professor</span>
      </label>
      <input name="salutation" id="salutation" autocomplete="honorific-prefix" type="text" data-width="12ch">
    </div>

    <div class="field">
      <!-- Use an icon with each error message so: Color is not the only means of conveying information. WCAG 1.4.1 Use of Color - Level A https://www.w3.org/WAI/WCAG21/quickref/#qr-visual-audio-contrast-without-color
-->
      <label for="firstName">
        <span class="field-label">Given name</span>
        <span class="field-error">
          <i class="fas fa-exclamation-circle" title="Error: "></i>
          Enter your given name</span>
      </label>
      <input name="firstName" id="firstName" autocomplete="given-name" autocorrect="off" type="text" required aria-invalid="true">
      <!-- Include autocorrect="off" because it is enabled by default, and any field that expects a proper name (such as first, last, or city name) can be problematic with autocorrect enabled - See https://uxcellence.com/2014/tweaking-automatic-form-input -->
      <!-- Include autocapitalize="words" to make a virtual keyboard automatically uppercase the first letter of each word. This can ease entering multi-word proper nouns on mobile. See https://developers.google.com/web/updates/2015/04/autocapitalize -->
    </div>

    <div class="field">
      <label for="lastName">
        <span class="field-label">Family name</span>
        <span class="field-error">
          <i class="fas fa-exclamation-circle" title="Error: "></i>
          Enter your family name</span>
      </label>
      <input name="lastName" id="lastName" autocomplete="family-name" autocorrect="off" type="text" required aria-invalid="true">
      <!-- Include autocorrect="off" because it is enabled by default, and any field that expects a proper name (such as first, last, or city name) can be problematic with autocorrect enabled - See https://uxcellence.com/2014/tweaking-automatic-form-input -->
      <!-- Include autocapitalize="words" should make a virtual keyboard automatically uppercase the first letter of each word. It's buggy. This can ease entering multi-word proper nouns on mobile. See https://developers.google.com/web/updates/2015/04/autocapitalize -->
    </div>

    <div class="field">
      <!-- https://design-system.service.gov.uk/patterns/email-addresses/#if-the-email-address-is-not-in-the-correct-format-and-there-is-no-example -->
      <label for="email_address">
        <span class="field-label">Email</span>
        <span class="field-hint">A payment receipt will be sent to your email address.</span>
        <span class="field-error">
          <i class="fas fa-exclamation-circle" title="Error: "></i>
          Enter an email address in the correct format, like name@example.com</span>
      </label>
      <input name="email_address" id="email_address" autocomplete="email" type="email" required aria-invalid="true">
    </div>

    <div class="field-checkbox">
      <input id="enewsletter" value="1" name="enewsletter" type="checkbox" checked>
      <label for="enewsletter">
        <span class="field-label">Sign up for enewsletters (optional)</span>
      </label>
    </div>

    <div class="field">
      <label for="primary_phone">
        <span class="field-label">Phone</span>
        <span class="field-hint">For international numbers include the country code</span>
        <span class="field-error">
          <i class="fas fa-exclamation-circle" title="Error: "></i>
          Enter your phone number</span>
      </label>
      <input name="primary_phone" id="primary_phone" autocomplete="tel" type="tel" maxlength="12" required aria-invalid="true">
    </div>

    <!-- Several address fields warrant grouping with a fieldset https://design-system.service.gov.uk/components/fieldset/ -->
    <fieldset>
      <legend>
        <h2>Your address</h2>
        <span class="field-hint">Why we ask your address ...</span>
      </legend>
      <div class="field">
        <label for="address_line1">
          <span class="field-label">Address line 1 (optional)</span>
        </label>
        <input name="address_line1" id="address_line1" autocomplete="address-line1" type="text">
      </div>

      <div class="field">
        <label for="address_line2">
          <span class="field-label">Address line 2 (optional)</span>
        </label>
        <input name="address_line2" id="address_line2" autocomplete="address-line2" type="text">
      </div>

      <div class="field">
        <label for="address_town">
          <span class="field-label">Suburb/town (optional)</span>
        </label>
        <input name="address_town" id="address_town" autocomplete="address-level2" type="text" class="width-two-thirds">
      </div>

      <div class="field">
        <label for="address_state">
          <span class="field-label">State (optional)</span>
        </label>
        <input name="address_state" id="address_state" autocomplete="address-level1" type="text" class="width-two-thirds">
      </div>

      <div class="field">
        <label for="postcode_stats">
          <span class="field-label">Postcode (optional)</span>
        </label>
        <input name="postcode_stats" id="postcode_stats" autocomplete="postal-code" type="text" maxlength="10" autocapitalize="characters">
      </div>

      <!-- In our case, country is not needed. If needed, check out: -->
      <!-- https://gist.github.com/danrovito/977bcb97c9c2dfd3398a -->
      <!-- http://nostyle.herokuapp.com/components/autocomplete -->

    </fieldset>

    <!-- The aria-invalid="true" attribute is placed on the fieldset. Putting it directly on the radio button would be incorrect here, because it’s not the individual input that’s invalid — it’s the group. A Flight Booking Form in Form Design Patterns by Adam Silver. -->
    <fieldset aria-invalid="true" aria-describedby="radio_error_1">
      <!-- Fieldsets that contain radios need a programmatic association. https://russmaxdesign.github.io/accessible-error-fieldset/index.html -->
      <legend>
        <h2>Fieldset with heading in legend</h2>
        <span class="field-hint">Hint: This fieldset contains radios ...</span>
        <span class="field-error" id="radio_error_1">
          <i class="fas fa-exclamation-circle" title="Error: "></i>
          Accessible error message associated with fieldset</span>
      </legend>
      <div class="field radios">
        <div class="field-radio">
          <input id="anonymous_radio_donation_2" value="2" name="anonymous_radio_donation" type="radio">
          <label for="anonymous_radio_donation_2">
            <span class="field-label">Radio ga-ga</span>
            <span class="field-hint">All we hear is ...</span>
          </label>
        </div>
        <div class="field-radio">
          <input id="anonymous_radio_donation_1" value="1" name="anonymous_radio_donation" type="radio">
          <label for="anonymous_radio_donation_1">
            <span class="field-label">Radio goo-goo</span>
            <span class="field-hint">I heard it on my radio.</span>
          </label>
        </div>
      </div>
    </fieldset>

    <div class="field-checkbox">
      <input id="anonymous_donation" value="1" name="anonymous_donation" type="checkbox" checked>
      <label for="anonymous_donation">
        <span class="field-label">Anonymous donation (optional)</span>
        <span class="field-hint">Your donation will be marked as anonymous and will not appear in any public communications.</span>
      </label>
    </div>

    <button type="submit" class="primaryButton" name="save_continue">Save and continue</button>

  </form>
</div>
              
            
!

CSS

              
                * {
  margin: 0;
  padding: 0;
}
/* Check for colour-only indicators with a greyscale filter. At https://youtu.be/Wq2-cZ-vZBc?t=11m24s Julie Grundy describes how she uses a grayscale filter to check for colour-only indicators. 

body {
  filter: grayscale(100%);
}
/**/
.pageContent {
  padding: 20px 10px;
}

/* Text fields to support WCAG 2.1 Success Criterion 1.4.12: Text Spacing https://adrianroselli.com/2019/09/under-engineered-text-boxen.html */
textarea,
input {
  font: inherit;
  letter-spacing: inherit;
  word-spacing: inherit;
  line-height: inherit;
}

[type="checkbox"],
[type="date"],
[type="email"],
[type="file"],
[type="number"],
[type="password"],
[type="radio"],
[type="search"],
[type="submit"],
[type="tel"],
[type="text"],
select,
textarea {
  border: 2px solid #222;
  border-radius: 4px;
  box-sizing: border-box;
  width: 100%;
  /* max-width: 100%; /* avoid spill over on narrow viewports */
  max-width: 420px;
  padding: 0.3rem 1ch; /* Using ch as per http://revoltpuppy.com/articles/89/using-ch-an-underappreciated-css-length */
  margin: 0.5rem 0;
}
@media (min-width: 40.0625em) {
  .width-two-thirds {
    width: 66.66%;
  }
}

input[maxlength] {
  /* padding: 0.3rem 1ch; /* Include this if it hasn't already been */
  font-family: Consolas, “Andale Mono”, “Lucida Console”,
    “Lucida Sans Typewriter”, Monaco, “Courier New”, “monospace”; /* explanation for a monospaced font stack coming later */
}

input[maxlength="12"],
input[data-width="12ch"] {
  width: calc(
    12ch + 2ch + 1ch + 2px
  ); /* maxlength + padding + breathing space + border */
}
input[maxlength="10"] {
  width: calc(
    10ch + 2ch + 1ch + 2px
  ); /* maxlength + padding + breathing space + border */
}
input[maxlength="4"] {
  width: calc(
    4ch + 2ch + 1ch + 2px
  ); /* maxlength + padding + breathing space + border */
}
input[maxlength="3"] {
  width: calc(
    3ch + 2ch + 1ch + 2px
  ); /* maxlength + padding + breathing space + border */
}

/* https://css-tricks.com/snippets/css/turn-off-number-input-spinners/ */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
/* https://jwatt.org/2013/12/11/input-type-number-coming-to-mozilla/ */
input[type="number"] {
  -moz-appearance: textfield;
}

/* basic visual styles */
html {
  font-size: 62.5%;
}
body {
  font-family: Roboto, helvetica, arial, sans-serif;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
  font-size: 1.8rem;
}
fieldset,
.field,
.field-checkbox,
.field-radio {
  max-width: 26em;
  margin-bottom: 30px;
}
.field-checkbox,
.field-radio {
  padding-left: 1.8em;
  max-width: calc(26em - 1.8em);
}
.field-checkbox label span,
.field-radio label span {
  margin-left: 1.8rem; /* rem units ensure both field-label and field-hint are aligned.  */
}

fieldset,
legend {
  border: 0;
  padding: 0;
  margin: 0;
}
label,
input,
select,
textarea,
label span {
  display: block;
  font-size: 2.125rem;
  line-height: 1.38889;
}
label[for],
button {
  cursor: pointer; /* I adopted this from https://patterns.boilerform.design/#group-label-component-default It helps mouse users realise they can click anywhere on the label */
}
.field-label {
  font-weight: 700;
  margin-bottom: 0.25rem;
}
label span,
.field-radioButton {
  margin-bottom: 0.25rem;
}
.field-hint,
.field-error {
  color: #595959; /* #595959 is the minimum grey on white background to pass AA and AAA for a contrast ratio of 7:1 */
  font-size: 0.9em;
  font-weight: normal;
  display: block;
  margin-bottom: 0.25rem;
}

/* Visually hidden techniques allow for content to be hidden from sighted users while still allowing ATs to discover and interact with the content. Inclusively Hidden https://www.scottohara.me/blog/2017/04/14/inclusively-hidden.html by @scottohara */
/* ie9+ */
.sr-only:not(:focus):not(:active) {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

:root {
  /* With bold font weight (700) this color passes the direct sunlight test at https://whocanuse.com/?b=ffffff&c=b61d14&f=20&s=b #D4351C is from https://design-system.service.gov.uk/components/error-message/ and is better contrast with both background and nearby body text/labels than #b00f1f from http://nostyle.herokuapp.com/patterns/fix-form-errors */
  --color-error: hsl(3.3deg, 80.2%, 39.6%);

  /* https://whocanuse.com/?b=000000&c=ffbf47&f=19&s= is a color with enough contrast against black for focus styles */
  --color-focus: hsl(39.1deg, 100%, 63.9%);
}
/* error styles */
[data-prefix="fas"] {
  /* Any additional styling for fontawesome svg icons goes here */
}
.field-error {
  color: var(--color-error);
  font-weight: 700;
}
input[aria-invalid="true"] /*
:invalid:focus was the best compromise I arrived at. Adding :focus avoids marking all required fields as invalid before a user has started filling in the form, but does mark the focused input as invalid before typing in anything such as in required fields!

For type=email this input will remain as invalid until after an @ and one more character.

https://css-tricks.com/almanac/selectors/i/invalid/ is unhelpful as [value=""] doesn't work.

From https://css-tricks.com/form-validation-ux-html-css/ :invalid:not(:focus):not(:placeholder-shown) relies on adding placeholder=" " to each input which causes screen readers announce an extra "blank" before the value "blank" */
{
  border-color: var(--color-error);
}

/* focus style */
[type="checkbox"]:focus,
[type="date"]:focus,
[type="email"]:focus,
[type="file"]:focus,
[type="number"]:focus,
[type="password"]:focus,
[type="radio"]:focus,
[type="search"]:focus,
[type="submit"]:focus,
[type="tel"]:focus,
[type="text"]:focus,
button:focus,
button:hover,
select:focus,
textarea:focus,
input[type="checkbox"]:focus + label::before {
  outline: 0;
  box-shadow: 0 0 1px 4px var(--color-focus);
}
[type="radio"]:focus + label::before {
  box-shadow: inset 0 0 1px 4px var(--color-focus) !important;
}

.primaryButton {
  font: inherit;
  border: none;
  appearance: none;
  -webkit-appearance: none;
  font-size: 1em;
  line-height: 1.5625;
  padding: 1rem 4ch;
  background-color: #0074d9;
  color: #fff;
  width: inherit;
}
/* on wider screens make the primary button text larger and easier to read */
@media screen and (min-width: 37.5em) {
  .primaryButton {
    font-size: 1.125em;
    line-height: 1.38889;
  }
}
/* toggle foreground and background color on press */
button:active {
  background-color: #fff;
  color: #0074d9;
}

/* https://adrianroselli.com/2017/05/under-engineered-custom-radio-buttons-and-checkboxen.html */
input[type="radio"],
input[type="checkbox"] {
  /* hide the native control */
  position: absolute;
  top: auto;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  width: 1px;
  height: 1px;
  white-space: nowrap;
}
/* CREATE FAKE VISUAL CHECKBOX AND RADIO */
input[type="radio"] + label::before,
input[type="checkbox"] + label::before {
  content: "";
  background: #fff;
  border: 2px solid #222;
  border-radius: 4px;
  background-color: #fff;
  display: block;
  box-sizing: border-box;
  float: left;
  width: 1.8em;
  height: 1.8em;
  margin-left: -1.5em;
  margin-top: 0.225em;
  vertical-align: top;
  cursor: pointer;
  text-align: center;
  transition: all 0.1s ease-out;
}
/* make the radio a circle */
input[type="radio"] + label::before {
  border-radius: 100%;
}
/* radio checked */
input[type="radio"]:checked + label::before {
  background-color: #000;
  box-shadow: inset 0 0 1px 4px #fff;
}
/* checkbox checked (part 1 of 2) */
input[type="checkbox"] + label::after {
  display: block;
  content: "";
  position: relative;
  top: 0.5em;
  left: 0.5em;
  width: 1em;
  height: 1em;
  transform: rotate(0deg);
  transition: all 0.1s ease-out;
}
/* checkbox checked (part 2 of 2) */
input[type="checkbox"]:checked + label::after {
  top: 0.3em;
  left: 0.65em;
  width: 0.35em;
  height: 1.1em;
  transform: rotate(45deg);
  border-right: 0.25em solid #000; /* right-half of check */
  border-bottom: 0.25em solid #000; /* left-half of check */
}

              
            
!

JS

              
                /* https://zellwk.com/blog/style-hover-focus-active-states/ */
document.addEventListener("click", (event) => {
  if (event.target.matches("button")) {
    event.target.focus();
  }
});

              
            
!
999px

Console