Better Variation Selection Dropdowns

Sometimes you have those situation in WooCommerce that you need to style <select> elements, but you don’t want to, because it’s messy and you are tempted to add another plugin to your growing stack! But, wait, there are some really good solutions out there that don’t make you fiddle with WooCommerce itself, but directly with the frontend. Just with JS and CSS you can modify the dropdowns for your variation selections or other prebuilt select fields that you might encounter.

This is for now the best solution I found (credit goes to w3 or another source) for custom select dropdowns. Add also the SCSS to it and you get your self a highly customizable select html tag.

$('select').each(function(){
        var $this = $(this), numberOfOptions = $(this).children('option').length;

        $this.addClass('select-hidden');
        $this.wrap('<div class="select"></div>');
        $this.after('<div class="select-styled"></div>');

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

        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');

        $styledSelect.click(function(e) {
            e.stopPropagation();
            $('div.select-styled.active').not(this).each(function(){
                $(this).removeClass('active').next('ul.select-options').hide();
            });
            $(this).toggleClass('active').next('ul.select-options').toggle();
        })




        $listItems.click(function(e) {
            e.stopPropagation();
            $styledSelect.text($(this).text()).removeClass('active');
            $this.val($(this).attr('rel'));
            $list.hide();

            var originalSelect = $list.parent().find('select');
            originalSelect.trigger('change');

            originalSelect.val($(this).attr('rel'))
            originalSelect.addClass('selected');
            console.log(originalSelect.val())
        });



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

    });

Here is the SASS that goes with it. Pay close attention to:

  1. The hidden old select field. In the JS, this is added to the original <select> tag, and in the CSS you can see its hidden. We don’t want it, we want something more fun.
  2. The active classes, they are used to activate the dropdown basically. And can allow you to animate the dropdown.
  3. The options from the original <select> become actual <li> in your new dropdown.
.select-hidden {
  display: none;
  visibility: hidden;
  padding-right: 10px;
}

$background: transparent;
$select-color: $white;
$select-background: transparent;
$select-width: 100%;
$select-height: 40px;
$white: #fff;

.select {
  margin-top:20px;
  cursor: pointer;
  display: inline-block;
  position: relative;
  font-size: 16px;
  color: $select-color;
  width:$select-width;
  height: $select-height;
  border-bottom: solid 1px $white;
}
.select-styled {

  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: $select-background;
  transition: all 0.2s ease-in;
  text-transform: uppercase;
  font-size: 20px;
  color:$white;
  font-weight: normal;
  line-height: 0.8;
  padding:0;
  &:after {
    content:"";
    background-image: url("data:image/svg+xml;charset=utf8,%3Csvg width='17' height='12' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2 2l6.5 7L15 2' stroke='%23FCFBF7' stroke-width='4' fill='none' fill-rule='evenodd'/%3E%3C/svg%3E");
    top: 20%;
    background-size: 15px;
    background-repeat: no-repeat;
    width: 15px;
    height: 12px;
    position: absolute;
    right: 10px;
    transition:all 0.3s ease-in;
  }
  &:hover {
    background-color: darken($select-background, 2);
  }
  &:active, &.active {
    background-color: darken($select-background, 5);
    &:after {
      transform: rotateX(180deg);
      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: $select-color;
  li {
    margin: 0;
    padding: 12px 0;
    text-indent: 15px;
    border-top: 1px solid darken($select-background, 10);
    color:$dark-forest-green;
    &:hover {
      color: $select-background;
      background: $select-color;
    }
    &[rel="hide"] {
      display: none;
    }
  }
}

Best of luck with this and your next WooCommerce project! Let me know if it works 🙂

Leave a Reply