# Webcore form controls

Retro OS text field, checkbox, radio buttons and dropdown on a grey or pink dialog face\.

- Kind: element
- Category: misc
- Default background: light
- Use when: Guestbook and contact forms, settings boxes and fake sign\-ups on Y2K pages\.
- Avoid when: Long forms or payment details, where the joke styling gets in the way\.
- Requires: Give each radio group its own name, and wrap the controls in your own form element\.
- Kit: [Webcore](https://thuvien.org/ui/kits/webcore.md)
- Credit: [Luna UI](https://thuvien.org/ui)
- License: MIT

## Variants

Add one variant class next to the root element's class.

- [Grey](https://thuvien.org/ui/elements/webcore-form?variant=grey): default, no extra class
- [Pink](https://thuvien.org/ui/elements/webcore-form?variant=pink): `tv-webcore-form--pink`

## HTML

```html
<div class="tv-webcore-form">
  <label class="tv-webcore-form-field">
    <span class="tv-webcore-form-label">screen name</span>
    <input class="tv-webcore-form-input" type="text" value="sk8rgrrl99">
  </label>
  <label class="tv-webcore-form-option">
    <input class="tv-webcore-form-box" type="checkbox" checked>
    <span>Remember me on this computer</span>
  </label>
  <fieldset class="tv-webcore-form-group">
    <legend class="tv-webcore-form-label">mood</legend>
    <label class="tv-webcore-form-option"><input class="tv-webcore-form-dot" type="radio" name="tv-webcore-mood" checked><span>sparkly</span></label>
    <label class="tv-webcore-form-option"><input class="tv-webcore-form-dot" type="radio" name="tv-webcore-mood"><span>sleepy</span></label>
  </fieldset>
  <label class="tv-webcore-form-field">
    <span class="tv-webcore-form-label">theme</span>
    <select class="tv-webcore-form-select">
      <option>bubblegum</option>
      <option>lilac glass</option>
      <option>dialog grey</option>
    </select>
  </label>
</div>
```

## CSS

```css
/* Retro OS form controls on a dialog face: navy rules, a pink inner line, and pixel-crisp marks. */
.tv-webcore-form {
  --tv-webcore-form-face: var(--tv-webcore-grey, #d9d9e5);
  display: grid;
  gap: 14px;
  box-sizing: border-box;
  width: 100%;
  max-width: 22rem;
  margin: 0 auto;
  padding: 18px;
  border: 2px solid var(--tv-webcore-lilac, #a49bf3);
  background: var(--tv-webcore-form-face, #d9d9e5);
  color: var(--tv-webcore-navy, #2c2b9f);
  font: 14px/1.4 "Lucida Console", "Courier New", ui-monospace, monospace;
}

.tv-webcore-form-field {
  display: grid;
  gap: 5px;
}

.tv-webcore-form-label {
  padding: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.tv-webcore-form-input,
.tv-webcore-form-select {
  box-sizing: border-box;
  width: 100%;
  min-height: 2.5rem;
  padding: 6px 10px;
  border: 1px solid var(--tv-webcore-navy, #2c2b9f);
  border-radius: 0;
  background-color: var(--tv-webcore-paper, #ffffff);
  color: inherit;
  font: inherit;
  letter-spacing: 0.04em;
  box-shadow: inset 0 0 0 2px var(--tv-webcore-paper, #ffffff), inset 0 0 0 3px var(--tv-webcore-pink, #f7b5e4);
}

/* The dropdown key: a pink square with a navy arrow, drawn in the background. */
.tv-webcore-form-select {
  padding-right: 42px;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M0 0h10L5 6z' fill='%232c2b9f'/%3E%3C/svg%3E"), linear-gradient(var(--tv-webcore-navy, #2c2b9f), var(--tv-webcore-navy, #2c2b9f)), linear-gradient(var(--tv-webcore-pink, #f7b5e4), var(--tv-webcore-pink, #f7b5e4));
  background-position: right 11px center, right 30px top, right top;
  background-repeat: no-repeat;
  background-size: 10px 6px, 1px 100%, 30px 100%;
  cursor: pointer;
}

.tv-webcore-form-group {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 0;
  border: 0;
}

.tv-webcore-form-group .tv-webcore-form-label {
  margin-bottom: 2px;
}

.tv-webcore-form-option {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 2rem;
  cursor: pointer;
}

.tv-webcore-form-box,
.tv-webcore-form-dot {
  flex-shrink: 0;
  box-sizing: border-box;
  width: 22px;
  height: 22px;
  margin: 0;
  border: 1px solid var(--tv-webcore-navy, #2c2b9f);
  background-color: var(--tv-webcore-paper, #ffffff);
  background-position: center;
  background-repeat: no-repeat;
  appearance: none;
  cursor: pointer;
}

.tv-webcore-form-box:checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' shape-rendering='crispEdges'%3E%3Cpath d='M2 7l3.5 3.5L12 4' fill='none' stroke='%232c2b9f' stroke-width='2.5' stroke-linecap='square'/%3E%3C/svg%3E");
  background-size: 14px 14px;
}

.tv-webcore-form-dot {
  border-radius: 50%;
}

.tv-webcore-form-dot:checked {
  background-image: radial-gradient(var(--tv-webcore-navy, #2c2b9f) 0 4px, transparent 4.5px);
}

.tv-webcore-form-input:focus-visible,
.tv-webcore-form-select:focus-visible,
.tv-webcore-form-box:focus-visible,
.tv-webcore-form-dot:focus-visible {
  outline: 2px dashed var(--tv-webcore-navy, #2c2b9f);
  outline-offset: 3px;
}

.tv-webcore-form--pink {
  --tv-webcore-form-face: var(--tv-webcore-pink, #f7b5e4);
}
```
