Is it possible to center text in select box?
CssCss 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:
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.
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:
- probably works, I haven't tried the dynamic solution but it should work.
CONS:
- 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.
- 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;
}
});