有没有一种CSS方法可以根据文本字符串的大小自动设置元素的宽度?

时间:2016-08-22 20:50:55

标签: css select width

我正在创建一个样式化的选择菜单,其中我正在设置一个替换我的select元素的无序列表。

<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;
}

现在我正在对宽度进行硬编码(220px),我的问题是我可以用一种不太严格的方式来构建它,这样宽度将自动成为最长元素名称的宽度吗?这是解释我的困境的小提琴 - https://jsfiddle.net/n73ao02h/13/

2 个答案:

答案 0 :(得分:0)

不要设置宽度,不要在select上设置display:none,在div.select-styled上设置white-space:nowrap

&#13;
&#13;
$(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
&#13;
#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;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

那是怎么回事:https://jsfiddle.net/n73ao02h/14/

没有任何width的选择框将始终根据其选项进行设置。所以我们用它......

第一步是移除固定宽度 在我们添加display:none之前,我们在JS中获得宽度 然后,我们生成一个零宽度的临时元素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,...)所以计算的尺寸是正确的。