Вопрос:

Есть ли способ CSS для автоматической установки ширины элемента в зависимости от размера текстовых строк?

css select width

90 просмотра

2 ответа

1092 Репутация автора

Я создаю стилизованное меню выбора, в котором я создаю неупорядоченный список, который заменяет мой элемент выбора.

<div class="select">
    <select name="distance" id="distance" class="select-hidden">
        <option value="5.0 5"><font><font>5 mi</font></font></option>
        <option value="6.0 4">6 km</option>
        <option value="10.0 4" selected="selected"><font><font>10 km</font></font></option></select><div class="select-styled">10 km</div><ul class="select-options" style="display: none;"><li rel="5.0 5"><font><font>5 mi</font></font></li><li rel="6.0 4"><font><font>6 km</font></font></li><li rel="10.0 4"><font><font>10 km</font></font></li></ul>
</div>

Тогда у меня есть этот стиль

.select {
  cursor: pointer;
  display: inline-block;
  position: relative;
  font-size: 16px;
  color: #000000;
  width: 220px;
  height: 42px;
}

Сейчас я жестко программирую ширину (220 пикселей), и мой вопрос заключается в том, могу ли я построить ее менее жестким способом, чтобы ширина автоматически соответствовала ширине самого длинного имени элемента? Вот Скрипка, которая иллюстрирует мою дилемму - https://jsfiddle.net/n73ao02h/13/ .

Автор: Dave Источник Размещён: 22.08.2016 08:50

Ответы (2)


0 плюса

389 Репутация автора

Не устанавливайте ширину и не устанавливайте отображение: ни один на выбор, плюс установите white-space:nowrapна свой стиль div.select:

$(function() {

        $('select').each(function(){
            styleSelectMenu($(this));
        });

});

// This method applies the styles to our select menu
function styleSelectMenu(selectMenu)
{
    var $this = $(selectMenu), numberOfOptions = $(selectMenu).children('option').length;

    $this.addClass('select-hidden');
    if ( !$this.parent().hasClass('select') ) {
        $this.wrap('<div class="select"></div>');
    }   // if
    if ( !$this.next().hasClass('select-styled') ) {
        $this.after('<div class="select-styled"></div>');
    }    // if

    var $styledSelect = $this.next('div.select-styled');
    $styledSelect.text($this.children('option').eq(0).text());

    if ( $styledSelect.parent().find('ul').length > 0 ) {
        $styledSelect.parent().find('ul').remove();
    }   // if
    var $list = $('<ul />', {
        'class': 'select-options'
    }).insertAfter($styledSelect);

    for (var i = 0; i < numberOfOptions; i++) {
        $('<li />', {
            text: $this.children('option').eq(i).text(),
            rel: $this.children('option').eq(i).val()
        }).appendTo($list);
    }

    var $listItems = $list.children('li');

    // This is the event when someone opens the list
    $styledSelect.unbind('click')
    $styledSelect.click(function(e) {
        e.stopPropagation();
        $('div.select-styled.active').each(function(){
            $(this).removeClass('active').next('ul.select-options').hide();
        });
        $(this).toggleClass('active').next('ul.select-options').toggle();
    });

    // This is the event when someone actually selects something from the list
    $listItems.unbind('click.selectStyledItem')
    $listItems.bind('click.selectStyledItem', function(event) {
         clickListItem($styledSelect, $this, $(this), $list);
    });

    $(document).click(function() {
        $styledSelect.removeClass('active');
        $list.hide();
    });
    

    var selectedIndex = $this[0].selectedIndex;
    if (selectedIndex > 0) {
        var name = $this.attr("name")
        var selectedText = $( "select[name='" + name + "'] option:selected" ).text();
        selectItemFromStyledList($styledSelect, $this, selectedText, $list);
    }   // if

}

// This is the method that will select an item from the styled list
function selectItemFromStyledList(styledSelect, selectMenu, selectedText, listToHide)
{
    $(styledSelect).text(selectedText).removeClass('active');
    $(selectMenu).val($(selectMenu).attr('rel'));
    $(listToHide).hide();
    // Select option in the underlying list so that the form gets submitted
    // with the right values
    selectedOption = $(selectMenu).find("option").filter(function () { return $(this).html() == selectedText; });
    $(selectMenu).find("option[selected='selected']").removeAttr("selected");
    $(selectedOption).attr("selected","selected");
}       // selectItemFromStyledList

// Called when someone clicks an item from the styled list
// The event data should contain the following parameters:
//      styledSelect - the <div> element that contains the styled menu
//      selectMenu - the actual form element that contains the items
//      listItemClicked - the item that was clicked.
//      list - THe <UL> element containig the <li> options
function clickListItem(styledSelect, selectMenu, listItemClicked, list)
{
        var $styledSelect = $(styledSelect);
        var $selectMenu = $(selectMenu);
        var $listItem = $(listItemClicked);
        var $list = $(list);

        event.stopPropagation();
        var selectedText = $listItem.text();
        selectItemFromStyledList($styledSelect, $selectMenu, selectedText, $list)
}       // clickListItem
#statSearchFields {
    vertical-align: top;
    font-size: 90%;
}

.selectMenu {
        font-family: 'Oxygen', sans-serif;
        font-size: 20px;
        height: 50px;
        -webkit-appearance: menulist-button;
}

.select-hidden {
  visibility: hidden;
  padding-right: 10px;
}

.select {
  cursor: pointer;
  display: inline-block;
  position: relative;
  font-size: 16px;
  color: black;
  height: 42px;
}
.select-styled {
    white-space: nowrap;
}
.select-styled {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: gray;
  padding: 11px 12px;
  @include transition(all 0.2s ease-in);
  &:after {
    content:"";
    width: 0;
    height: 0;
    border: 7px solid transparent;
    border-color: black transparent transparent transparent;
    position: absolute;
    top: 16px;
    right: 10px;
  }
  &:hover {
    background-color: darken(gray, 2);
  }
  &:active, &.active {
    background-color: darken(gray, 5);
    &:after {
      top: 9px;
      border-color: transparent transparent $select-color transparent;
    }
  }
}

.select-options {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  left: 0;
  z-index: 999;
  margin: 0;
  padding: 0;
  list-style: none;
  background-color: darken(gray, 5);
  overflow: scroll;
  li {
    margin: 0;
    padding: 12px 0;
    text-indent: 15px;
    border-top: 1px solid darken(gray, 10);
    @include transition(all 0.15s ease-in);
    &:hover {
      color: gray;
      background: black;
    }
    &[rel="hide"] {
      display: none;
    }
  }
}

#statSearchContainer {
  padding: 10px;
  font-family: "Calibre", "Helvetica Neue", "Helvetica", "Roboto", "Arial", sans-serif;
  background-color: tan;
  display: table;
}
#statSearchContainer h1 {
  margin: 5px 0;
  font-size: 1.0em;
}
#stat-search-form {
  display: block;
  padding: 0px;
}
#stat-search-form form input {
  vertical-align: middle;
}


#statSearchFields {
    vertical-align: top;
    font-size: 90%;
}

.searchField {
    display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="statSearchContainer">

	<div class="searchField">
	Distance<br/>
	<select name="distance" id="distance"><option value="5.0 5">5 mi</option>
<option value="6.0 4">6 km</option>
<option selected="selected" value="10.0 4">10 km</option></select>
	</div>

	<input alt="Search" type="image" src="/assets/magnifying-glass-0220f37269f90a370c3bb60229240f2ef2a4e15b335cd42e64563ba65e4f22e4.png" class="search_button">
</div>
</div>

Автор: Fabien Размещён: 22.08.2016 08:59

0 плюса

1686 Репутация автора

Решение

Как насчет этого: https://jsfiddle.net/n73ao02h/14/

Поле выбора без какого-либо widthстиля всегда будет соответствовать его параметрам. Итак, мы используем это ...

Первый шаг - удалить фиксированную ширину.
Мы получаем ширину в JS, прежде чем добавить display:noneк ней.
Затем мы генерируем временный элемент styled-selectс нулевой шириной, чтобы автоматически получить заполнение, определенное в CSS, без его жесткого кодирования.

Затем у нас есть все, что нам нужно, чтобы рассчитать новую ширину вашего стилизованного блока выбора:

    /* ... */
    var $paddingCalculator = $('<div />', {
        'class' : "select-styled test"
    }).css({
        width : 0,
        visibility : "hidden"
    }).appendTo("body");
    var paddingWidth = $paddingCalculator.outerWidth();
    $paddingCalculator.remove();

    var selectWidth = $this.width() + paddingWidth;

    $this.addClass('select-hidden');
    if ( !$this.parent().hasClass('select') ) {
        var $wrapper = $("<div />", {
            'class' : "select"
        }).css({
            width : selectWidth
        });
        $this.wrap( $wrapper );
    }   // if
    /* ... */


небольшое дополнение:
имейте в виду, что оба - исходное поле выбора и ваш стилизованный div - должны иметь одинаковый размер шрифта (и все, что связано со стилем текста, например, font-family, font-weight, letter-spacing, .. .) чтобы рассчитанные размеры были правильными.

Автор: Seika85 Размещён: 23.08.2016 06:22
Вопросы из категории :
32x32