стилизация - раскрывающийся список html




Как стилизовать раскрывающийся список<select> с помощью только CSS? (16)

Есть ли способ только CSS для стилирования выпадающего списка <select> ?

Мне нужно создать форму <select> насколько это возможно по-человечески, без какого-либо JavaScript. Каковы свойства, которые я могу использовать для CSS?

Этот код должен быть совместим со всеми основными браузерами:

  • Internet Explorer 6,7 и 8
  • Fire Fox
  • Сафари

Я знаю, что могу сделать это с помощью JavaScript: Example .

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

Я нашел похожие вопросы о переполнении стека.

И это на Doctype.com.


В современных браузерах относительно безболезненно стиль <select> в CSS. С appearance: none единственная сложная часть не заменяет стрелу (если это то, что вы хотите). Вот решение, которое использует встроенные data: URI с открытым текстом SVG:

select {
  -moz-appearance: none;
  -webkit-appearance: none;
  appearance: none;
  
  background-repeat: no-repeat;
  background-size: 0.5em auto;
  background-position: right 0.25em center;
  padding-right: 1em;
  
  background-image: url("data:image/svg+xml;charset=utf-8, \
    <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 40'> \
      <polygon points='0,0 60,0 30,40' style='fill:black;'/> \
    </svg>");
}
<select>
  <option>Option 1</option>
  <option>Option 2</option>
</select>

<select style="font-size: 2rem;">
  <option>Option 1</option>
  <option>Option 2</option>
</select>

Остальная часть стиля (границы, обивка, цвета и т. Д.) Довольно проста.

Это работает во всех браузерах, которые я только что попробовал (Firefox 50, Chrome 55, Edge 38 и Safari 10). Одна из примечаний к Firefox заключается в том, что если вы хотите использовать символ # в URI данных (например, fill: #000 ), вам нужно его избежать ( fill: %23000 ).


Вот 3 решения:

Решение №1 - внешний вид: нет - с обходным путем ie10-11 ( Demo )

Чтобы скрыть appearance: none стрелки по умолчанию appearance: none на элементе select, добавьте свою собственную стрелку с background-image

select {
   -webkit-appearance: none; 
   -moz-appearance: none;
   appearance: none;       /* remove default arrow */
   background-image: url(...);   /* add custom arrow */
}

Поддержка браузера:

appearance: none них appearance: none имеет очень хорошей поддержки браузера ( caniuse ) - за исключением ie11- и firefox 34-

Мы можем улучшить эту технику и добавить поддержку для ie10 и ie11, добавив

select::-ms-expand { 
    display: none; /* hide the default arrow in ie10 and ie11 */
}

Если ie9 вызывает беспокойство - у нас нет способа удалить стрелку по умолчанию (что означало бы, что у нас теперь будут две стрелки), но мы могли бы использовать funky ie9 selector, чтобы по крайней мере отменить нашу собственную стрелку - оставив стрелку выбора по умолчанию неповрежденными.

/* target Internet Explorer 9 to undo the custom arrow */
@media screen and (min-width:0\0) {
    select {
        background-image:none\9;
        padding: 5px\9;
    } 
}

Все вместе:

select {
  margin: 50px;
  width: 150px;
  padding: 5px 35px 5px 5px;
  font-size: 16px;
  border: 1px solid #ccc;
  height: 34px;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background: url(http://www..com/favicon.ico) 96% / 15% no-repeat #eee;
}


/* CAUTION: IE hackery ahead */


select::-ms-expand { 
    display: none; /* remove default arrow in IE 10 and 11 */
}

/* target Internet Explorer 9 to undo the custom arrow */
@media screen and (min-width:0\0) {
    select {
        background:none\9;
        padding: 5px\9;
    }
}
<select>
  <option>Apples</option>
  <option selected>Pineapples</option>
  <option>Chocklate</option>
  <option>Pancakes</option>
</select>

Это решение легко и имеет хорошую поддержку браузера - этого обычно должно хватить.

Если необходима поддержка браузера для ie9- и firefox 34, продолжайте читать ...

Решение № 2 Усечь элемент выбора, чтобы скрыть стрелку по умолчанию ( Demo )

(Подробнее читайте здесь)

Оберните элемент select в div с фиксированной шириной и overflow:hidden .

Затем дайте элементу select ширину около 20 пикселей больше, чем div .

В результате стрелка раскрывающегося списка по умолчанию элемента select будет скрыта (из-за overflow:hidden в контейнере), и вы можете поместить любое фоновое изображение, которое вы хотите, в правую часть div.

Преимущество такого подхода заключается в том, что это кросс-браузер (Internet Explorer 8 и более поздние WebKit , WebKit и Gecko ). Однако недостатком этого подхода является то, что раскрывающийся список опций выставляется справа (на 20 пикселей, которые мы спрятали ... потому что элементы опций занимают ширину элемента select).

[Следует, однако, отметить, что если пользовательский элемент выбора необходим только для устройств MOBILE, то вышеуказанная проблема не применяется - из-за того, как каждый телефон изначально открывает элемент выбора. Так что для мобильных устройств это может быть лучшим решением.]

.styled select {
  background: transparent;
  width: 150px;
  font-size: 16px;
  border: 1px solid #ccc;
  height: 34px;
}
.styled {
  margin: 50px;
  width: 120px;
  height: 34px;
  border: 1px solid #111;
  border-radius: 3px;
  overflow: hidden;
  background: url(http://www..com/favicon.ico) 96% / 20% no-repeat #eee;
}
<div class="styled">
  <select>
    <option>Pineapples</option>
    <option selected>Apples</option>
    <option>Chocklate</option>
    <option>Pancakes</option>
  </select>
</div>

Если пользовательская стрелка необходима в Firefox - до версии 35, но вам не нужно поддерживать старые версии IE, тогда продолжайте читать ...

Решение # 3 - Используйте свойство pointer-events ( Demo )

(Подробнее читайте здесь)

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

Преимущество: хорошо работает в WebKit и Gecko. Он также выглядит хорошо (без использования элементов option )

Недостаток: Internet Explorer (IE10 и down) не поддерживает pointer-events , что означает, что вы не можете нажать на пользовательскую стрелку. Кроме того, еще один (очевидный) недостаток этого метода заключается в том, что вы не можете настроить таргетинг на новое изображение стрелки с эффектом наведения или курсором, потому что у нас есть только что отключенные события указателей на них!

Однако с помощью этого метода вы можете использовать Модернизатор или условные комментарии, чтобы Internet Explorer возвращался к стандартной встроенной стрелке.

NB: Поскольку Internet Explorer 10 больше не поддерживает conditional comments : если вы хотите использовать этот подход, вероятно, вы должны использовать Modernizr . Тем не менее, все же можно исключить CSS-указатели-события из Internet Explorer 10 с описанным here CSS-хаком.

.notIE {
  position: relative;
  display: inline-block;
}
select {
  display: inline-block;
  height: 30px;
  width: 150px;
  outline: none;
  color: #74646e;
  border: 1px solid #C8BFC4;
  border-radius: 4px;
  box-shadow: inset 1px 1px 2px #ddd8dc;
  background: #fff;
}
/* Select arrow styling */

.notIE .fancyArrow {
  width: 23px;
  height: 28px;
  position: absolute;
  display: inline-block;
  top: 1px;
  right: 3px;
  background: url(http://www..com/favicon.ico) right / 90% no-repeat #fff;
  pointer-events: none;
}
/*target Internet Explorer 9 and Internet Explorer 10:*/

@media screen and (min-width: 0\0) {
  .notIE .fancyArrow {
    display: none;
  }
}
<!--[if !IE]> -->
<div class="notIE">
  <!-- <![endif]-->
  <span class="fancyArrow"></span>
  <select>
    <option>Apples</option>
    <option selected>Pineapples</option>
    <option>Chocklate</option>
    <option>Pancakes</option>
  </select>
  <!--[if !IE]> -->
</div>
<!-- <![endif]-->


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

Работает с IE10 + с надежной защитой для IE8 / 9. Одно из предостережений для этих браузеров заключается в том, что фоновое изображение должно располагаться и быть достаточно маленьким, чтобы скрываться за встроенным элементом управления расширением.

HTML

<select name='options'>
  <option value='option-1'>Option 1</option>
  <option value='option-2'>Option 2</option>
  <option value='option-3'>Option 3</option>
</select>

SCSS

body {
  padding: 4em 40%;
  text-align: center;
}

select {
  $bg-color: lightcyan;
  $text-color: black;
  appearance: none; // using -prefix-free http://leaverou.github.io/prefixfree/
  background: {
    color: $bg-color;
    image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/1255/caret--down-15.png");
    position: right;
    repeat: no-repeat;
  }
  border: {
    color: mix($bg-color, black, 80%);
    radius: .2em;
    style: solid;
    width: 1px;
    right-color: mix($bg-color, black, 60%);
    bottom-color: mix($bg-color, black, 60%);
  }
  color: $text-color;
  padding: .33em .5em;
  width: 100%;
}

// Removes default arrow for IE10+
// IE 8/9 get dafault arrow which covers caret image
// as long as caret image is small than and positioned
// behind default arrow
select::-ms-expand {
    display: none;
}

Codepen

http://codepen.io/ralgh/pen/gpgbGx



Если стиль - важная проблема, использующая полностью настраиваемый виджет, может помочь, например, тот, который описан в блоге Post Reinventing Drop Down с CSS и jQuery .


Используйте свойство clip для обрезания границ и стрелки элемента select , а затем добавьте свои собственные стили замены в оболочку:

    <!DOCTYPE html>
    <html>
      <head>
        <style>
          select { position: absolute; clip:rect(2px 49px 19px 2px); z-index:2; }
          body > span { display:block; position: relative; width: 64px; height: 21px; border: 2px solid green;  background: url(http://www..com/favicon.ico) right 1px no-repeat; }
        </style>
      </head>
      <span>
        <select>
          <option value="">Alpha</option>
          <option value="">Beta</option>
          <option value="">Charlie</option>
        </select>
      </span>
    </html>

Используйте второй выбор с нулевой прозрачностью, чтобы сделать кнопку нажатой:

    <!DOCTYPE html>
    <html>
      <head>
        <style>
          #real { position: absolute; clip:rect(2px 51px 19px 2px); z-index:2; }
          #fake { position: absolute; opacity: 0; }
    
          body > span { display:block; position: relative; width: 64px; height: 21px; background: url(http://www..com/favicon.ico) right 1px no-repeat; }
        </style>
      </head>
      <span>
        <select id="real">
          <option value="">Alpha</option>
          <option value="">Beta</option>
          <option value="">Charlie</option>
        </select>
        <select id="fake">
          <option value="">Alpha</option>
          <option value="">Beta</option>
          <option value="">Charlie</option>
        </select>
      </span>
    </html>

Координаты отличаются между Webkit и другими браузерами, но запрос @media может покрыть это.

Рекомендации



Редактировать этот элемент не рекомендуется, но если вы хотите попробовать, это похоже на любой другой элемент HTML.

Пример редактирования:

/*Edit select*/
select {
    /*css style here*/
}

/*Edit option*/
option {
    /*css style here*/
}

/*Edit selected option*/
/*element  attr    attr value*/
option[selected="selected"] {
    /*css style here*/
}

<select>
    <option >Something #1</option>
    <option selected="selected">Something #2</option>
    <option >Something #3</option>
</select>

Сообщение в блоге Как стирать CSS-форму, JavaScript не работает для меня, но в Opera это не работает:

select {
    border: 0 none;
    color: #FFFFFF;
    background: transparent;
    font-size: 20px;
    font-weight: bold;
    padding: 2px 10px;
    width: 378px;
    *width: 350px;
    *background: #58B14C;
}

#mainselection {
    overflow: hidden;
    width: 350px;
    -moz-border-radius: 9px 9px 9px 9px;
    -webkit-border-radius: 9px 9px 9px 9px;
    border-radius: 9px 9px 9px 9px;
    box-shadow: 1px 1px 11px #330033;
    background: url("arrow.gif") no-repeat scroll 319px 5px #58B14C;
}

<div id="mainselection">
    <select>
    <option>Select an Option</option>
    <option>Option 1</option>
    <option>Option 2</option>
    </select>
</div>

Теги <select> могут быть стилизованы через CSS так же, как и любой другой элемент HTML на странице HTML, отображаемой в браузере. Ниже приведен пример (слишком простой), который будет позиционировать элемент выбора на странице и отобразить текст вариантов в синем.

Пример файла HTML (selectExample.html):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <title>Select Styling</title>
  <link href="selectExample.css" rel="stylesheet">
</head>
<body>
<select id="styledSelect" class="blueText">
  <option value="apple">Apple</option>
  <option value="orange">Orange</option>
  <option value="cherry">Cherry</option>
</select>
</body>
</html>

Пример файла CSS (selectExample.css):

/* All select elements on page */
select {
  position: relative;
}

/* Style by class. Effects the text of the contained options. */
.blueText {
  color: #0000FF;
}

/* Style by id. Effects position of the select drop down. */
#styledSelect {
  left: 100px;
}

Элемент select и его раскрывающийся список сложны для стиля.

атрибуты стиля для выбранного элемента Криса Хейлмана подтверждают, что Райан Дохери сказал в комментарии к первому ответу:

«Элемент select является частью операционной системы, а не браузера хром, поэтому он очень ненадежен для стиля, и в любом случае не имеет смысла пытаться».


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

select {
    -webkit-appearance: button;
    -moz-appearance: button;
    -webkit-user-select: none;
    -moz-user-select: none;
    -webkit-padding-end: 20px;
    -moz-padding-end: 20px;
    -webkit-padding-start: 2px;
    -moz-padding-start: 2px;
    background-color: #F07575; /* fallback color if gradients are not supported */
    background-image: url(../images/select-arrow.png), -webkit-linear-gradient(top, #E5E5E5, #F4F4F4); /* For Chrome and Safari */
    background-image: url(../images/select-arrow.png), -moz-linear-gradient(top, #E5E5E5, #F4F4F4); /* For old Fx (3.6 to 15) */
    background-image: url(../images/select-arrow.png), -ms-linear-gradient(top, #E5E5E5, #F4F4F4); /* For pre-releases of IE 10*/
    background-image: url(../images/select-arrow.png), -o-linear-gradient(top, #E5E5E5, #F4F4F4); /* For old Opera (11.1 to 12.0) */ 
    background-image: url(../images/select-arrow.png), linear-gradient(to bottom, #E5E5E5, #F4F4F4); /* Standard syntax; must be last */
    background-position: center right;
    background-repeat: no-repeat;
    border: 1px solid #AAA;
    border-radius: 2px;
    box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
    color: #555;
    font-size: inherit;
    margin: 0;
    overflow: hidden;
    padding-top: 2px;
    padding-bottom: 2px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

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

Самой важной частью является свойство appearance , которое изменяет поведение элемента.

Он отлично работает практически во всех браузерах на базе Webkit, включая мобильные, хотя Gecko не поддерживает appearance а также Webkit.


Решение только для CSS и HTML

Я считаю совместимым с Chrome, Firefox и IE11. Но, пожалуйста, оставьте отзыв о других веб-браузерах.

Как было предложено в ответ @Danield, я переношу свой выбор в div (даже два div для совместимости с x-браузером), чтобы получить ожидаемое поведение.

См. Http://jsfiddle.net/bjap2/

HTML:

<div class="sort-options-wrapper">
    <div class="sort-options-wrapper-2">
        <select class="sort-options">
                <option value="choiceOne">choiceOne</option>
                <option value="choiceOne">choiceThree</option>
                <option value="choiceOne">choiceFour</option>
                <option value="choiceFiveLongTestPurpose">choiceFiveLongTestPurpose</option>
        </select>
    </div>
    <div class="search-select-arrow-down"></div>
</div>

Обратите внимание на 2 обертки. Также обратите внимание на добавление дополнительного div, чтобы поместить стрелку вниз, где бы вы ни находились (позиционируется абсолютно), здесь мы помещаем ее слева.

CSS

.sort-options-wrapper {
    display: inline-block;
    position: relative;
    border: 1px solid #83837f;
}
/* this second wrapper is needed for x-browser compatibility */
.sort-options-wrapper-2 {
    overflow: hidden;
}
select {
    margin-right: -19px; /* that's what hidding the default-provided browser arrow */
    padding-left: 13px;
    margin-left: 0;
    border: none;
    background: none;
    /* margin-top & margin-bottom must be set since some browser have default values for select elements */
    margin-bottom: 1px;
    margin-top: 1px;
}
select:focus {
    outline: none; /* removing default browsers outline on focus */
}
.search-select-arrow-down {
    position: absolute;
    height:10px;
    width: 12px;
    background: url(http://i.imgur.com/pHIYN06.png) scroll no-repeat 2px 0px;
    left: 1px;
    top: 5px;
}

Существует способ стилизации тегов SELECT.

Если в теге есть параметр «размер», применяется практически любой CSS. Используя этот трюк, я создал скрипку, которая практически эквивалентна обычным тегам select, плюс значение можно редактировать вручную, как ComboBox на визуальных языках (если только вы не вставляете readonly во входной тег).

Итак, вот минимальный пример, чтобы понять принцип:
(вам понадобится jQuery для механизма щелчка) :

<style>

    /* only these 2 lines are truly required */
    .stylish span {position:relative;}
    .stylish select {position:absolute;left:0px;display:none}

    /* now you can style the hell out of them */
    .stylish input    { ... }
    .stylish select   { ... }
    .stylish option   { ... }
    .stylish optgroup { ... }

</style>
...
<div class="stylish">
    <label> Choose your superhero: </label>
    <span>
        <input onclick="$(this).closest('div').find('select').slideToggle(110)">
        <br>
        <select size=15 onclick="$(this).hide().closest('div').find('input').val($(this).find('option:selected').text());">

            <optgroup label="Fantasy"></optgroup>
            <option value="gandalf">Gandalf</option>
            <option value="harry">Harry Potter</option>
            <option value="jon">Jon Snow</option>

            <optgroup label="Comics"></optgroup>
            <option value="tony">Tony Stark</option>
            <option value="steve">Steven Rogers</option>
            <option value="natasha">Natasha Romanova</option>

        </select>
    </span>
</div>

Вот скрипка с несколькими стилями: https://jsfiddle.net/dkellner/7ac9us70/

(Конечно, это слишком сложно, просто чтобы продемонстрировать возможности.)

Обратите внимание, как теги не инкапсулируют параметры, принадлежащие им, как они обычно должны; да, это намеренно, это для стиля. (Добродетельный способ был бы намного менее стильным.) И да, они отлично работают.

Прежде чем кто-нибудь отметит часть NO-JS: я знаю, что в вопросе говорилось «нет Javascript». Для меня это больше похоже на то, что не надо с плагинами, я знаю, что они могут это сделать, но мне нужен родной путь . Понятно, никаких плагинов, никаких дополнительных скриптов, только то, что помещается внутри тега «onclick». Единственная зависимость - это jQuery, чтобы избежать безумства «document.parentNode.getElementsByTagName». Но это может сработать. Так что да, это родной тег select с родным стилем и некоторыми обработчиками onclick. Это явно не «решение Javascript».

Наслаждайтесь!


Второй способ в ответе Данелда ( https://.com/a/13968900/280972 ) можно улучшить для работы с эффектами зависания и другими событиями мыши. Просто убедитесь, что элемент «button» появляется сразу после элемента select в разметке. Затем настройте его с помощью селектора + css:

HTML:

<select class="select-input">...</select>
<div class="select-button"></div>

CSS:

.select-input:hover+.select-button {
    [hover styles here]
}

Это, однако, покажет эффект наведения при наведении указателя на любой элемент над элементом select, а не на кнопку «.

Я использую этот метод в сочетании с Angular (так как мой проект, как правило, является Angular-app), чтобы охватить весь элемент select, и пусть Angular отображает текст выбранной опции в элементе «button». В этом случае имеет смысл, что эффект зависания применяется при падении в любом месте над выбором. Однако он не работает без javascript, поэтому, если вы хотите это сделать, и ваш сайт должен работать без javascript, вы должны убедиться, что ваш скрипт добавляет элементы и классы, необходимые для улучшения. Таким образом, браузер без javascript просто получит нормальный, неэкранированный, выберите, а не стилизованный значок, который не будет корректно обновляться.


label {
    position: relative;
    display: inline-block;
}
select {
    display: inline-block;
    padding: 4px 3px 5px 5px;
    width: 150px;
    outline: none;
    color: black;
    border: 1px solid #C8BFC4;
    border-radius: 4px;
    box-shadow: inset 1px 1px 2px #ddd8dc;
    background-color: lightblue;
}

Это использует цвет фона для отдельных элементов, и я удалил изображение.





skinning