When is it allowed to style pseudo elements on an option element? - html

I am trying to use pseudo elements with <option> element. However I am observing a few differences in rendering with different browsers.
So my question is, when is it allowed to use pseudo elements such as ::before, ::after and ::first-letter with an <option> element?
Context
Let's say I have three option elements,
<select>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
I want to add some content before and after the certain elements using ::before and ::after selectors. So I will add a CSS class "special" to one of the elements and add a CSS rule like so,
.special::before {
content: " Before - ";
}
.special::after {
content: " - After ";
}
<select>
<option value="1" class="special">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
It doesn't work in any of the browsers. However, now if I simply modify the select element to allow multiple selections, the pseudo elements will work in Chrome, Firefox and Edge, but still not in IE 11.
.special::before {
content: " Before - ";
}
.special::after {
content: " - After ";
}
<select multiple>
<option value="1" class="special">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
I am able to apply different styles, such as color, font-family, font-size and even display on these pseudo elements!
.special::before {
content: " Before - ";
color: red;
font-size: 15px;
}
.special::after {
content: " - After ";
font-family: Consolas, Arial, Verdana;
display: block;
color: blue;
}
<select multiple>
<option value="1" class="special">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
However, the found that the behavior is not completely consistent with Chrome, Firefox and Edge either.
For example, in Chrome, if I use the ::first-letter pseudo element, it works for option elements under a select element, but not under an optgroup element. However it works fine with both Firefox and Edge.
.special::first-letter {
color: red;
font-size: 20px;
}
select {
height: 100px;
}
<select multiple>
<option value="1" class="special">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<select multiple>
<optgroup label="Item 1">
<option value="1" class="special">One</option>
</optgroup>
<optgroup label="Other items">
<option value="2">Two</option>
<option value="3">Three</option>
</optgroup>
</select>
Note: None of this works when the option element is used within a datalist element. But I am not concerned with that at the moment. I have some examples here in case you wish to see.
Upon searching I found that <option> element is considered a replaced element only in certain cases. However I wasn't able to find any documentation online as to when it is allowed to use pseudo elements with it.

The short answer, if you're looking for a standards-based answer, is that CSS does not currently support using pseudo-elements with form elements, be it ::before/::after, or other pseudo-elements such as ::first-letter. As a result, every browser does its own thing, and there is little to no interop.
As stated, there is no specification for the interaction between most pseudo-elements and form elements and/or replaced content The only statement in any spec for this is in css-content-3, which says:
Note: Replaced elements do not have ::before or ::after pseudo-elements; the content property replaces their entire contents.
But it gets worse: strictly speaking, form elements aren't the same thing as replaced content (despite many people, myself included, often stating the contrary), even though they behave very similarly. Form elements just happen to have platform-specific layout rules that prevent them from being completely styleable with CSS. They may support some common CSS properties and adhere to the box model to some extent, but they have limitations that prevent you from treating them fully as a regular, non-replaced element. This is really the only thing they have in common with replaced content.
To top it all off, the rendering of form elements is not covered in any current CSS spec. Work is being done to try and rein this all in in css-ui-4, but I'm not holding my breath.

Related

Why is it that if you target a "Form" element in CSS, the properties apply only to the first child-element, and not all?

Here's what I mean.
<div class="drop-down">
<form action="/action-page.php">
<label for="cars">Choose a Japanese car:</label>
<select id="cars" name="cars">
<option value="Toyota">Toyota</option>
<option value="Honda">Honda</option>
<option value="Mitsubishi">Mitsubishi</option>
<option value="Suzuki">Suzuki</option>
<option value="Nissan">Nissan</option>
<option value="Subaru">Subaru</option>
<option value="Mazda">Mazda</option>
</select>
<input type="submit">
</form>
</div>
and CSS:
.drop-down {
background-color:white;
padding:20px;
display:inline-block;
padding-right:70px;
padding-left:70px;
font-size:20px;
}
Now, the font-size applies to only the first child-element, which is the label element. Why is it that it doesn't apply to the rest of the child-elements, i.e. the select and input?
I have to separately target them to change their font-size. I thought that, if I target the parent element, the changes are going to cascade down to all the texts within the parent element, yet it only cascades down to the first child element.
Why is that?
Browser has it's own stylesheet (called user agent stylesheet).
If you inspect your input and select elements, you would see that browser overrides your style, since it has higher specificity:
Simply adding
input, select{
font-size: inherit;
}
solves the problem.
It would be good idea to add css reboot like this or write your own in separate file. That would solve common problems and make styles less browser-opinionated.
You can do it by defining a separate CSS for select.
select {
font-size:20px;
}
if you want the same style for both you can add it in style like .drop-down, select {} but it will make it worse as there is padding in your style for the label. it will be applied to the options also this will make your dropdown larger.
.drop-down {
background-color:white;
padding:20px;
display:inline-block;
padding-right:70px;
padding-left:70px;
font-size:20px;
}
select {
font-size:20px;
}
<div class="drop-down">
<form action="/action-page.php">
<label for="cars">Choose a Japanese car:</label>
<select id="cars" name="cars">
<option value="Toyota">Toyota</option>
<option value="Honda">Honda</option>
<option value="Mitsubishi">Mitsubishi</option>
<option value="Suzuki">Suzuki</option>
<option value="Nissan">Nissan</option>
<option value="Subaru">Subaru</option>
<option value="Mazda">Mazda</option>
</select>
<input type="submit">
</form>
</div>

Style option element of select list to open it from right to left

I have following markup that renders HTML dropdown. On my web page the dropdown is placed at extreme right side of the container. Dropdown contains some lengthy text.
When open in chrome, dropdown opens correctly starting from right towards left, thus showing the lengthiest option clearly. Where in firefox dropdown starts off from left towards right, thus some of the option text goes out of the screen.
Is there any way/css to change this behavior in firefox.
<div style="float:right;">
<select id="select_1" style="width:100px;" name="select_1">
<option value="-1" selected="selected">Browse options</option>
<option value="-1">------------------------------------</option>
<option value="224">Option 1</option>
<option value="234">Longer title for option 2</option>
<option value="242">Very long and extensively descriptive title for option 3</option>
</select>
</div>
Just use this may help you
#-moz-document url-prefix() {
select {
direction: rtl;
}
option{
text-align: left;
}
}
The problem is caused by setting the select element with a fixed width (100px)
Remove that and the select element will work correctly in all browsers.
Fiddle
If it's important for you to keep the width, then you can use firefox-only CSS to change the width back to auto in Firefox.
NB: It is generally frowned upon to rely on hacks like these in production code. Use with caution!
Fiddle
select {
width: 100px;
}
/* firefox-only CSS..
WARNING: Use at your own risk */
#-moz-document url-prefix() {
select {
width: auto;
}
}
<div style="float:right;">
<select id="select_1" name="select_1">
<option value="-1" selected="selected">Browse options</option>
<option value="-1">------------------------------------</option>
<option value="224">Option 1</option>
<option value="234">Longer title for option 2</option>
<option value="242">Very long and extensively descriptive title for option 3</option>
</select>
</div>

Mysterious extra left padding on input[type="search"]

Anyone know what's causing this extra left 'padding' on the input? The inspector isn't reporting that anything is actually causing it. Can't say I've run into this issue beforeā€¦
The top field is a text input (search), the bottom field is a select
Apparently the HTML code is the key to solving the problem, here you go:
<input type="search" placeholder="Search" />
<select>
<option value="ir35">IR35</option>
</select>
Edit to add:
I was a bit of a doofus, but the problem still remains. In experimenting with different input types I'd created two templates. The isse is actually on an input[type="search"] - NOT text. This is an issue with the search type. However I am already applying -webkit-appearance: textfield is there something else I'm missing? There's no actualy 'thing' causing the padding, text indent, padding, etc. It's just 'there'.
Edit:
My solution will be dropping search in favour of text - it's a workaround but it'll do.
select elements and input elements operate, I believe, under different box-models.
box-sizing:border-box is the default on select elements.
You can check this by looking in the "Computed Styles" when using Developer Tools
Setting box-sizing:border-box on both should fix it.
DEMO Without
select,
input {
display: block;
width: 200px;
}
<select name='options'>
<option value='option-1'>Option 1</option>
<option value='option-2'>Option 2</option>
<option value='option-3'>Option 3</option>
</select>
<input type="text" />
DEMO With
select, input {
display: block;
width: 200px;
box-sizing:border-box;
}
<select name='options'>
<option value='option-1'>Option 1</option>
<option value='option-2'>Option 2</option>
<option value='option-3'>Option 3</option>
</select>
<input type="text" />
The styling of certain form elements like input and select is not specified in the CSS specification and is left up to the discretion of the browser developer, so there will be slight style variations across browsers.
In Firefox, you can make some hard-coded style adjustments to fix the padding issue that you are seeing.
For example, if you add padding-left: 3px to the input field, then the text value will line up with the option value displayed in the select box.
However, since padding cannot be negative, you can eliminate the left padding in the select element, though you can in the option element.
select,
input {
display: block;
width: 200px;
box-sizing: border-box;
}
select {
padding-left: 0px;
}
input {
padding-left: 3px;
}
<input type="text" value="Option 1" />
<select name='options'>
<option value='option-1'>Option 1</option>
<option value='option-2'>Option 2</option>
<option value='option-3'>Option 3</option>
</select>

Style Select And Multiple Select?

How can I style both the <select> HTML tag, and the <select multiple="multiple"> HTML tag while both of the tags reside under a <form> tag? Of course styling within CSS. If someone knows how to accomplish this, may someone give me an example?
Thank you!
Aaron
You can use classes fairly easily:
.singleSelect {
width: 200px;
}
.singleMultiple {
width: 300px;
}
<form>
<select class="singleSelect">
<option>Test</option>
</select>'
<br/>
<select class="singleMultiple" multiple="multiple">
<option>Test 1</option>
<option>Test 2</option>
<option>Test 3</option>
</select>
</form>
http://jsfiddle.net/GyxL4/
A more advanced selector may be used on the select[multiple], but beware, legacy browsers (EDIT: apparently only IE6) may not always support the attribute selector, and in the first example below, you're styling every SELECT element on the page (this is called an element selector):
select {
width: 200px;
}
select[multiple] {
width: 300px;
}
See: http://www.w3.org/TR/CSS2/selector.html

Styling disabled <select> (dropdown boxes) in HTML

One of our customers has a hard time reading the grey text in disabled controls in our web-based application:
We would like to change the style to a light grey background and a black text. Unfortunately, most browsers (including IE, which is what the customer is using) ignore the color: ... CSS attribute on disabled controls, so we cannot change the foreground color.
For text boxes (input type="text"), this can easily be workarounded by using the readonly instead of the disabled attribute. Unfortunately, this is not an option for dropdowns (select) or checkboxes (input type="checkbox").
Is there an easy workaround for that? Preferebly one where the control does not need to be replaced by another type of control? (...since our controls are rendered by ASP.NET)
PS: Using the [disabled] selector in CSS does not make a difference.
In Internet Explorer 9, support will be added for the :disabled pseudo-selector (ref). I don't know whether that will honor the "color" property, but it seems likely.
In older versions of IE, you can adjust the background color (but not the color). Thus:
<style type="text/css">
select[disabled] { background-color: blue; }
</style>
That works in IE 7 and IE 8. You still can't alter the foreground color, but you can change the background color to contrast more strongly with the gray that IE assigns it when it's disabled.
This worked for me in webkit and Firefox
select:disabled{
opacity: 0.6;
}
For those still finding this.
Not working:
select[disabled] { background-color: blue; }
Working:
select option [disabled] { background-color: blue; } will do
This worked for me
select[disabled='disabled']::-ms-value {
color: red;
}
Sorry for my english...
That's not possible using css just, IE doesn't allow change properties of a disabled select tag
You can try the following:
<style>
/*css style for IE*/
select[disabled='disabled']::-ms-value {
color: #555;
}
/*Specific to chrome and firefox*/
select[disabled='disabled'] {
color: #555;
}
</style>
I know this is question is old but this code worked well for me.
It allowed for full control of text and background color. I used this code with a disabled select control whose value is set based on a value from another select. I didn't want to see the grayed background, especially when the value had not yet been set.
CSS
<style>
.whatever-control:disabled, .whatever-control[readonly] {
background-color: white;
opacity: 1;
color: blue;
font-weight: bold;
}
</style>
Form
<select id = "SelectState" name="SelectState" class="whatever-control" disabled="disabled">
<option value="AK">Alaska</option>
<option value="AL">Alabama</option>
<option value="AR">Arkansas</option>
<option value="AZ">Arizona</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<option value="DC">District of Columbia</option>
<option value="DE">Delaware</option>
<option value="FL" selected="selected">Florida</option>
<option value="GA">Georgia</option>
</select>
You can try,
option:disabled{
opacity: 0.6;background-color: #ff888f;
}
<select id="HouseCleaningEmp" onChange="myCalculater()">
<option value="1">option 1 </option>
<option value="2">option 2 </option>
<option value="3">option 3 </option>
<option value="4">option 4 </option>
<option value="5" disabled>option 5 </option>
<option value="6" disabled>option 6 </option>
<option value="7">option 7 </option>
<option value="8">option 8 </option>
</select>