dynamic css animation on radio button - html

Is there a way to have the .switch__indicator cover each label without having to set a fixed width for the .switch container?
I'm using translate3d but this requires me to set the width of the container and I want to keep it dynamic.
.wrap {
display: flex;
}
.switch {
position: relative;
width: auto;
padding: 0 1rem;
}
.switch:before {
content: ' ';
position: absolute;
left: 0;
z-index: -1;
width: 100%;
height: 3rem;
border: 2px solid #eee;
border-radius: 30px;
}
.switch__label {
display: inline-block;
width: 2rem;
border: 3px solid;
padding: 1rem;
text-align: center;
cursor: pointer;
transition: color 200ms ease-out;
}
.switch__indicator {
width: 4rem;
height: 4rem;
position: absolute;
top: -.5rem;
left: 0;
background: green;
border-radius: 50%;
transition: transform 600ms cubic-bezier(0.02, 0.94, 0.09, 0.97), background 300ms cubic-bezier(0.17, 0.67, 0.14, 1.03);
transform: translate3d(1rem, 0, 0);
}
.switch input#one:checked~.switch__indicator {
transform: translate3d(1.2rem, 0, 0);
}
.switch input#two:checked~.switch__indicator {
transform: translate3d(5.5rem, 0, 0);
}
.switch input#three:checked~.switch__indicator {
transform: translate3d(9.6rem, 0, 0);
}
.switch input#four:checked~.switch__indicator {
transform: translate3d(14rem, 0, 0);
}
.switch input[type="radio"]:not(:checked),
.switch input[type="radio"]:checked {
display: none;
}
<div class="wrap">
<div class="switch">
<input id="one" type="radio" name='thing' value='a' checked="checked" />
<label for="one" class="switch__label">One</label>
<input id="two" type="radio" name='thing' value='b' />
<label for="two" class="switch__label">Two</label>
<input id="three" type="radio" name='thing' value='c' />
<label for="three" class="switch__label">Three</label>
<input id="four" type="radio" name='thing' value='d' />
<label for="four" class="switch__label">Four</label>
<div class="switch__indicator"></div>
</div>
</div>

Its a bit difficult to calculate the exact space between labels as label are inline elements which have a space around them to aligned, so better to use flexbox here to remove the space and then use margin to give space between them.
Now you will need to calculate the exact translateX value which will be sum of border value, width of label and the margin value between them.
Also you don't need of translate3d here just use translateX and use calc() to calculate the exact amount of space.
.wrap {
display: flex;
}
.switch {
position: relative;
width: auto;
padding: 0 1rem;
display: flex;
}
.switch:before {
content: ' ';
position: absolute;
left: 0;
z-index: -1;
width: 100%;
height: 3rem;
border: 2px solid #eee;
border-radius: 30px;
}
.switch__label {
display: inline-block;
width: 2rem;
border: 3px solid;
padding: 1rem;
text-align: center;
cursor: pointer;
transition: color 200ms ease-out;
margin-right: 4px;
}
.switch__indicator {
width: 4rem;
height: 4rem;
position: absolute;
bottom: 0;
left: 0;
background: green;
border-radius: 50%;
transition: transform 600ms cubic-bezier(0.02, 0.94, 0.09, 0.97), background 300ms cubic-bezier(0.17, 0.67, 0.14, 1.03);
transform: translate3d(1rem, 0, 0);
}
.switch__label:last-of-type {
margin-right: 0;
}
.switch input#one:checked~.switch__indicator {
transform: translateX(calc(1rem + 3px));
}
.switch input#two:checked~.switch__indicator {
transform: translateX(calc(5rem + 13px));
}
.switch input#three:checked~.switch__indicator {
transform: translateX(calc(9rem + 23px));
}
.switch input#four:checked~.switch__indicator {
transform: translateX(calc(13rem + 33px));
}
.switch input[type="radio"]:not(:checked),
.switch input[type="radio"]:checked {
display: none;
}
<div class="wrap">
<div class="switch">
<input id="one" type="radio" name='thing' value='a' checked="checked" />
<label for="one" class="switch__label">One</label>
<input id="two" type="radio" name='thing' value='b' />
<label for="two" class="switch__label">Two</label>
<input id="three" type="radio" name='thing' value='c' />
<label for="three" class="switch__label">Three</label>
<input id="four" type="radio" name='thing' value='d' />
<label for="four" class="switch__label">Four</label>
<div class="switch__indicator"></div>
</div>
</div>

Related

Make inline element align with inline-block element [duplicate]

This question already has answers here:
How to center an element horizontally and vertically
(27 answers)
Closed 2 years ago.
I have some toggles with spans next to them (the spans with "True" and "False" in them). I want the spans to be centered in the vertical space that the toggles takes up. How can I best achieve this?
.question__label-group {
margin-bottom: 2rem;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: '';
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:checked + .slider {
background-color: #2196f3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196f3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
<div class="question__label-group">
<label class="switch">
<input type="radio" name="1" id="1" />
<span class="slider"></span>
</label>
<span>False</span>
</div>
<div class="question__label-group">
<label class="switch">
<input type="radio" name="1" id="1" />
<span class="slider"></span>
</label>
<span>True</span>
</div>
The easiest way to do this would be to give the .question__label-group class the following styles: display: flex and align-items: center.
Updated your fiddle for you. You may also want to give your slider or span a margin left/right.
.question__label-group {
margin-bottom: 2rem;
display: flex;
align-items: center;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: '';
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:checked + .slider {
background-color: #2196f3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196f3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
<div class="question__label-group">
<label class="switch">
<input type="radio" name="1" id="1" />
<span class="slider"></span>
</label>
<span>False</span>
</div>
<div class="question__label-group">
<label class="switch">
<input type="radio" name="1" id="1" />
<span class="slider"></span>
</label>
<span>True</span>
</div>
update css:
.question__label-group {
display: flex;
align-items: center;
margin-bottom: 2rem;
}

CSS prevent rotation transform from affecting :before elements

I'm trying to have the checkboxes appear below their slanted "span" label. However, the transform applied to the "span" is also applying to the custom checkbox created with the ":before" selector. How do you prevent the 45deg rotation to the custom checkbox, and have it appear directly below it's label?
.slanted_chkbx {
margin-top: 25px;
}
.slanted_check {
margin-left: 5px;
margin-right: 15px;
display: inline-block;
position: relative;
}
.slanted_check span {
position: absolute;
top: -20px;
left: .7em;
transform-origin: bottom left;
transform: rotate(-45deg);
}
.custom_check {
display: none;
}
.custom_check + span:before {
content: '';
display: block;
cursor: pointer;
width: 10px;
height: 10px;
left: 0;
top: 0;
position: absolute;
border: 2px solid #111111;
-webkit-transition: all .2s;
transition: all .2s;
}
.custom_check:checked + span:before {
width: 5px;
top: -2px;
left: 2px;
border-radius: 0;
opacity: 1;
border-top-color: transparent;
border-left-color: transparent;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
<div class="slanted_chkbx">
<label class="slanted_check">
<input type="checkbox" class="custom_check" name="option_one" value="option_one">
<span>One</span>
</label>
<label class="slanted_check">
<input type="checkbox" class="custom_check" name="option_two" value="option_two">
<span>Two</span>
</label>
<label class="slanted_check">
<input type="checkbox" class="custom_check" name="option_three" value="option_three">
<span>Three</span>
</label>
</div>
You need to place the reverse transform on the base state of the pseudo-element, not on the hover state.
.slanted_chkbx {
margin-top: 25px;
}
.slanted_check {
margin-left: 15px;
margin-right: 15px;
display: inline-block;
position: relative;
}
.slanted_check span {
margin-right: -25px;
display: inline-block;
transform-origin: bottom left;
transform: rotate(-45deg);
}
.custom_check {
display: none;
}
.custom_check+span:before {
content: '';
display: block;
cursor: pointer;
width: 10px;
height: 10px;
left: -15px;
bottom: -10px;
position: absolute;
border: 2px solid #111111;
-webkit-transition: all .2s;
transition: all .2s;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.custom_check:checked+span:before {
width: 5px;
border-radius: 0;
opacity: 1;
border-top-color: transparent;
border-left-color: transparent;
}
<div class="slanted_chkbx">
<label class="slanted_check">
<input type="checkbox" class="custom_check" name="option_one" value="option_one">
<span>One</span>
</label>
<label class="slanted_check">
<input type="checkbox" class="custom_check" name="option_two" value="option_two">
<span>Two</span>
</label>
<label class="slanted_check">
<input type="checkbox" class="custom_check" name="option_three" value="option_three">
<span>Three</span>
</label>
</div>
I'm not entirely sure what effect you are going for in the checked state so I have not adjusted that.

How can I restyle inputs of type radio in css?

I want to create my own radio buttons, but it seems I cant restyle them.
I got the following html:
.segment {
all: unset;
position: relative;
border: solid 1px blue;
height: 2rem;
width: 3rem;
-webkit-tap-highlight-color: transparent;
}
<div>
<input id="segemnt0" class="segment" type="radio" name="segment">
<input id="segemnt1" class="segment" type="radio" name="segment">
<input id="segemnt2" class="segment" type="radio" name="segment">
</div>
This isn't working. Nothing displays at all. If I remove the "all: unset;" it just displays the normal styled checkbox without borders etc...
You can customise radio buttons adding <label> tag and CSS
Here is the fiddle this might help you:
[type="radio"]:checked,
[type="radio"]:not(:checked) {
position: absolute;
left: -9999px;
}
[type="radio"]:checked+label,
[type="radio"]:not(:checked)+label {
position: relative;
padding-left: 28px;
cursor: pointer;
line-height: 20px;
display: inline-block;
color: #666;
}
[type="radio"]:checked+label:before,
[type="radio"]:not(:checked)+label:before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 18px;
height: 18px;
border: 1px solid #ddd;
border-radius: 100%;
background: #fff;
}
[type="radio"]:checked+label:after,
[type="radio"]:not(:checked)+label:after {
content: '';
width: 12px;
height: 12px;
background: #F87DA9;
position: absolute;
top: 4px;
left: 4px;
border-radius: 100%;
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
}
[type="radio"]:not(:checked)+label:after {
opacity: 0;
-webkit-transform: scale(0);
transform: scale(0);
}
[type="radio"]:checked+label:after {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}
<input id="segemnt0" class="segment" type="radio" name="segment">
<label for="segemnt0">one</label>
<input id="segemnt1" class="segment" type="radio" name="segment">
<label for="segemnt1">two</label>
<input id="segemnt2" class="segment" type="radio" name="segment">
<label for="segemnt2">three</label>
Try the sample with label. You need to add label in your code to style radio.
input[type=radio] {
display: none;
}
input[type=radio] + label:before {
content: '';
display: inline-block;
border: 2px solid #0F81D5;
height: 12px;
width: 12px;
border-radius: 50%;
margin: 2px 5px 0 0px
}
input[type=radio]:checked + label:before {
border-width: 5px;
height: 6px;
width: 6px;
}
<div>
<input type="radio" name="radio" id="radio1" />
<label for="radio1">radio1</label>
</div>
<div>
<input type="radio" name="radio" id="radio2" />
<label for="radio2">radio2</label>
</div>
<div>
<input type="radio" name="radio" id="radio3" />
<label for="radio3">radio3</label>
</div>

How to style radio inputs both in checked and not checked state with different background?

I have multiple color select option, I want to highlight whatever they are selected
Here is my first image ,
Here I want to convert this to this
Thanks for time and suggestions
You can change the style of radio put likewise. For the checked state, use
[input-selector]:checked + label:after and for the unchecked state, use [input-selector]:not(:checked) + label:before.
[type="radio"]:checked,
[type="radio"]:not(:checked) {
position: absolute;
left: -9999px;
}
[type="radio"]:checked+label,
[type="radio"]:not(:checked)+label {
position: relative;
padding-left: 28px;
cursor: pointer;
line-height: 20px;
display: inline-block;
color: #666;
}
[type="radio"]:checked+label:before,
[type="radio"]:not(:checked)+label:before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 18px;
height: 18px;
border: 1px solid #ddd;
border-radius: 100%;
background: #fff;
}
[type="radio"]:checked+label:after,
[type="radio"]:not(:checked)+label:after {
content: '';
width: 12px;
height: 12px;
position: absolute;
top: 3px;
left: 3px;
border-radius: 100%;
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
}
[type="radio"]:not(:checked)+label:after {
-webkit-transform: scale(0);
transform: scale(0);
}
[type="radio"]:checked+label:after {
-webkit-transform: scale(1);
transform: scale(1);
}
/* To change the background color, only customize the code below*/
.red-input:not(:checked)+label:before {
background: red;
}
.red-input:checked+label:after {
background: black;
}
.green-input:not(:checked)+label:before {
background: green;
}
.green-input:checked+label:after {
background: blue;
}
.black-input:not(:checked)+label:before {
background: black;
}
.black-input:checked+label:after {
background: silver;
}
.silver-input:not(:checked)+label:before {
background: silver
}
.silver-input:checked+label:after {
background: #E6B5A3;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" rel="stylesheet"/>
<form class="form-inline m-5">
<div class="form-group">
<div class="mx-2">
<input type="radio" id="test1" name="radio-group" class="red-input">
<label for="test1">Peach</label>
</div>
<div class="mx-2">
<input type="radio" id="test2" name="radio-group" class="green-input">
<label for="test2">Orange</label>
</div>
<div class="mx-2">
<input type="radio" id="test3" name="radio-group" class="black-input">
<label for="test3">Mango</label>
</div>
<div class="mx-2">
<input type="radio" id="test4" name="radio-group" class="silver-input">
<label for="test4">Lime</label>
</div>
</div>
</form>
Check this codepen
Update
To set the default background of the inputs, use [input-selector]:not(:checked)+label:before.
.red-input:not(:checked)+label:before {
background: red;
}

'Pure CSS Accordion' auto-closing with Filter Menu

Pure CSS Accordion can be found here: https://codepen.io/raubaca/pen/PZzpVe
My issue can be seen on this URL:
http://prj.sellerdeckwebhosting.co.uk/ks/smr/acatalog/trade-essentials-column-radiators-1.html
The issue is if you expand a sidebar menu e.g 'Height (mm)' and tick an option, the options will then disappear, this is the issue.
.filter-list .tab {
position: relative;
margin-bottom: 1px;
width: 100%;
overflow: hidden;
}
.filter-header {
color: #333;
}
input.filter-head-cb {
position: absolute;
opacity: 0;
z-index: -1;
}
.filter-header>label {
position: relative;
display: block;
padding: 0 0 0 3em;
background: #f6f6f6;
font-weight: bold;
line-height: 3;
cursor: pointer;
border: solid 1px #ddd;
}
.filter-list .blue label {
background: #2980b9;
}
.filter-list .tab-content {
max-height: 0;
overflow: hidden;
-webkit-transition: max-height .35s;
-o-transition: max-height .35s;
transition: max-height .35s;
}
.tab-content p {}
/* :checked */
input.filter-head-cb:checked+.tab-content {
max-height: 100%;
}
/* Icon */
.filter-header>label::after {
position: absolute;
left: 0;
top: 0;
display: block;
width: 3em;
height: 3em;
line-height: 3;
text-align: center;
-webkit-transition: all .35s;
-o-transition: all .35s;
transition: all .35s;
}
.filter-header>input[type=checkbox]+label::after {
content: "+";
}
.filter-header>input[type=radio]+label::after {
content: "\25BC";
}
.filter-header>input[type=checkbox]:checked+label::after {
transform: rotate(315deg);
}
.filter-header>filter-head-cb[type=radio]:checked+label::after {
transform: rotateX(180deg);
}
.filter-list {
margin-top: 10px;
}
.clear-button {
position: absolute;
top: 12px;
right: 6px;
}
.filter-checkboxes {
padding-top: 5px;
padding-left: 5px;
padding-right: 5px;
}
<div class="filter-list">
<h4 class="filter-header" id="S_1_66439_0">
<label for="tab_S_1_66439_0">Height (mm)</label>
<input class="filter-head-cb" id="tab_S_1_66439_0" type="checkbox" name="tabs" onclick="OnFilter(this);">
<div id="FilterPropertyOptions_S_1_66439_0" class="filter-checkboxes tab-content">
<div id="PropOptionTemplate_S_1_66439_0" style="display:none;"><input type="checkbox" value="<Actinic:FilterPropValue></Actinic:FilterPropValue>" id="<Actinic:FilterPropChoiceID></Actinic:FilterPropChoiceID>" actiniccustomselection="" actinicdisabledctrl="" onclick="OnFilter(this);">
<label for="<Actinic:FilterPropChoiceID></Actinic:FilterPropChoiceID>" actinicdisabledstyle=""><actinic:filterproptext></actinic:filterproptext></label><br></div>
<input type="checkbox" name="S_1_66439_0" value="300" id="S_1_66439_0-2" disabled="disabled" onclick="OnFilter(this);">
<label for="S_1_66439_0-2" style="color:gray">300 (0)</label><br>
<input type="checkbox" name="S_1_66439_0" value="500" id="S_1_66439_0-3" onclick="OnFilter(this);">
<label for="S_1_66439_0-3">500 (19)</label><br><input type="checkbox" name="S_1_66439_0" value="600" id="S_1_66439_0-4" onclick="OnFilter(this);">
<label for="S_1_66439_0-4">600 (17)</label><br><input type="checkbox" name="S_1_66439_0" value="750" id="S_1_66439_0-5" disabled="disabled" onclick="OnFilter(this);">
<label for="S_1_66439_0-5" style="color:gray">750 (0)</label><br><input type="checkbox" name="S_1_66439_0" value="1800" id="S_1_66439_0-6" disabled="disabled" onclick="OnFilter(this);"><label for="S_1_66439_0-6" style="color:gray">1800 (0)</label><br></div>
</h4>
</div>