Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using ::after with ~ in same selector [duplicate]

I wanted to create a custom radio button using ::after. My HTML structure looks like this:

<div class='radio'>
  <input type='radio' class='radio-input'>
</div>

and what I want is to add an ::after to the radio element and apply some style when the input is checked. What I wrote (and is not working) is this:

.radio-input:checked ~ .radio::after {
  ...
}

If I use an element instead of the ::after it works but I wanted to know why this doesn't.

like image 906
SKOLZ Avatar asked Nov 17 '25 15:11

SKOLZ


1 Answers

The reason the selector .radio-input:checked ~ .radio::after doesn't work with your markup is because you can't target ancestor elements, with any selector. Yours starts with the child (.radio-input), goes up to the parent (.radio) and then back down to the child pseudo. CSS cascades down, it doesn't ascend.

Instead give the input a true sibling. Here I use a label because it conforms to accessibility standards which make sure screen readers can interpret your form:

input:checked ~ label::before

with markup like:

<input type="checkbox" name="dubstep" id="dubstep" value="dubstep" tabindex="0">
<label for="dubstep">dubstep</label>

See example:

ul.check-or-radio-set {
		list-style-type: none;
		padding: 0;
		margin: 0;
        position:relative;
	}

    ul.check-or-radio-set li {
      padding:0;
      margin:0 0 10px 0;
      height:1.6em;
    }

	ul.check-or-radio-set input {
		position: absolute;
		left: -9999em;
	}

	ul.check-or-radio-set input ~ label::before {
		background: white;
		border: 2px white solid;
		box-shadow: 0 0 0 1px darkGray;
		content: '\a0';
		display: inline-block;
		line-height: 1;
		text-indent: .15em;
	}

	ul.check-or-radio-set input[type=checkbox] ~ label {
        position: relative;
        margin-left: 32px;
		line-height: 1.4em;
	}

	ul.check-or-radio-set input[type=checkbox] ~ label::before {
        position: absolute;
		margin-left: -32px;
		height: 1.4em;
		width: 1.4em;
		border-radius: 4px;
		transition: all .3s;
		background-image: url(http://imgh.us/checkmark-white.svg);
		background-position: 50%;
		background-repeat: no-repeat;
		margin-right: 10px;
	}

	/* checked */
	ul.check-or-radio-set input:checked ~ label::before {
		background-color: orange;
	}

	ul.check-or-radio-set input:focus ~ label::before {
		box-shadow: 0 0 5px 1px #007fea;
	}
	ul.check-or-radio-set input:disabled ~ label {
		color: lightGray;
		cursor: not-allowed;
	}
	ul.check-or-radio-set input:disabled ~ label::before {
		background-color: gray;
		box-shadow: 0 0 0 1px darkGray;
	}
<ul class="check-or-radio-set">
  <li>
    <input type="checkbox" name="rock" id="rock" value="rock" tabindex="0">
	<label for="rock">rock</label>
  </li>
  <li>
    <input type="checkbox" name="pop" id="pop" value="pop" tabindex="0" checked="checked">
	<label for="pop">pop</label>
  </li>
  <li>
    <input type="checkbox" name="dubstep" id="dubstep" value="dubstep" tabindex="0">
	<label for="dubstep">dubstep</label>
  </li>
</ul>

Note: I got this pattern from here: https://standards.usa.gov/form-controls/ - it's a great resource for making great looking, accessible form controls.

like image 156
inorganik Avatar answered Nov 19 '25 06:11

inorganik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!