Upgrade to Pro — share decks privately, control downloads, hide ads and more …

input, i ♥️ you, but you're bringing me down

input, i ♥️ you, but you're bringing me down

Browsers have had an <input> element since the dawn of time, and yet any time you talk to web developers about it, everyone complains about it. It's unpredictable. It's grumpy. It's got reaaaaally strong opinions about style, and it doesn't want to listen to yours. I'm going to tell you a story about how grew up to be the moody adult it is, and why it's maybe time we stood up to it.

Monica Dinculescu

June 16, 2016
Tweet

More Decks by Monica Dinculescu

Other Decks in Programming

Transcript

  1. type=date not working properly empty input is invalid regardless of

    minlength type=number doesn’t work with pattern type=number can type eee without firing event weird caret offset with type=search typing moves cursor to the end
  2. input[type=range] { … } // Webkit ::-webkit-slider-thumb { … }

    ::-webkit-slider-runnable-track { … } // FF ::-moz-range-thumb { … } ::-moz-range-track { … } // Never stop being different, IE <3 ::-ms-thumb { … } ::-ms-track { … } ::-ms-fill-lower { … } ::-ms-fill-upper { … }
  3. input[type=range] { … } // Webkit ::-webkit-slider-thumb { … }

    ::-webkit-slider-runnable-track { … } // FF ::-moz-range-thumb { … } ::-moz-range-track { … } // Never stop being different, IE <3 ::-ms-thumb { … } ::-ms-track { … } ::-ms-fill-lower { … } ::-ms-fill-upper { … }
  4. input[type=range] { … } // Webkit ::-webkit-slider-thumb { … }

    ::-webkit-slider-runnable-track { … } // FF ::-moz-range-thumb { … } ::-moz-range-track { … } // Never stop being different, IE <3 ::-ms-thumb { … } ::-ms-track { … } ::-ms-fill-lower { … } ::-ms-fill-upper { … }
  5. input[type=range] { … } // Webkit ::-webkit-slider-thumb { … }

    ::-webkit-slider-runnable-track { … } // FF ::-moz-range-thumb { … } ::-moz-range-track { … } // Never stop being different, IE <3 ::-ms-thumb { … } ::-ms-track { … } ::-ms-fill-lower { … } ::-ms-fill-upper { … }
  6. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput);
  7. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput);
  8. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput);
  9. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput);
  10. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput); createdCallback() { this._value = null; }
  11. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput); attachedCallback() { this._input = document.createElement('input'); this._input = 'text'; this._input = this._value; this.createShadowRoot().appendChild(this._input); this._input.addEventListener(‘keypress’, _restrict); this._input.addEventListener(‘input’, _onInput); }
  12. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput); attachedCallback() { this._input = document.createElement('input'); this._input = 'text'; this._input = this._value; this.createShadowRoot().appendChild(this._input); this._input.addEventListener(‘keypress’, _restrict); this._input.addEventListener(‘input’, _onInput); }
  13. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput); attachedCallback() { this._input = document.createElement('input'); this._input = 'text'; this._input = this._value; this.createShadowRoot().appendChild(this._input); this._input.addEventListener(‘keypress’, _restrict); this._input.addEventListener(‘input’, _onInput); }
  14. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput); attachedCallback() { this._input = document.createElement('input'); this._input = 'text'; this._input = this._value; this.createShadowRoot().appendChild(this._input); this._input.addEventListener(‘keypress’, _restrict); this._input.addEventListener(‘input’, _onInput); }
  15. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput); getValue() { return this._value; }
  16. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput); setValue(v) { this._input.value = this._value = this._fix(v); } getValue() { return this._value; }
  17. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput); _fix(value) { if (!value) return null; if (awfulRegex.test(value)) return Number(value); return NaN; }
  18. class NumberInput extends HTMLElement { constructor() {…} createdCallback() {…} attachedCallback()

    {…} attributeChanged(which, oldV, newV) {} getValue() {…} setValue(v) {…} } document.registerElement(‘number-input’, NumberInput); attributeChangedCallback(which, oldV, newV) { if (which == 'value') { this._input.value = newV; } }