rlandster
rlandster

Reputation: 7835

Styling part of the OPTION text

I have a SELECT list with several OPTION elements. Here is my naive approach to styling part of the option text:

<select name="color">
<option value="0">red <span style="font-weight: bold;">SLOW</span></option>
<option value="1">blue <span style="font-weight: bold;">SLOWER</span></option>
<option value="2">green <span style="font-weight: bold;">SLOWEST</span></option>
</select>

This does not work: the browser does not like a SPAN element inside the OPTION element.

Is there some other way to style part of an OPTION element's text?

Upvotes: 43

Views: 53268

Answers (8)

Johnny Cache
Johnny Cache

Reputation: 85

While you can't put markup within an OPTION element, you can use the CSS ::BEFORE and/or ::AFTER pseudo-elements and give them different styles. For example this will create a SELECT element with bolded numbers for each OPTION.

Note: I haven't tried this with all browsers yet, but it should work with all the modern ones.

option::before {
  content: attr(value) ":";
  display: inline-block;
  padding-right: 3px;
  padding-left: 1px;
  font-weight: bold;
  width: 1.6em;
  text-align: right;
}
<select name=menu multiple size=4>
  <option value=1>Hamburger</option>
  <option value=2>Cheeseburger</option>
  <option value=3>Hot Dog</option>
  <option value=4>Fries</option>
</select>

Upvotes: 2

SarangRN
SarangRN

Reputation: 140

You can achieve this using react js react-select options as below.

enter image description here

enter image description here

import { useEffect, useState } from "react";
import Select from "react-select";

function App(props) {
  //const options = compliments;
  const [state, setState] = useState({
    rows: [
      {
        rowId: 0,
        config: ""
      }
    ],
    id: 1
  });
  const [configOpts, setConfigOpts] = useState([]);

  const configstyles = {
    control: (styles, { isFocused, isSelected }) => ({
      ...styles,
      backgroundColor: "white",
      borderColor: isSelected ? "yellow" : "grey"
    }),
    option: (styles, { data, isDisabled, isFocused, isSelected }) => ({
      ...styles,
      width: "auto"
    }),
    singleValue: (styles, { data }) => ({
      ...styles,
      ":before": {
        borderRadius: 10,
        content: data.label === "Test3" ? '"Red"' : '"Green"',
        color: data.label === "Test3" ? "Red" : "Green",
        display: "inline",
        marginRight: 8,
        height: 10,
        width: 10
      }
    }),
    menu: (styles) => ({
      ...styles,
      width: "max-content",
      minWidth: "100%"
    })
    // Input: (styles) => ({ ...styles, width: "auto" })
  };

  const handleAddRow = () => {
    const newRow = {
      rowId: state.id,
      config: ""
    };
    setState({
      ...state,
      rows: [...state.rows, newRow],
      id: state.id + 1
    });
  };

  const handleRemoveRow = (idx) => () => {
    const rows = state.rows.filter((FilterdRow) => FilterdRow.rowId !== idx);
    console.log("rows", rows);

    setState({
      ...state,
      rows
    });
  };

  const handleConfigChange = (index) => (selectedOption) => {
    console.log("SelectedOption: " + selectedOption.label);
    const rows = state.rows.map((row) => {
      if (row.id === index) {
        return {
          ...row,
          ["config"]: selectedOption.label
        };
      }
      return row;
    });
    setState({
      ...state,
      rows
    });
  };

  useEffect(() => {
    setConfigOpts([
      { label: "Test11111111111111111111111111", value: "Test1" },
      { label: "Test2", value: "Test2" },
      { label: "Test3", value: "Test3" },
      { label: "Test4", value: "Test4" }
    ]);
  }, []);

  return (
    <>
      <table>
        {state.rows.map((item, idx) => (
          <tr key={item.rowId}>
            <td>
              <Select
                options={configOpts}
                onChange={handleConfigChange(item.rowId)}
                styles={configstyles}
              />
            </td>
            <td>
              <button onClick={handleRemoveRow(item.rowId)}>Remove</button>
            </td>
          </tr>
        ))}
      </table>
      <div>
        <button onClick={handleAddRow}>Add</button>
      </div>
    </>
  );
}

export default App;

CodeSandbox

Upvotes: 0

Nikhil K S
Nikhil K S

Reputation: 9

Permitted content in the option tag is Text, possibly with escaped characters (like é).MDN doc for more details

Upvotes: 0

mlt
mlt

Reputation: 1659

This is more like an answer / workaround to the question closed as a duplicate on other tags rather than styling in particular for <options>.

If you don't mind getting dirty with JavaScript, Select2 provides a very concise way to achieve that. It does use lists for that as well.

Here is HTML

<select id="e1" style="width:300px">
  <option value="AL" data-badge="3">Alabama</option>
  <option value="WY">Wyoming</option>
</select>

And here is CoffeeScript

$("#e1").select2
  theme: "bootstrap"
  templateResult: (data) ->
    badge = $(data.element).data('badge')
    if badge
      return $(document.createTextNode(data.text)).add($('<span class="badge pull-right">').text(badge))
    data.text

And here is JSFiddle.

Rendered result

Upvotes: 0

mr. hadi mollaei
mr. hadi mollaei

Reputation: 1

In some cases I could do that by jQuery. Look here: http://jsfiddle.net/rangine/wegx00La/4/

I used a select box for choosing a glyph icon in bootstrap form. but unfortunately this worked only in Firefox.(I don't test it on all browser. in Chrome not works and in IE! I threw it away.

Html:

This code Only works in Firefox.
<br/>
<select id="myselect">
  <option value="_none"> - Select One - </option>
  <option value="asterisk">asterisk</option>
  <option value="plus">plus</option>
  <option value="euro" class="red">euro</option>
  <option value="eur">eur</option>
  <option value="minus" class="green">minus</option>
  <option value="cloud">cloud</option>
  <option value="envelope">envelope</option>
  <option value="pencil">pencil</option>
  <option value="glass">glass</option>
  <option value="music">music</option>
  <option value="search">search</option>
  <option value="heart">heart</option>
  <option value="star">star</option>
  <option value="star-empty">star-empty</option>
  <option value="user">user</option>
  <option value="film">film</option>
</select>
<span class="preview"> </span>

jquery:

(function($) {
  $(document).ready(function() {
    $('#myselect option').each(function() {
      $(this).html('<i class="glyphicon glyphicon-' + $(this).text() + '"></i> ' + $(this).text());
    })

  });
  $('.preview').html(' <i class="preview glyphicon glyphicon-' + $('#myselect').val() + '"></i>');
  $('#myselect').change(function() {
    $('.preview').html(' <i class="preview glyphicon glyphicon-' + $('#myselect').val() + '"></i>');

  });

})(jQuery);

Some CSS:

#myselect {
  margin: 40px;
  height: 30px;
  font-size: 14pt;
}

option.red {
  color: red;
}

option.green {
  color: green;
}

.preview {
  font-size: 20pt;
}

Upvotes: -4

Kirby
Kirby

Reputation: 15855

Or you could do it with Bootstrap Drop Downs plus a couple lines of Javascript.

Here is the Bootstrap example with a slight alteration plus a 'lil Javascript:

$(function() {
   $('#my-select').find('li').click(function() {
      $('#selected').html($(this).html());
   });
});
<head>
      <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js" type="text/javascript"></script>
    <script class="cssdeck" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<!-- Single button -->
<div id='my-select' class="btn-group">
  <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    <span id="selected">Action</span> <span class="caret"></span>
  </button>
  <ul class="dropdown-menu">
    <li><a href="#">Action <span style='color:red'>like Super Man</span></a></li>
    <li><a href="#">Another action</a></li>
    <li><a href="#">Something else here</a></li>
    <li role="separator" class="divider"></li>
    <li><a href="#">Separated link</a></li>
  </ul>
</div>
</body>

Upvotes: 11

clu3Less
clu3Less

Reputation: 1892

But you could always create a Custom select box. Refer the jsFiddle below,

JSFiddle for multi colored selectbox options

// Insert a list item into the unordered list for each select option
for (var i = 0; i < numberOfOptions; i++) {
    $('<li />', {
        html: $this.children('option').eq(i).text()
        .split(' ').join(' <span style="color:red">'),
            rel: $this.children('option').eq(i).val()
    }).appendTo($list);
}

Upvotes: 14

Ms2ger
Ms2ger

Reputation: 15993

Nope. options are styled in a way native to the platform, and styling only a part of one doesn't work. (It usually wouldn't be a particularly good idea either.)

Upvotes: 13

Related Questions