Is it possible to center text in select box?

Css

Css Problem Overview


I tried this: http://jsfiddle.net/ilyaD/KGcC3/

HTML:

<select name="state" class="ddList">
    <option value="">(please select a state)</option>
    <option class="lt" value="--">none</option>
    <option class="lt" value="AL">Alabama</option>
    <option class="lt" value="AK">Alaska</option>
    <option class="lt" value="AZ">Arizona</option>
    <option class="lt" value="AR">Arkansas</option>
    <option class="lt" value="CA">California</option>
    <option class="lt" value="CO">Colorado</option>
</select>

CSS:

select { width: 400px; text-align: center; }
select .lt { text-align: center; }

As you can see, it doesn't work. Is there a CSS-only way to center text in the select-box?

Css Solutions


Solution 1 - Css

There is a partial solution for Chrome:

select { width: 400px; text-align-last:center; }

It does center the selected option, but not the options inside the dropdown.

Solution 2 - Css

That's for align right. Try it:

select{
    text-align-last:right;
    padding-right: 29px;
    direction: rtl;
}

the browser support for the text-align-last attribute can be found here: https://www.w3schools.com/cssref/css3_pr_text-align-last.asp It looks like only Safari is still not supporting it.

Solution 3 - Css

You have to put the CSS rule into the select class.

Use CSS text-indent

Example

<select class="day"> /* option 1 option 2 option 3 option 4 option 5 here */ </select>

CSS code

select { text-indent: 5px; }

Solution 4 - Css

Yes, it is possible. You can use text-align-last

text-align-last: center;

Solution 5 - Css

2020, Im using:

select {
	text-align: center;
    text-align-last: center;
    -moz-text-align-last: center;
}

Solution 6 - Css

I'm afraid this isn't possible with plain CSS, and won't be possible to make completely cross-browser compatible.

However, using a jQuery plugin, you could style the dropdown:

https://www.filamentgroup.com/lab/jquery-ui-selectmenu-an-aria-accessible-plugin-for-styling-a-html-select.html

This plugin hides the select element, and creates span elements etc on the fly to display a custom drop down list style. I'm quite confident you'd be able to change the styles on the spans etc to center align the items.

Solution 7 - Css

just using this:

select {

text-align-last: center;
padding-right: 29px;

}

Solution 8 - Css

select {
  text-align: center;
  text-align-last: center;
}
option {
  text-align: left;
}

<select>
   <option value="">(please select a state)</option>
   <option class="lt" value="--">none</option>
   <option class="lt" value="AL">Alabama</option>
   <option class="lt" value="AK">Alaska</option>
   <option class="lt" value="AZ">Arizona</option>
   <option class="lt" value="AR">Arkansas</option>
   <option class="lt" value="CA">California</option>
   <option class="lt" value="CO">Colorado</option>
</select>

Solution 9 - Css

This JS function should work for you

function getTextWidth(txt) {
  var $elm = $('<span class="tempforSize">'+txt+'</span>').prependTo("body");
  var elmWidth = $elm.width();
  $elm.remove();
  return elmWidth;
}
function centerSelect($elm) {
    var optionWidth = getTextWidth($elm.children(":selected").html())
    var emptySpace =   $elm.width()- optionWidth;
    $elm.css("text-indent", (emptySpace/2) - 10);// -10 for some browers to remove the right toggle control width
}
// on start 
$('.centerSelect').each(function(){
  centerSelect($(this));
});
// on change
$('.centerSelect').on('change', function(){
  centerSelect($(this));
});

Full Codepen here: http://codepen.io/anon/pen/NxyovL

Solution 10 - Css

I have always gotten away with the following hack to get it to work with css only.

padding-left: 45%;
font-size: 50px;

padding will center the text and can be tweaked for the text size :)

This is obviously not 100% correct from a validation point of view I guess but it does the job :)

Solution 11 - Css

Alternative "fake" solution if you have a list with options similar in text length (page select for example):

padding-left: calc(50% - 1em);

This works in Chrome, Firefox and Edge. The trick is here to push the text from the left to the center, then substract the half of length in px, em or whatever of the option text.

enter image description here

Best solution IMO (in 2017) is still replacing the select via JS and build your own fake select-box with divs or whatever and bind click events on it for cross-browser support.

Solution 12 - Css

Not quite Centering but using example above you can make a left margin in select box.

<style>.UName { text-indent: 5px; }</style><br>

<select  name="UserName" id="UserName" size="1">
    <option class="UName" selected value="select">Select User</option>
    <option class="UName" value="User1">User 1 Name</option>
    <option class="UName" value="User2">User 2 Name </option>
    <option class="UName" value="User3">User 3 Name</option>
</select>

Solution 13 - Css

this worked for me:

text-align: center;
text-align-last: center;

Solution 14 - Css

try this :

select {
    padding-left: 50% !important;
    width: 100%;
}

Solution 15 - Css

You can't really customise <select> or <option> much. The only way (cross-browser) would be to manually create a drop down with divs and css/js to create something similar.

Solution 16 - Css

If you didn't find any solution, you can use this trick on angularjs or using js to map selected value with a text on the div, this solution is full css compliant on angular but need a mapping between select and div:

var myApp = angular.module('myApp', []);

myApp.controller('selectCtrl', ['$scope',
  function($scope) {
    $scope.value = '';


  }
]);

.ghostSelect {
  opacity: 0.1;
  /* Should be 0 to avoid the select visibility but not visibility:hidden*/
  display: block;
  width: 200px;
  position: absolute;
}
.select {
  border: 1px solid black;
  height: 20px;
  width: 200px;
  text-align: center;
  border-radius: 5px;
  display: block;
}

<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Example - example-guide-concepts-1-production</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body ng-app="myApp">
  <div ng-app ng-controller="selectCtrl">
    <div class=select>
      <select ng-model="value" class="ghostSelect">
        <option value="Option 1">Option 1</option>
        <option value="Option 2">Option 2</option>
        <option value="Option 3">Option 3</option>
      </select>
      <div>{{value}}
      </div>
    </div>
  </div>
</body>

Hope this could be useful for someone as it took me one day to find this solution on phonegap.

Solution 17 - Css

While you cannot center the option text within a select, you can lay an absolutely positioned div over the top of the select to the same effect:

#centered
{
  position: absolute;
  top: 10px;
  left: 10px;
  width: 818px;
  height: 37px;
  text-align: center;
  font: bold 24pt calibri;
  background-color: white;
  z-index: 100;
}

#selectToCenter
{
  position: absolute;
  top: 10px;
  left: 10px;
  width: 840px;
  height: 40px;
  font: bold 24pt calibri;
}

$('#selectToCenter').on('change', function () {
    $('#centered').text($(this).find('option:selected').text());
});

<select id="selectToCenter"></select>
<div id="centered"></div>

Make sure the both the div and select have fixed positions in the document.

Solution 18 - Css

On your select use width: auto and no padding to see how long your text is. I'm using 100% available width on my select and all of my options have the same length, this allows me to use very simple css.

text-indent will move the text from left, similar to padding-left
120px is my text length - I want to center it so take half of that size and half of the select size, leaving me with 50% - 60px

select{
  width: 100%;
  text-indent: calc(50% - 60px);
}

What if I have different sizes of options?

It is possible, however, the solution will not be a pretty one.
The former solution might get you really close to being centered if the difference between options isn't like 5 characters.

If you still need to center it more precisely you can do this

Prepare this class:

.realWidth{
   width: auto;
}

Apply onChange listener to select element

In that listener apply .realWidth to the select element with

const selectRef = document.getElementById("yourId");
selectRef.classList.add("realWidth");

Get access to the real width of the option.

const widthOfSelect = selectRef.getBoundingClientRect().width / 2;

widthOfSelect is the width you are looking for. Store it in global/component variable.

Remove the realWidth, you don't need it anymore.

selectRef.classList.remove("realWidth");

I am using react, I'm not sure this will work in vanilla, if not you have to find another solution.

<select style={`textIndent: calc(50% - ${widthOfSelect}) %`}> ... </select>

Another solution, however, that is a bad one could be creating the CSS classes with js and putting it to head.

PROS:

  1. probably works, I haven't tried the dynamic solution but it should work.

CONS:

  1. if the program is not fast enough user will see the width: auto taking place and thus wonder what's going on. If that is the case just create duplicate select, hide it behind something with a higher z-index and apply the on select listener from the original to the hidden duplicate.
  2. Might be hard to use if you cant inline the style because of vanilla limitation, but you can make a script to optimize the appendChild to the head.

Solution 19 - Css

I ran into this issue where a client was insisting on this, and they were on a Mac and and iPhone.

I wound up using media queries and a percentage padding for padding-left. Was this a satisfying solution? Not at all, but it let me move on.

Solution 20 - Css

Easiest way: Use padding-left

select{
   padding-left:2rem
}

Solution 21 - Css

It's not 100% yet, but you can use this snippet!

text-align-last: center; // For Chrome text-align: center; // For Firefox

Doesn't work on Safari or Edge, for now!

Solution 22 - Css

if the options are static, you could listen for the change event on your select box and add padding for each individual item

$('#id').change(function() {
    var select = $('#id');
    var val = $(this).val();

    switch(val) {
        case 'ValOne':
            select.css('padding-left', '30px');
            break;
        case 'ValTwoLonger':
            select.css('padding-left', '20px');
             break;
        default:
            return;
    }
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionilyoView Question on Stackoverflow
Solution 1 - CssJulian CardenasView Answer on Stackoverflow
Solution 2 - CssAly-ElgarhyView Answer on Stackoverflow
Solution 3 - Cssmarc carrerasView Answer on Stackoverflow
Solution 4 - CssManjeet Kumar NaiView Answer on Stackoverflow
Solution 5 - CssjzuhriView Answer on Stackoverflow
Solution 6 - CssCurtisView Answer on Stackoverflow
Solution 7 - CssAouidane Med AmineView Answer on Stackoverflow
Solution 8 - CssJamie HutberView Answer on Stackoverflow
Solution 9 - CssMr. SmeeView Answer on Stackoverflow
Solution 10 - CssBen PretoriusView Answer on Stackoverflow
Solution 11 - CssDennis HeidenView Answer on Stackoverflow
Solution 12 - CssRichardView Answer on Stackoverflow
Solution 13 - CssDiego Santa Cruz MendezúView Answer on Stackoverflow
Solution 14 - CsshmahdaviView Answer on Stackoverflow
Solution 15 - CssEmmanuelView Answer on Stackoverflow
Solution 16 - Cssjup31View Answer on Stackoverflow
Solution 17 - CssszozzView Answer on Stackoverflow
Solution 18 - CssLukáš BrýlaView Answer on Stackoverflow
Solution 19 - CssredcartelView Answer on Stackoverflow
Solution 20 - CssTanishka BansalView Answer on Stackoverflow
Solution 21 - CssalvescleitonView Answer on Stackoverflow
Solution 22 - CssBrian ParksView Answer on Stackoverflow