[Перевод] я ♥ тебя, но ты меня обламываешь
Привет, представляю твоему вниманию перевод статьи Моники Динкулеску 'I ♡ you, but you're bringing me down'. Художественный перевод с английского не является моей основной специализацией, по этому в тексте возможны неточности. Правки призываю отправлять личным сообщением, а если есть что сказать, велкам в комментарии. Отдельное спасибо @Kt за редакторские правки. Приятного чтения.
Некоторые люди делают мебель. Некоторые люди вяжут. Некоторые люди имеют хобби, которые никак не пересекаются с HTML спецификациям из 90-х. Но я не из таких. И, вот история о том, как <input> стал той хренью, которой он является, и почему его надо сжечь
1995 был клевым годом. Друзья, Скорая Помощь, Зена по телеку. TLC занимали верхушки чартов с хитом "Waterfalls". С браузерами было нормуль, потому что HTML было все очень нормуль. У нас были Mosaic, Netscape и IE1, а при утверждении спеков HTML 2, наконец, выкроили время для стандартизации форм. Девяносто пятый был годом рождения <input>, и теперь, когда он достаточно взрослый, чтобы покупать в магазине алкоголь, нам нужно поговорить.
Изначально <input> пришел к нам в восьми видах: text, password, checkbox, radio, image, hidden, submit и reset, а так же с отдельном последующим RFC, file.
Подожди, ты сказал image? Да, давай я расскажу о нем.
<input type='image' src='cat.png'> выглядит как обычное изображение, но на самом деле это изображение-кнопка, которая при нажатии также передает x и y координаты того места, в котором на нее нажали. При этом, если не указано изображение для атрибута src, «изображение-кнопка» станет кнопкой с надписью «Submit». А если дело будет происходить Firefox, то текст кнопки изменится на «Submit Query» и кнопка будет выглядеть как обычный текст. А если открыть пример в IE, в этом случае ты не увидишь ничего.
А вот вопрос, достойный вашего местного клуба «Что? Где? Когда?», если тип элемента = 'file', то текст который будет отображаться на месте этого элемента, когда не выбран ни один из файлов: «No file chosen», «no file selected», «No file selected», и просто пустой текстовый блок в Chrome, Safari, Firefox и IE соответствнно.
Ладно, хорошо.
Я всегда думала, что input и textarea были придуманы в разное время, и это объясняет, почему они так безумно отличаются. Это в целом так, input был частью браузера Mosaic по крайней мере с 1993, и он был, по сути, исправленной имплементацией ISINDEX. Тем не менее, официально, они оба были детьми HTML2, который решил, что <input> это самозакрывающийся тег в котором значение тега помещаяется в атрибут value, в то время как для тега <textarea> нужен закрывающий тег, а его значение хранится в его содержимом, даже если они оба тега используются только для хранения простого текста, который кто-то ввел:
<input value="batman">
<textarea rows="1">batman</textarea>
Небольшой апдейт: некто подсказывает, что <textarea> должен поддерживать ввод многострочного текста, а символы переноса строки не допускаются внутри значений атрибутов, вот почему мы должны использовать содержимое тега. А это имеет смысл!
В 1999 году, в HTML4 добавили только один новый тип тега = 'button'. Что мне в этом особенно нравится, что без каких-либо дополнительных пользовательских стилей, <input type='button'> и <input type='button' value='Submit'> помещенные в одну и ту же строку, не совпадают по вертикали в Chrome/Safari/Edge.
Позже, в 2011 году, спецификация HTML5 добавила тысячи новых типов для <input>. И на сегодняшний день, большинство из них не реализовано. Вот краткий перечень неработающих фич: type=color работает только в Firefox/Chrome, data/time работает только в Chrome/EDGE/iOS, и все, что работает в Chrome работает в Opera. Вот сравнение всех доступных типов input'ов на сегодня, так что ты можешь сравнить и поплакать наедине.
Давай поговорим о некоторых интересных фактах.
<input type='search'> имеет странные случайно выбранные отступы между текстом и границей, а так же популярные в середине 2000-х закругленные углы, внешний вид которых отличается от браузера к браузеру и от которых почти невозможно избавиться.
А если твоему браузеру повезло поддерживать тип = 'date', не волнуйся о стилизации элемента выбора даты – у нас есть 8 чудесных ::webkit псевдо-селекторов, которые помогут настроить стиль текстового блока, но ни одного для стилизации выпадающего блока выбора даты! В любом случае, знай, CSS вреден для твоего здоровья.
Видите ли, я могу оправдать причуды CSS. Я работала над браузером Chrome в течение 2 лет, сейчас я работаю с командой Blink, я понимаю, что мы все пишем разные рендеры и что для них своейственны свои собственные баги CSS. Тем не менее, <input> API даже нельзая назвать странным – он буквально как банка пауков, и в тот момент, когда ты открываешь банку, уже слишком поздно. Ты весь в пауках. Даже твоя кошка стала пауком. Лучше сжечь тут всё.
Начиная с 1995 года, элементы формы с типами radio и checkbox имеет дополнительный атрибут 'checked' который позволяет определить состояние элемента. Поскольку HTMLInputElement это HTMLInputElement и это HTMLInputElement, выходит, что во всех остальных типах элемента <input> этот атрибут также присутсвует, но его просто игнорируют. Да, даже если это и не имеет смысла, это восхитительно:
var textInput = document.querySelector('input[type="text"]');
console.log(textInput.checked); // prints false.
textInput.checked = true;
console.log(textInput.checked); // prints true.
// did not open the hellmouth.
Круто. Круто круто круто!
содержит текст, текст может быть выделен, а в прототипе HTMLInputElement определенны два свойства: selectionStart и selectionEnd – два числа которые определяют диапазон выбора. Таким образом, ты можешь сделать:
document.querySelector('input').selectionStart += 2;
И продвинуться на 2 символа вперед от начала выделения текста. Мега заурядное исключение из этого факта то, что selectionStart – атрибут который доступен только для input'ов c типами text, url и password. А еще он доступен для вызова (это даже не настраивается) бросая исключение так же для всех остальных типов элемента :
Uncaught DOMException: Failed to read the 'selectionStart'
property from 'HTMLInputElement': The input elements type ('number')
does not support selection.
Даже если я могу вручную выделить этот текст:
Вот и получается, что в некоторых случаях, свойства могут реально использоватсья, а в других случаях они покажут свой «волчий оскал». Ве-ли-ко-леп-но. Именно такого постоянства я ищу в API.
К сожалению, это еще не все. Я уверена, что это еще не все. Дело в том, у разработчиков браузеров был 21 год, чтобы починить отображение input'ов, но им даже не удалось договориться о том, как писать «you haven't picked a file».
Теперь представь будущее, в котором веб-компоненты поддерживаются нативно, кто угодно может написать свой <better-input> – реальный инкапсулированный DOM элемент, а не просто лапшу из DIV'ов. Представь как ты используешь этот <better-input>, что его реализация не отличается от бразуера к браузеру, он выглядит одинаково везде, и что, вероятно, он знает, как испечь тебе вишневый торт. Только представь.