I want to make a website more accessible by considering user with high contrast mode (or maybe just dark mode).
Now I have a problem with custom radio buttons which are just HTML elements that have a round border: when the user has set the default background color of his browser to black, the background-color of my elements is also black, making it look like a checked option, even though I set the background-color of this elements to white.
To prevent this I made the white border thicker, so it looks like a white background. But it also creates the problem, that sometimes there is a tiny black dot in the middle of my buttons at some zoom-levels or resolutions.
Is there any way to prevent the browser from overwriting the background-color I declared in my CSS?
Is there anything I missed out on like an attribute that prevents this behaviour?
I could also replace this elements or implement them in a different way, but at this point i am just curious if there isn't any simple solution to that.
The style of my radio buttons looks like this:
input.check + label:before {
display: inline-block;
content: "";
width: 1rem;
height: 1rem;
background: #fefefe;
border: 0.2rem solid #fefefe;
border-radius: 50%;
position: absolute;
left: -1rem;
}
input.check:checked + label:before {
background: #000000;
}
Here is a link to a picture of my radio when checked / or default black background-color
I make the 'checked' look of my radio button by setting the background-color to black - like the browser does in this case.
Edit
So far there are good answers for improving the accessability of custom radio buttons.
To be a little bit more specific on my problem:
I tested the page in Firefox with the following color settings
But this seems to overwrite every background-color no matter what you specified for each element. Is there a way to make an exception for this overwriting?
Using a pseudo element - which is already mooted in the question - it is possible to style the button exactly as you would like.
The main difference in this snippet and the CSS in the question is that we set the actual input element to opacity 0. This means it is still 'there' for accessibility purposes but it can't be actually seen.
Also, using radial-gradient for coloring the buttons we can have rings of different colors, or just one color as best suits the background chosen. As the code in the question does, we also size everything in terms of rems so that the user who has changed their browser setting for this gets the benefit.
body {
background-color: black;
}
input {
opacity: 0;/* keep the input element in the DOM for accessibility it's just not seen*/
}
/* a pseudo element - this is what the user actually sees and we can style it */
label > input[type="radio"] + *::before {
content: "";
display: inline-block;
width: 2rem;
height: 2rem;
margin-right: 1rem;
border-radius: 50%;
border-style: solid;
border-width: 0.2rem;
border-color: white;
background: radial-gradient(white 0%, white 100%);/* choose what you want - one color or rings */
border-color: white;
}
label > input[type="radio"]:checked + *::before {
background: radial-gradient(red 0%, red 50%, white 50%, white 100%);/* choose what you want here too */
border-color: red;
}
label {
font-size: 2rem;
color: white;
}
<label>
<input type="radio" name="mybutton" value="A" checked />
<span>A</span>
</label>
<label>
<input type="radio" name="mybutton" value="B" />
<span>B</span>
</label>
<label>
<input type="radio" name="mybutton" value="C" />
<span>C</span>
</label>
In order to remove the default browser styling for the radio buttons you need appearance: none;
You will find more on that here, and you can check browser support here.
From there, you can use the background property to create the checked effect, you don't even need to use ::before.
I created this fiddle to demonstrate.
The code looks like this:
:root {
--background-color: white;
--text-color: black;
--fill-color: black;
--border-color: black;
}
#media (prefers-color-scheme: dark) {
:root {
--background-color: black;
--text-color: white;
--fill-color: white;
--border-color: white;
}
}
body {
background: var(--background-color);
color: var(--text-color);
}
div {
display: flex;
align-items: center;
}
input[type=radio] {
appearance: none;
margin: 0 0.5rem 0 0;
border: 1px solid var(--border-color);
border-radius: 50%;
width: 1rem;
height: 1rem;
}
input[type=radio]:checked {
background: radial-gradient(var(--fill-color) 0%, var(--fill-color) 30%, var(--background-color) 31%);
}
<p>Select an option:</p>
<div>
<input class="check" type="radio" id="huey" name="duck" value="huey" checked>
<label for="huey">Huey</label>
</div>
<div>
<input class="check" type="radio" id="dewey" name="duck" value="dewey">
<label for="dewey">Dewey</label>
</div>
<div>
<input class="check" type="radio" id="louie" name="duck" value="louie">
<label for="louie">Louie</label>
</div>
Related
I've stumbled upon an interesting challenge in css which I can't seem to figure out.
I'm trying to make a form field, quite similar to what google does in their login form, where the label is moved relatively to to the top when the form field has focus, covering part of the form field's border. This is rather easy when the background is white, as I can just set background-color: #fff on the label.
In my case, however, I have a full-screen image background, which means my label background has to be transparent for the background-image, but has to cover the border of the form field. Is this possible?
This is my form markup:
<form>
<div class="form-field__container">
<div class="form-field__wrapper">
<label class="form-field__label input--active">Email</label>
<input class="form-field__input form-field__input--text"
type="text">
</div>
</div>
</form>
The form-field has a border around it:
.form-field__input {
border: 2px solid #e6e6e6;
}
The input--active class is set when the form field has focus, which adds the following styles to the label:
top: -10px;
left: 10px;
z-index: 1;
This moves my label over the top-border of the form field. Normally, I would then just add a background-color to the label which is the same as the page background, set a display: blockon that, and the label would cover the part of the form field border, which would solve my issue.
I do however have an image as a page background, which means I can't set a background-color on the label, because this would also cover a part of the page background. Is there any css property which allows me to have the label behave in a way that cuts out the part of the top border of the form-field which is below the label but doesn't cut away any of the background-image?
Below is an image of what I've got so far, for clarification:
I'd really appreciate the help.
Greetz derelektrischemoench
That's what you have fieldset and Legend for:
<fieldset>
<legend>
<label class="form-field__label input--active">Email</label>
</legend>
<input class="form-field__input form-field__input--text" type="text">
</fieldset>
here's an alternative hack that hides the top border completely and uses additional elements to create border to the left and right of the label text...
it's different than your approach and element structure, but it may give you some hints in how to use other elements to emulate a top border
body {
font-family: sans-serif;
background: linear-gradient(to top right, pink, orange);
}
input {
border: 2px solid black;
border-top: 0;
background: transparent;
}
input:focus {
outline: none;
border-color: blue;
}
label {
display: flex;
flex-direction: column;
}
label:focus-within .top-border-replacement:before,
label:focus-within .top-border-replacement:after {
border-color: blue;
}
label:focus-within .label-text {
color: blue;
}
.top-border-replacement {
display: flex;
}
.label-text {
position: relative;
bottom: -7px;
display: inline-block;
font-size: 12px;
padding: 0 4px;
font-weight: bold;
}
.top-border-replacement:before {
content: '';
width: 10px;
border-bottom: 2px solid black;
}
.top-border-replacement:after {
content: '';
width: 100%;
border-bottom: 2px solid black;
}
<label>
<span class="top-border-replacement">
<span class="label-text">TEST</span>
</span>
<input type="text" />
</label>
<input type="text" placeholder="First Name *" />
How can I change the color of place holder differently like "First Name" in yellow and "*" in red.
Is it possible to do that?
You can change the color of the placeholder but I don't think you can add two colors in one placeholder. First, add a class name of input to the input element. Then add this css,
.input::placeholder {
color: red;
}
Inline elements such input do not support :before and :after. To make things even harder the placeholder selector and their pseudo-classes are not fully supported by all browsers.
input {
width: auto;
}
/* the negative of the input width */
input[required]+label {
color: #1b1b1b;
font-size: .7em;
position: relative;
left: -166px;
}
input[required]+label:after {
content: ' *';
color: red;
}
/* show the placeholder when input has no content */
input[required]:invalid+label {
display: inline-block;
}
/* hide the placeholder when input has some text typed in it */
input[required]:valid+label {
display: none;
}
<form>
<input type="text" id="name" name="name" required="required" />
<label for="name">First Name</label>
</form>
You could use linear-gradient to do this, but this first approach wouldn't work with fluctuating length of placeholder text
input::placeholder {
background: linear-gradient(to right, gray 5em, red 5em);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
If your input text is right aligned, this would work with different lengths of content
input {
text-align: right;
}
input::placeholder {
background: linear-gradient(to left, red 5px, gray 1em);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
Hello I want to set the light gray outline outside gray border line just like in the following image.either there is a border position set or blur effect the input text.
Please tell me how can I fix this issue? I am doing all of this in css.
.container {
background-color: aquamarine;
width: 100%;
height: auto;
}
input[type="text"],
textarea,
textarea.form-control {
background-color: #efeeef;
width: 396px;
height: 48px;
border-radius: 4px;
border: 3px solid #cecece;
}
textarea.form-control {
line-height: 50%;
font-size: 16px;
color: red;
font-weight: 500;
}
<div class="container">
<!--Form element-->
<form>
<fieldset>
<input type="text" name="form-email" placeholder="Enter Your email" class="form-email form-control textarea border-color outline" id="form-email">
</fieldset>
</form>
</div>
When I am using shade effects it is also useless.Is there any way to set the position of the border in this input area.
Borders cannot be set to blur (at least directly). If you are using some sort of CSS library, say Bootstrap then it may be adding box-shadow to the input elements.
Setting the box-shadow: none; on the required input should solve the problem.
I am not a expert but try
form{
border: 1px(thickness) outset(type of border) grey(color)
}
for more information go to this link:
https://www.w3schools.com/css/css_border.asp
Suppose I have this text field
<input type="text" placeholder="I am placeholder">
I know with css we can change placeholder color like this but is there any way to change color of one word only.
::-webkit-input-placeholder { /* Chrome/Opera/Safari */
color: pink;
}
::-moz-placeholder { /* Firefox 19+ */
color: pink;
}
:-ms-input-placeholder { /* IE 10+ */
color: pink;
}
:-moz-placeholder { /* Firefox 18- */
color: pink;
}
This code will change complete placeholder color but I want to change color of word placeholder only instead on complete I am placeholder
You can take a look at mix-blend-mode :
edit: for nowdays, see and use update below (3rd snippet) with background-clip.
label {
display: inline-block;
background: linear-gradient(to right, red 2.2em, blue 2.2em);
border: inset;
/* border here instead input */
font-family: monospace;
/* less surprise about length of text at screen */
}
input {
box-shadow: inset 0 0 0 2em white;
/* covers the background, needed for the blending */
}
input:invalid {
/* color part of text only when placeholder is shown */
mix-blend-mode: screen;
}
/* snippet disclaimer */
.disclaim {
mix-blend-mode: screen;
}
body {
background: white;
}
<label>
<input placeholder="I am placeholder" required />
</label>
<p class="disclaim">not avalaible yet for <span>'your browser',</span> please be patient.</p>
Else you need to use HTML and text:
label {
display: inline-block;
}
label>span {
position: absolute;
padding-left: 3px;
}
label>span span {
color: blue
}
input {
position: relative;
background: white;
}
input:invalid {
background: none;
}
<label>
<span>I am <span>placeholder</span></span>
<input type="text" required />
</label>
edit 2020
background-clip is now well supported and can be used instead mix-blend-mode
mix-blend-mod trick was a workaround for Firefoxe. Firefoxe understood color:transparent but not background-clip-text; yet ... text was gone.
label {
display: inline-block;
font-family: monospace;
/* less surprise about length of text at screen */
}
input:invalid {
background: linear-gradient(to right, red 2.2em, blue 2.2em);
background-clip:text;
color:transparent;
}
<label>
<input placeholder="I am placeholder" required />
</label>
You can't possibly do it with standard placeholder. Instead make a div and put your input element and one more child(say span/p element) inside this div and position span/p inside your input element and on focus hide the span/p element.
Something like this : link
Hi friends you should us div tag with an attribute of contenteditable="true" instead of input tag and then find its children elements and change their size color etc using javascript.and I think it is the only answer for your question.And if you only want to change the first letter or word color you should use pseudo selectors.
Do you know how I could style a checkbox when it is disabled?
E.g.:
<input type="checkbox" value="All Terrain Vehicle"
name="exfilter_All Terrain Vehicle"
id="exfilter_All_Terrain_Vehicle"
class="exfilter" disabled="">
Use the attribute selector in the css
input[disabled]{
outline:1px solid red; // or whatever
}
for checkbox exclusively use
input[type=checkbox][disabled]{
outline:1px solid red; // or whatever
}
$('button').click(function() {
const i = $('input');
if (i.is('[disabled]'))
i.attr('disabled', false)
else
i.attr('disabled', true);
})
input[type=checkbox][disabled] {
outline: 2px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" value="tasd" disabled />
<input type="text" value="text" disabled />
<button>disable/enable</button>
You can't style a disabled checkbox directly because it's controlled by the browser / OS.
However you can be clever and replace the checkbox with a label that simulates a checkbox using pure CSS. You need to have an adjacent label that you can use to style a new "pseudo checkbox". Essentially you're completely redrawing the thing but it gives you complete control over how it looks in any state.
I've thrown up a basic example so that you can see it in action: http://jsfiddle.net/JohnSReid/pr9Lx5th/3/
Here's the sample:
input[type="checkbox"] {
display: none;
}
label:before {
background: linear-gradient(to bottom, #fff 0px, #e6e6e6 100%) repeat scroll 0 0 rgba(0, 0, 0, 0);
border: 1px solid #035f8f;
height: 36px;
width: 36px;
display: block;
cursor: pointer;
}
input[type="checkbox"] + label:before {
content: '';
background: linear-gradient(to bottom, #e6e6e6 0px, #fff 100%) repeat scroll 0 0 rgba(0, 0, 0, 0);
border-color: #3d9000;
color: #96be0a;
font-size: 38px;
line-height: 35px;
text-align: center;
}
input[type="checkbox"]:disabled + label:before {
border-color: #eee;
color: #ccc;
background: linear-gradient(to top, #e6e6e6 0px, #fff 100%) repeat scroll 0 0 rgba(0, 0, 0, 0);
}
input[type="checkbox"]:checked + label:before {
content: '✓';
}
<div><input id="cb1" type="checkbox" disabled checked /><label for="cb1"></label></div>
<div><input id="cb2" type="checkbox" disabled /><label for="cb2"></label></div>
<div><input id="cb3" type="checkbox" checked /><label for="cb3"></label></div>
<div><input id="cb4" type="checkbox" /><label for="cb4"></label></div>
Depending on your level of browser compatibility and accessibility, some additional tweaks will need to be made.
Use the :disabled CSS3 pseudo-selector
You can select it using css like this:
input[disabled] { /* css attributes */ }
Checkboxes (radio buttons and <select>) are OS-level components, not browser-level. You cannot reliably style them in a manner that will be consistent across browsers and operating systems.
Your best bet it to put an overlay on top and style that instead.
Use CSS's :disabled selector (for CSS3):
checkbox-style { }
checkbox-style:disabled { }
Or you need to use javascript to alter the style based on when you enable/disable it (Assuming it is being enabled/disabled based on your question).
input[type='checkbox'][disabled][checked] {
width:0px; height:0px;
}
input[type='checkbox'][disabled][checked]:after {
content:'\e013'; position:absolute;
margin-top:-10px;
opacity: 1 !important;
margin-left:-5px;
font-family: 'Glyphicons Halflings';
font-style: normal;
font-weight: normal;
}
If you're trying to stop someone from updating the checkbox so it appears disabled then just use JQuery
$('input[type=checkbox]').click(false);
You can then style the checkbox.
do not put disabled in the input and apply the following styles
input[type="checkbox"] {
pointer-events: none;
}
This is supported by IE too:
HTML
class="disabled"
CSS
.disabled{
...
}
In case if you really want to add some colors to a checkbox, try this workaround.
input[type=checkbox][disabled] {
outline: 5px solid red;
outline-offset: -20px;
}