x
 
Павел Шумаков
15 марта 2012

Дизайнеры всё время изощряются с тенями и красивыми формами.

Вопрос такой — как проще всего сверстать нестандартный <select>?



Если вы в раю и верстаете только под Вебкит, то воспользуйтесь правилом -webkit-appearance: button, чтобы стилизовать кнопку селекта как угодно.

Обычный селект:




Немного ЦСС:

.ap-select_special {
  -webkit-appearance: button;
  -webkit-border-radius: 20px;
  /* Подмешал вебкитовский градиент,
     чтобы не показывать стрелку в других браузерах */
  background: url(select-arrow.png) no-repeat right center,
              -webkit-linear-gradient(#fff, #fff);
  border: 2px solid #adcbe2;
  padding: 0 29px 0 7px;
  height: 24px;
  font-size: 13px;
  line-height: 16px;
  text-overflow: ellipsis;
  white-space: nowrap;
  outline: none;
  color: #3e94c5;
  font: -webkit-small-control;
}
.ap-select_special:focus {
  -webkit-box-shadow: 0 0 5px #879eb0;
}

И «дизайнерский» селект готов, но работает он только в Сафари и Хроме:




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

По сути, селект — это кнопка и поповер со списком вариантов. Зная джаваскрипт, можно написать собственный элемент. Но сначала лучше поискать что-то готовое.

Вот, например, Chosen. Тут уже реализованы навигация по списку стрелками и поиск.

Попробуем:

$(function() {
  $('select', '.ap-chosen').chosen({no_results_text: 'Не нашлось'});
});



Неплохо, осталось написать нужные стили, спрятать поле поиска и заодно исправить неопрятные моменты (например, убрать четырёх-пиксельный отступ вокруг списка):

.ap-chosen_special .chzn-single {
  background: url(select-arrow.png) no-repeat right center;
  border: 2px solid #adcbe2;
  padding: 0 29px 0 7px;
  height: 20px;
  font-size: 13px;
  line-height: 20px;
  text-overflow: ellipsis;
  white-space: nowrap;
  outline: none;
  color: #3e94c5;
  border-radius: 20px;
  box-shadow: none;
}
.ap-chosen_special .chzn-single SPAN {
  display: inline;
  margin: 0;
  overflow: visible;
}
.ap-chosen_special .chzn-single DIV {
  display: none;
}
.ap-chosen_special .chzn-container-active .chzn-single {
  box-shadow: 0 0 5px #879eb0;
}
.ap-chosen_special .chzn-drop {
  margin: 5px 0 0 3px;
  background-color: #fff;
  border: 1px solid;
  border-color: #e4e4e5 #c4c4c4 #979797;
  border-radius: 4px;
  box-shadow: rgba(0, 0, 0, 0.25) 0 10px 15px;
}
.ap-chosen_special .chzn-search {
  /* Прячу поле поиска */
  position: absolute;
  left: -99999px;
}
.ap-chosen_special .chzn-results {
  margin: 0;
  padding: 4px 0;
}
.ap-chosen_special .chzn-results LI {
  /* Запрещаю скрывать неподходящие значения */
  display: block !important;
  border-top: 1px solid #fff;
  border-bottom: 1px solid #fff;
  line-height: 1.3;
  padding-top: 3px;
  padding-bottom: 3px;
}
.ap-chosen_special .chzn-results LI.highlighted {
  background-image: linear-gradient(#6aabd0, #4073b0);
  background-color: #548ebf;
  border-top: 1px solid #97c5df;
  border-bottom: 1px solid #294b75;
}
.ap-chosen_special .chzn-results LI EM {
  background: transparent;
}
.ap-chosen_special .chzn-results LI.no-results {
  /* Прячу сообщение о неудачном поиске */
  display: none !important;
}

Изменить поведение при вводе с клавиатуры, чтобы приблизиться к стандартному селекту — после ввода каждой буквы есть 1,5 секунды для ввода следующей, затем значение невидимого поля поиска сбрасывается:

$(function() {
  var clearChznSearch = function(chznSearch) {
    clearTimeout(chznSearch.data('timeout'));
    chznSearch.val('').trigger('keyup');
  }

  var chznSpecial = $('.ap-chosen_special');

  $('input', chznSpecial).bind('keypress', function() {
    var chznSearch = $(this);
    // Очищаю заданный ранее таймаут
    clearTimeout(chznSearch.data('timeout'));
    chznSearch.data({
      timeout: setTimeout(function() {
        // Очищаю поиск по списку через 1,5 секунды
        clearChznSearch(chznSearch);
      }, 1500)
    });
  });

  $('li', chznSpecial).bind('mouseover', function() {
    // Очищаю поиск по списку по наведению на значения
    var chznSearch = $('input', $(this).parents('.ap-chosen_special'));
    if (chznSearch.val()) {
      clearChznSearch(chznSearch);
    }
  });
});

Результат, работает в ИЕ 8+ и всех остальных браузерах:




Для второго элемента с вашей картинки (выбор количества звёзд) ни стандартный селект, ни Chosen не подойдут — придётся написать его самостоятельно.

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

P. S.
Это был совет о разработке веб-интерфейсов. Хотите узнать всё об умной вёрстке, правильных скриптах, грациозной деградации, трюках и работе технолога с дизайнером? Присылайте вопросы.

Поделиться
Отправить

Комментарии

Владимир Страшков
15 марта 2012

Возникает резонный вопрос — а нужен ли в данном случае выпадающий список вообще?

Константин Петров
15 марта 2012

Основная проблема с «дизайнерскими» контролами в том, что в каждой операционной системе есть различные хоткеи, включая редкоиспользуемые. Даже если рассмотреть только Windows: хоть я давно пользуюсь Маком, но помню свою привычку раскрывать селекты по «Альт+вниз». Ни одна из виденных мной JS-реализаций эту комбинацию клавиш не поддерживала, включая те, где разработчики заявляли о «полной эмуляции» родных селектов.

А сколько таких «дизайнерских» селектов сделаны до появления айфонов, и сколько людей мучаются с этим «дизайном» на маленьких тачскринах?

С приведенным вариантом проблема: pgup/pgdn/home/end просто прокручивают страницу.

Да и с простой стилизацией селектов надо быть аккуратнее. Вот, например, на этой странице я ввожу комментарий в узком «иллюминаторе», перемещаясь по элементам формы исключительно табуляцией. На других страницах «Советов» все хорошо — так что логика подсказывает, что виноваты подключенные на этой странице ЦСС :-)

Саша Сергеев
15 марта 2012

Я бы задал дизайнеру вопросы: «так ли нужно приукрасить форму» и «можно ли обойтись другими средстами».

Сторонние плагины часто являются «пушкой по воробьям» и плохо влияют на скорость загрузки страницы.

Дополнительный ЦСС испортил вам форму комментария :-)

Артём Сапегин
15 марта 2012

Есть ещё один способ, близкий к первому, но чуть более сложный и требующий немного JS и дополнительной разметки.

Под стандартный select подкладывается div, выглядящий так как, как должен выглядеть желаемый select, а самому селекту делается opacity:0 (и filter:Alpha(opacity=0)). Далее остаётся только перехватывать события селекта focus и blur (ну и mouseover/mouseout если нужно) и устанавливать на div соответствующие классы-состояния. А по change и keyup записывать в div текст выбранного в select пункта.

Выглядеть и работать будет точно так вариант с webkit-appearance. Прекрасно работает в ИЕ8+ (про более старые не уверен). Как это работает можно посмотреть, например, на новой главной Мэйл.ру (выбор домена в форме входа).

P. S. Понравился хак с градиентом. Артём, а почему button, а не none?


15 марта 2012

Спасибо Саше и Константину за баг-репорты. Форма не открывалась не из-за ЦСС, а из-за несовместимости с Джейквери 1.7.1, который я подключил для Чозена. Теперь скрипт формы модернизирован и работает.

И я немного поправил сам Чозен — убрал произвольное выпрыгивание клавиатуры на айпаде, починил потерю фокуса и ещё какие-то интерфейсные мелочи. Мои исправления можно найти в файле chosen.jquery.customized.js по четырём слешам (////):

http://artgorbunov.ru/…/soviet/20120315/chosen/chosen.jquery.customized.js (http://artgorbunov.ru/bb/soviet/20120315/chosen/chosen.jquery.customized.js)


15 марта 2012

Артём, разницы между button и none при тестировании я не заметил. Выбрал первое из-за семантики и гипотетически более надёжного определения ширины и умещения невлезающего текста.

Александр Дебкалюк
15 марта 2012

Приложение IMDB использует для голосования стандартный «барабан» iOS, но опция голосования простым нажатием на сайте IMDB намного проще.

Могли бы применять ее везде. Это, по мне, удачный повод использовать нестандартный контрол.

Сергей Никитин
9 апреля 2012

Пользовался Chosen-селектом, но из-за недостатка возможностей написал свой:

http://mrnix.ru/combosex

Евгений Бескровный
25 мая 2012

Продолжая комментарий Артема Сапегина, вот это решение, доработанное Роджером Йохансеном (Roger Johansson), неплохо http://www.456bereastreet.com/…keyboard_friendly_custom_select_menu (http://www.456bereastreet.com/archive/201111/an_accessible_keyboard_friendly_custom_select_menu/)


Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры. Мы ожидаем, что такие комментарии составят около 20% от общего числа.

Решение о публикации принимается один раз; мы не имеем возможности комментировать или пересматривать свое решение, хотя оно может быть ошибочно. Уже опубликованные комментарии могут быть удалены через некоторое время, если без них обсуждение не становится менее ценным или интересным.

Вот такой веб 2.0.

4 Сайты для слабовидящих 2 4 За какими вещами нужно следить, чтобы при загрузке страница выглядела прилично? 1