Кроссбраузерная стилизация input type="file" с помощью CSS.

Данный плагин позволяет стилизовать с помощью CSS следующие HTML-элементы:

  • флажок ;
  • переключатель ;
  • поле для выбора файла .
  • поле для ввода чисел .
  • раскрывающийся список ;
Демонстрация работы плагина

Живые примеры можно посмотреть на отдельной странице . Стоит заметить, что при оформлении элементов форм не использовано ни одного изображения, только CSS.

Достоинства
  • Общее:
    • Простота оформления с помощью CSS.
    • При отключенном JavaScript отображаются стандартные элементы форм, т.е. их работоспособность не теряется.
    • Псевдоэлементы выводятся внутристрочно, т.е. повторяют свойство стандартных элементов.
    • Поддержка работы с динамически добавляемыми/изменяемыми элементами.
    • Поддержка атрибутов checked , selected , disabled .
    • Атрибуты class , id , data-* , title , указанные у оригинальных элементов форм, передаются в соответствующие псевдоэлементы (id передается с суффиксом, чтобы избежать дублирования).
    • Поддержка динамического добавления/изменения атрибутов class , id , data-* , title .
    • Поддержка сброса формы при нажатии на .
    • Умеет «ловить» нажатие клавиши Tab и позволяет переключать элементы с клавиатуры.
    • Кроссбраузерность (все современные браузеры, а также IE8 и выше).
    • Поддержка валидации HTML5.
    • Поддержка мультиязычности.
  • Для селектов:

    • Поддерживает атрибут multiple , т.е. позволяет выбирать несколько пунктов (мультиселект).
    • Поддерживает группировку элементов списка в селекте (тег ).
    • Позволяет задать максимальную высоту для выпадающего списка (CSS-свойством max-height , либо через опцию selectVisibleOptions).
    • Поддерживает «умное позиционирование», т.е. не уходит за видимую часть страницы при открытии списка.
    • Поддержка поиска по пунктам одиночного селекта.
    • Поддержка замещающего текста (placeholder).
    • Автоматически подстраивает ширину, если она не указана.
    • Поддерживает прокрутку колесом мыши.
Недостатки
  • При использовании некоторых нестандартных шрифтов (например, Open Sans, подключенный с Google Fonts), неправильно определяется ширина псевдоселекта, в связи с чем текст пунктов обрезается. Это связано с тем, что шрифт применяется лишь после стилизации селекта плагином. Как вариант решения этой проблемы, можно сделать отложенный запуск скрипта:

    setTimeout(function() { $("input, select").styler(); }, 100)

    Еще один вариант решения — использовать , который переинициализирует плагин после окончания загрузки шрифта.

  • В Mac OS при переключении селекта с клавиатуры появляется нативный выпадающий список.
СкачатьПодключение плагина

Для работы плагина необходимо использовать jQuery не ниже версии 1.7.0.

Подключите jQuery (если он еще не подключен), плагин и стили к нему, добавив следующие строки перед тегом :

Файл jquery.formstyler.css — это обязательные стили, необходимые для корректной работы плагина, а jquery.formstyler.theme.css — визуальное оформление элементов форм.

Для активации плагина примените метод.styler к тегам, которые хотите стилизовать:

(function($) { $(function() { $("input, select").styler(); }); })(jQuery);

Отключение плагина (метод destroy)

Если есть необходимость отвязать плагин от стилизованного элемента, то задействуйте метод destroy:

$("select").styler("destroy");

Динамическое изменение

При динамическом изменении элементов формы необходимо запустить триггер refresh , например:

$("button").click(function(e) { e.preventDefault(); /* делаем чекбокс неактивным */ $("input:checkbox").attr("disabled", true) /* обновляем состояние псевдочекбокса */ .trigger("refresh"); });

При использовании сторонних плагинов, например, jQuery Validation , которые меняют атрибуты элементов формы, событие.trigger("refresh") необходимо запускать, используя setTimeout , иначе состояния псевдоэлементов не изменится. Пример с вышеуказанным плагином:

$("form").validate({ invalidHandler: function() { setTimeout(function() { $("input, select").trigger("refresh"); }, 1) } });

Опции плагина

Большинство опции плагина можно переопределить для конкретного тега, указав ему соответствующий data-атрибут.

Опция По умолчанию Описание data-атрибут
idSuffix -styler суффикс к атрибуту id , передаваемому от стилизуемого элемента
filePlaceholder Файл не выбран текст по умолчанию в поле выбора файла (когда файл не выбран) data-placeholder
fileBrowse Обзор... текст кнопки у поля для выбора файла data-browse
fileNumber Выбрано файлов: %s текст после выбора нескольких файлов, вместо %s вставится число data-number
selectPlaceholder Выберите... замещающий текст (плейсхолдер) в одиночном селекте; отображается, если по умолчанию выбран первый пункт с отсутствующим текстом: data-placeholder
selectSearch false показывать поисковое поле в одиночном селекте (true — да, false — нет) data-search
selectSearchLimit 10 минимальное количество пунктов одиночного селекта, при котором показывать поиск data-search-limit
selectSearchNotFound Совпадений не найдено текст сообщения о том, что нет пунктов, удовлетворяющих поиску data-search-not-found
selectSearchPlaceholder Поиск... текст по умолчанию в поисковом поле data-search-placeholder
selectVisibleOptions 0 количество отображаемых пунктов списка в простом селекте без прокрутки data-visible-options
selectSmartPositioning true умное позиционирование для выпадающего списка селекта:
true — работает вверх и вниз
false — работает только вниз
"-1" — позиционирование отключено
data-smart-positioning
locale ru текущая локаль
locales английская локализация массив локалей с переводом соответствующих опций, подробнее смотрите
Колбеки (callbacks)

Пример использования:

$("input, select").styler({ fileBrowse: "Выбрать", singleSelectzIndex: "999", onSelectOpened: function() { // к открытому селекту добавляется красная обводка $(this).css("outline", "3px solid red"); } });

Локализация

Плагин поддерживает многоязычность. Для этого используются опции locale и locales .

Пример локализации (английская по умолчанию включена в плагин):

$("input, select").styler({ locale: "en", locales: { "en": { filePlaceholder: "No file selected", fileBrowse: "Browse...", fileNumber: "Selected files: %s", selectPlaceholder: "Select...", selectSearchNotFound: "No matches found", selectSearchPlaceholder: "Search..." } }, });

CSS-селекторы, используемые для оформленияЧекбокс Радиокнопка Поле для выбора файла Поле для ввода чисел Селект (простой) Селект (множественный) Прочие элементы (только CSS)
.jq-checkbox чекбокс по умолчанию
.jq-checkbox__div дополнительный вложенный тег
.jq-checkbox.checked выбранный чекбокс
.jq-checkbox.disabled неактивный (недоступный для выбора) чекбокс
.jq-checkbox.focused фокус на чекбоксе, когда нажата клавиша Tab
.jq-checkbox span дополнительный вложенный тег
.jq-radio радиокнопка по умолчанию
.jq-radio__div дополнительный вложенный тег
.jq-radio.checked выбранная радиокнопка
.jq-radio.disabled неактивная (недоступная для выбора) радиокнопка
.jq-radio.focused фокус на радиокнопке, когда нажата клавиша Tab
.jq-radio span дополнительный вложенный тег
.jq-file родительский контейнер
.jq-file.focused фокус на поле
.jq-file.changed файл выбран
.jq-file.disabled неактивное поле
.jq-file__name поле с именем файла
.jq-file__browse кнопка выбора файла
.jq-number родительский контейнер
.jq-number.focused фокус на поле
.jq-number.disabled неактивное поле
.jq-number__field обертка для поля ввода
.jq-number__spin.minus кнопка «минус»
.jq-number__spin.plus кнопка «плюс»
.jq-selectbox родительский контейнер
.jq-selectbox.opened выпадающий список селекта раскрыт
.jq-selectbox.dropup выпадающий список селекта раскрыт вверх
.jq-selectbox.dropdown выпадающий список селекта раскрыт вниз
.jq-selectbox.changed выбрано значение, отличное от заданного по умолчанию
.jq-selectbox__select селект в свернутом состоянии
.focused .jq-selectbox__select фокус на селекте, когда нажата клавиша Tab
.disabled .jq-selectbox__select
.jq-selectbox__select-text дополнительный вложенный тег для свернутого селекта
.jq-selectbox .placeholder замещающий текст
.jq-selectbox__trigger правая часть свернутого селекта (условный переключатель)
.jq-selectbox__trigger-arrow вложенный тег для переключателя (стрелка)
.jq-selectbox__dropdown обертка для выпадающего списка
.jq-selectbox__search обертка для поискового поля
.jq-selectbox__search input поисковое поле
.jq-selectbox__not-found сообщение об отсутствии результатов поиска
.jq-selectbox ul выпадающий список
.jq-selectbox li пункт (опция) селекта
.jq-selectbox li.selected выбранный пункт селекта
.jq-selectbox li.disabled
.jq-selectbox li.optgroup заголовок для группы пунктов
.jq-selectbox li.option пункт списка в группе
.jq-select-multiple родительский контейнер
.jq-select-multiple.disabled неактивный (недоступный для выбора) селект
.jq-select-multiple li пункт (опция) селекта
.jq-select-multiple li.selected выбранный пункт селекта
.jq-select-multiple li.disabled неактивный (недоступный для выбора) пункт селекта
.jq-select-multiple li.optgroup заголовок для группы пунктов
.jq-select-multiple li.option пункт списка в группе
.styler класс, используемый для стилизации текстовых полей и кнопок (работает независимо от плагина)

В 1998 года, когда появился CSS Level 2, элементы форм уже поддерживались всеми основными браузерами. Спецификация CSS 2 не предусматривала решение проблемы представления . Так как эти элементы являются частью пользовательского интерфейса, авторы спецификации предпочли отдать их визуальное представление на откуп разработчикам браузеров.

Год за годом не достаточно детализированная спецификация заставляла веб- разработчиков экспериментировать в попытках привести представление таких элементов, как input , select , fieldset , legend и textarea в разных браузерах к «общему знаменателю». В этой статье мы рассмотрим некоторые приемы CSS, используемые веб-разработчиками для стандартизации визуального представления элементов форм.

Тесты Роджера Йоханссона

Сначала в 2004, а затем и в 2007 году, Роджер Йоханссон (Roger Johansson) создал исчерпывающий набор тестов для проверки применения CSS-стилей к элементам форм. Результатом выполнения этих тестов, которые вы можете найти в его статье «К вопросу о стилизации элементов форм с помощью CSS », стал неутешительный вывод, который Йоханссон выразил следующими словами:

Так что же показывает этот эксперимент? Как я и говорил, он показывает, что использование CSS для стилизации элементов форм с целью приведения их к единому виду в разных браузерах и на разных платформах невозможно. Он также показывает, что большинство браузеров игнорируют многие CSS-свойства, применяемые к элементам форм.

Несмотря на несомненную справедливость этих заключений, веб-разработчики продолжили активно тестировать применение CSS-стилей к элементам форм, чтобы найти Святой Грааль их кроссбраузерного представления или хотя бы разумный компромисс между стилями, применяемыми браузером по умолчанию, и заданными разработчиком.

Модель по умолчанию

Спецификация CSS 2.1 указывает в предлагаемой таблице стилей по умолчанию для HTML4 , что элементы форм, такие как textarea , input и select , являются строчно-блочными:

textarea , input , select { display : inline-block; }

В свою очередь, элементы form и fieldset являются блочными:

fieldset , form { display : block; }

Описание модели, предлагаемой спецификацией CSS по умолчанию, этим и ограничивается. Все остальные визуальные аспекты элементов форм зависят от таблицы стилей браузера, применяемой по умолчанию . Тем не менее, перечисленные правила означают следующее:

    Строчно-блочные элементы могут быть стилизованы с использованием строчной модели. Он позволяет использовать такие CSS-свойства, как line-height и vertical-align , для управления высотой блока и его вертикальным выравниванием. Кроме этого, для указания внешних и внутренних отступов блока могут быть применены свойства margin и padding . Строчно-блочные элементы поддерживают width и height , так как используют блочную модель форматирования.

    Блочные элементы могут быть стилизованы с использованием хорошо всем известного блочной модели. Тем не менее, проблемы возникают с элементами fieldset и legend , так как legend полностью зависит от стилей, применяемых браузером по умолчанию.

Как веб-разработчики решают эти проблемы?

Размеры

Веб-разработчики быстро заметили, что браузеры ведут себя странно при использовании строчно-блочных элементов, когда дело касается явного указания размеров. Указание высоты зачастую приводит к неожиданным результатам:

input , select { width : 120px ; height : 32px ; }

Разработчики пытались решить эту проблему, превратив эти элементы в блочные:

input , select { width : 120px ; height : 32px ; display : block; }

Сработало только с textarea . Стандартное решения этой проблемы заключается в использовании вместо height свойств font-size и padding .

Элементы форм не наследуют гарнитуру и кегль шрифта, поэтому первым делом необходимо указать их:

input , select { width : 120px ; font : 1em Arial, sans-serif; }

После определения гарнитуры можно задать padding для добавления внутренних отступов блоку элемента:

input , select { width : 120px ; font : 1em Arial, sans-serif; padding : 3px 6px ; }

Для элементов input и textarea в таблицах стилей браузеров определен border . Нормализуем его:

input , input , textarea { border : 1px solid #ccc ; }

Элементам input с типом button и submit браузеры добавляют дополнительный отступ. Распространенная практика их нормализации:

input , input { padding : 2px ; }

Проблема этого приема состоит в том, что браузеры, помимо прочего, применяют специфичные для них свойства к этим элементам, и padding не всегда способен нормализовать их. Например, в браузерах, на движке Webkit, вы можете обнаружить следующее:

input , input , input , input ::-webkit-file-upload-button , button { -webkit-box-align : center; text-align : center; cursor : default; color : buttontext; padding : 2px 6px 3px ; border : 2px outset buttonface; border-image : initial; background-color : buttonface; box-sizing : border-box; } input , input , input { -webkit-appearance : push-button; white-space : pre; }

padding используется также и для элементов fieldset и legend , но приводит к другим результатам:

  • Установка значения свойства padding для элемента fieldset в 0 по умолчанию сбросит отступ элемента legend в некоторых браузерах (но не в IE).
  • Установка значения свойства padding для элемента legend в 0 приведет к его схлопыванию.

Для select , и для input c типами checkbox и radio стоит использовать только:

  • font-family ,
  • font-size ,
  • width (для select),
  • padding .

Применение других свойств к этим элементам часто приводит к противоречивым результатам в различных браузерах.

Выравнивание

Элементы форм можно выровнять по горизонтали и по вертикали. Они могут быть расположены на одной линии или как группа блоков друг под другом. Для выравнивания их на одной линии вы можете использовать один из двух подходов:

  • Использовать float ,
  • Использовать для некоторых элементов строчно-блочную модель.
  • При использовании float элементы автоматически становятся блочными. Это означает, что эти элементы форм теперь подчиняются девяти правилам float-элементов .

    Элементы форм можно выравнивать по вертикали и по горизонтали.

    При использовании float основной проблемой является правильное выравнивания по вертикали относительно текущей строки. Обычно это делают используя margin или padding:

    input , select { width : 120px ; float : left; margin-top : 0.4em ; }

    Этот подход работает, когда вам не нужно задавать выравнивание блоков относительно текста, например, содержимого label . В случае, если это необходимо, вы можете использовать относительное позиционирование, padding и margin для элементов, содержащих только текст:

    label { float : left; padding-top : 0.4em ; width : 5em ; margin-right : 1em ; }

    Еще одна проблема возникает с кнопками. В случае, когда у вас есть кнопка, размеры которой превышают размеры других элементов, вы можете задать ее вертикальное выравнивание с помощью относительного позиционирования:

    input { float : left; width : 90px ; position : relative; top : 0.4em ; }

    Еще прием с относительным позиционированием можно использовать для input с типами checkbox и radio . Относительное позиционирование можно использовать даже для нормализации отступа слева у элемента legend внутри элемента fieldset . Единственное отличие состоит в необходимости использования свойства left вместо top .

    При использовании строчной и строчно-блочной модели для вертикального выравнивания элементов вы можете использовать свойство vertical-align:

    label , input { vertical-align : middle; margin-right : 1em ; }

    Бывает удобно использовать это свойство вместе с line-height . Важно отметить, что применять это свойство необходимо к родительскому элементу. Если вы примените это свойство непосредственно к элементам формы, это скажется при расчете их высоты:

    .form-row { line-height : 1.4 ; }

    Явное указание высоты родительского элемента эффективно также при использовании вместе с равным ему значением высоты строки:

    .form-row { line-height : 1.8 ; height : 1.8em ; }

    При использовании строчной или строчно-блочной модели вы также можете использовать свойство text-align для родительского элемента, чтобы выровнять элементы по правому краю, по левому краю или по центру.

    Странные особенности элементов выбора файлов

    - это особый случай. Исходя из соображений безопасности, этот тип элементов всегда должен быть видимым и узнаваемым в браузере. Это означает, что браузеры преднамеренно игнорируют некоторые стили (например, стили, относящиеся к видимости элемента) и стремятся применять представление, описанное их собственными таблицами стилей.

    Стоит отметить, что оформление по умолчанию у разных браузеров различается: некоторые браузеры показывают только одну кнопку, в то время, как другие добавляют текстовое поле для указания пути к загружаемому файлу.

    Веб-разработчики, тем не менее, быстро нашли способ преодолеть эти ограничения. Сначала они поместили поле ввода в контейнер:

    Затем они скрыли элемент input с помощью свойства opacity и применили стили к контейнеру:

    .upload { width : 157px ; height : 57px ; background : url (upload.png) no-repeat; overflow : hidden; } .upload input { display : block !important ; width : 157px !important ; height : 57px !important ; opacity : 0 !important ; overflow : hidden!important ; }

    Обратите внимание на!important . Это предпочтительный способ для переопределения стилей браузера по умолчанию.

    Заключение

    Полноценное управление представлением элементов форм невозможно ввиду отсутствия определенности в спецификации CSS и из-за стилей, применяемых браузерами по умолчанию. Тем не менее, используя некоторые общепринятые приемы, можно сократить различия в оформлении элементов (но не избавиться от них).

    Оригинальная статья: The Problem Of CSS Form Elements Статью вычитывали: , visitorFM , Anton Khlynovskiy , Igor Adamenko

    3.9 из 5

    Привет. Сегодня я хочу вам рассказать о том, как можно изменить внешний вид файлового инпута, как стилизовать файл-инпут под свой дизайн, как стилизовать .

    Хватит ключевых слов =). Суть я думаю вы поняли.

    Дело в том, что изменение внешнего вида инпутов, как правило, не вызывает трудностей, но этот вид инпутов отличается от остальных. В первую очередь это связано с безопасностью, во вторую с тем, что каждый браузер по своему отображает этот элемент, и на это почти нельзя повлиять.

    Как добиться того внешнего вида файл-инпута, который вам нужен и расскажет эта статья.

    Для начала давайте посмотрим на то, как отображаются файл-инпуты без применения каких-либо стилей в разных браузерах.

    В результате везде, кроме сафари мы видим начало адреса, которое не несет почти никакой смысловой нагрузки. Я сомневаюсь, что кто-то об этом не знал, но на эту глупость обратили внимание только ребята из эпла и сделали возможность сразу увидеть не только название выбранного файла, но и иконку. Такую же функциональность файл-инпута мы и собираемся реализовать для всех браузеров.

    Но cначала ознакомимся с проблематикой.
    1. Средствами JS мы не можем сымитировать клик на такой инпут. Вот что говорится об этом в святом писании спецификации DOM :

    click
    Simulate a mouse-click. For INPUT elements whose type attribute has one of the following values: “button”, “checkbox”, “radio”, “reset”, or “submit”.
    No Parameters
    No Return Value
    No Exceptions

    То есть методом click мы можем сымитировать клик почти на всех типах инпутов, но не на файл-инпуте. Это сделано чтобы обезопасить компьютер клиента: в противном случае хозяин сайта мог бы без проблем получать любые файлы с компьютера клиента. Хотя с другой стороны, по клику вызывается только окно выбора файла. Так или иначе, в девелопер-центре файерфокса этот факт обозначен как баг.

    Решение есть, и мы не придумывали велосипед, мы его тюнинговали. Все, кто стилизует инпуты действуют по той же схеме: создается инпут с нулевой прозрачностью и ставится поверх кнопки или изображения, которые представляют собой кнопку выбора файла.

    Основная трудность в следующей проблеме.

    2. Мы не можем свободно влиять на размеры кнопок «обзор», чтобы подогнать инпут под размер перекрываемой картинки. В файерфоксе мы вообще не можем изменить внешний вид файл-инпута средствами css (кроме высоты). То есть задача заключается определении оптимального размера перекрываемой картинки, чтобы минимальное количество пикселей было некликабельно, а пустые области не реагировали на клик.

    Посмотрим на кликабельные области и их размеры в разных браузерах.