I'm trying to implement radio buttons which kind of work like segmented controls:
* {
margin: 0;
padding: 0;
}
.container {
background-color: brown;
width: 80vw;
}
.box {
display: flex;
flex-direction: row;
border: 2rem solid skyblue;
border-radius: 999px;
}
label {
flex: 1;
padding: 2rem;
border-radius: 999px;
text-align: center;
}
input {
display: none;
}
input:checked + label {
background-color: skyblue;
}
<div class="container">
<div class="box">
<input type="radio" id="hello" name="test" checked />
<label for="hello">Hello</label>
<input type="radio" id="world" name="test" />
<label for="world">World</label>
</div>
</div>
However, there's an annoying gap of about 1px between the nested label and the parent div:
This issue is similar to this question, but the workarounds suggested don't really work for my use case since I can't change the background color. I'm also curious if this is a browser bug or some kind of anti-aliasing issue.
just add box shadow to the input:check + label
input:checked + label {
background-color: skyblue;
box-shadow: 0px 0px 0 1px skyblue;
}
Link to Jsfiddle
I don't know the reason why you are getting that 1 px gap but you can add "transform: translateX(-1px);" to shift it left by 1px. This can work as a temp solution.
label {
flex: 1;
padding: 2rem;
border-radius: 200px;
text-align: center;
transform: translateX(-1px);
}
Change label border-radius 999px to 35px
label {
flex: 1;
padding: 2rem;
border-radius: 35px;
text-align: center;
}
* {
margin: 0;
padding: 0;
}
.container {
background-color: brown;
width: 80vw;
}
.box {
display: flex;
flex-direction: row;
border: 2rem solid skyblue;
border-radius: 999px;
}
label {
flex: 1;
padding: 2rem;
border-radius: 35px;
text-align: center;
}
input {
display: none;
}
input:checked + label {
background-color: skyblue;
}
<div class="container">
<div class="box">
<input type="radio" id="hello" name="test" checked />
<label for="hello">Hello</label>
<input type="radio" id="world" name="test" />
<label for="world">World</label>
</div>
</div>
Related
I am trying to write code for folder tabs
what I am trying to archive is that when each folder tab is clicked, it should be shown the top most of other tabs while the others are positioned behind it.
I tried to work with z-index:-1 for all tabs yet the clicked tab gain z-index:3 but it doesn't work.
One strange thing is that when I remove the line of z-index : -1; in label style which will make the default z-index of the label to be auto (z-index : auto;) it works. My question is that why z-index: -1 doesn't work while z-index:auto works for label style?
section {
padding: 2rem;
height: 100vh;
display: flex;
flex-flow: column nowrap;
}
section .header {
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
}
section .header input {
display: none;
}
section .header label {
margin-left: -1rem;
padding: 0.5rem 1rem;
display: inline-block;
position: relative;
z-index: -1;
border-radius: 27px 0 0 0;
}
section .header input:checked~label {
z-index: 3;
background-color: grey;
}
section .header .weather label {
background-color: greenyellow;
}
section .header .others label {
background-color: indianred;
}
section .header .about-us label {
background-color: indigo;
}
section .main {
flex: 1;
border: 1px solid black;
}
<section>
<div class="header">
<div class="weather">
<input type="radio" name="tab" id="weather">
<label for="weather">weather</label>
</div>
<div class="others">
<input type="radio" name="tab" id="others">
<label for="others">others</label>
</div>
<div class="about-us">
<input type="radio" name="tab" id="about-us" checked>
<label for="about-us">about-us</label>
</div>
</div>
<div class="main">
This is main
</div>
</section>
scss:
section {
padding: 2rem;
height: 100vh;
display: flex;
flex-flow: column nowrap;
.header {
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
input {
display: none;
}
label {
margin-left: -1rem;
padding: .5rem 1rem;
display: inline-block;
position: relative;
z-index: -1; // while (z-index : auto;) works. why?
border-radius: 27px 0 0 0;
}
input:checked~label {
z-index: 3;
background-color: grey;
}
.weather {
label {
background-color: greenyellow;
}
}
.others {
label {
background-color: indianred;
}
}
.about-us {
label {
background-color: indigo;
}
}
}
.main {
flex: 1;
border: 1px solid black;
}
}
When you use z-index: -1 you should also add z-index: 0; to its parent - section .header div in your case, in order to put the element behind the desired element(s) in the same div. Otherwise it puts it behind the root element of the page. But in your case, the problem is that you hide the radio inputs. Apply the following css: position: absolute; width: 100%; height: 100%; opacity: 0; to your section .header input instead of the display:none; and it will work
I have the following images that represent each case for user input-validation.
No Error:
Input Error:
I would like to maintain the alignment of the upper image while moving the error message underneath the input field (keep Label on left and Input on right, place error message underneath and aligned with input).
.group {
display: flex;
flex-wrap: nowrap;
margin-top: 4px;
}
.group label {
display: flex;
width: 15%;
line-height: 30px;
justify-content: center;
align-items: center;
}
.group input[type="text"] {
width: 85%;
border: 1px solid rgb(116, 115, 115);
padding-left: 3px;
}
.group textarea:focus,
input:focus {
outline: none;
}
.group .errorMsg {
color: #cc0033;
display: inline-block;
font-size: 12px;
line-height: 15px;
margin: 5px 0 0;
width: 100%;
}
.group .errorMsg {
display: none;
}
/* Error Styling */
.err label {
color: #cc0033;
}
.err input[type=text] {
background-color: #fce4e4;
border: 1px solid #cc0033;
outline: none;
}
.err .errorMsg {
display: inline-block;
}
<div class="group err">
<label for="time">Time</label>
<input type="text" name="time" id="time" />
<div class="errorMsg">Invalid Time Format</div>
</div>
<div class="group">
<label for="time2">Time2</label>
<input type="text" name="time2" id="time2" />
<div class="errorMsg">Invalid Time Format</div>
</div>
Any recommendations to fix the poor alignment?
You can align them like this. I have added comments to the right of the changes.
.group {
display: flex;
flex-wrap: wrap; /* Wrap the elements */
margin-top: 4px;
}
.group label {
display: flex;
width: 15%;
line-height: 30px;
justify-content: center;
align-items: center;
}
.group input[type="text"] {
width: 85%;
border: 1px solid rgb(116, 115, 115);
padding-left: 3px;
flex: 1; /* Take the remaining width */
}
.group textarea:focus,
input:focus {
outline: none;
}
.group .errorMsg {
color: #cc0033;
display: inline-block;
font-size: 12px;
line-height: 15px;
margin: 5px 0 0;
width: 100%;
}
.group .errorMsg {
display: none;
}
/* Error Styling */
.err label {
color: #cc0033;
}
.err input[type=text] {
background-color: #fce4e4;
border: 1px solid #cc0033;
outline: none;
}
.err .errorMsg {
display: flex; /* Instead of inline-block */
width: 85%; /* Same as input width */
left: 15%; /* Rest of the width */
position: relative; /* Relative to parent */
}
<div class="group err">
<label for="time">Time</label>
<input type="text" name="time" id="time" />
<div class="errorMsg">Invalid Time Format</div>
</div>
<div class="group">
<label for="time2">Time2</label>
<input type="text" name="time2" id="time2" />
<div class="errorMsg">Invalid Time Format</div>
</div>
every time when I have to work with Inputs this problem occurs.
My goal is to make a simple input form and achieve that 2 Inputs type number will be the same width, with small space between them in one line, just under "Description" input.
I've tried to add them to divs and apply Display:inline-block to them, but it didn't work. Now I've tried to apply display: flex on it a this is the result. Changing the width of input does not work. Thank you for your help.
.inputBox{
width: 30%;
padding: 2em;
text-align: center;
background-color: white;
border-radius: .3em;
}
.inputBox h3{
font-size: 2em;
font-weight: 300;
}
.inputBox input[type="text"]{
width: 100%;
padding: .5em;
margin: 1em 0;
border-radius: .3em;
border: 1px solid grey;
box-sizing: border-box;
}
.inputBox input[type="number"]{
padding: .5em;
border-radius: .3em;
border: 1px solid grey;
box-sizing: border-box;
width: 100%;
}
label{
display: block;
text-align: left;
}
.flex{
display: flex;
justify-content: space-between;
}
<div className="inputBox">
<h3>Please set your alarm</h3>
<label for="text">Description</label>
<input type="text" id="text" />
<div className="flex">
<div className="inputNumber">
<label>Hours</label>
<input type="number" />
</div>
<div className="inputNumber">
<label>Minutes</label>
<input type="number" />
</div>
</div>
.inputBox{
width: 30%;
padding: 2em;
text-align: center;
background-color: white;
border-radius: .3em;
}
.inputBox h3{
font-size: 2em;
font-weight: 300;
}
.inputBox input[type="text"]{
width: 100%;
padding: .5em;
margin: 1em 0;
border-radius: .3em;
border: 1px solid grey;
box-sizing: border-box;
}
.inputBox input[type="number"]{
padding: .5em;
border-radius: .3em;
border: 1px solid grey;
box-sizing: border-box;
width: 100%;
}
label{
display: block;
text-align: left;
}
.flex{
display: flex;
justify-content: space-between;
}
.inputNumber{
flex-basis:48%;
}
<div class="inputBox">
<h3>Please set your alarm</h3>
<label for="text">Description</label>
<input type="text" id="text" />
<div class="flex">
<div class="inputNumber">
<label>Hours</label>
<input type="number" />
</div>
<div class="inputNumber">
<label>Minutes</label>
<input type="number" />
</div>
</div>
If you want to keep inputBox's width at 30%, you can do something like this:
HTML
<div class="inputBox">
<h3>Please set your alarm</h3>
<label for="text">Description</label>
<input type="text" id="text" />
<div class="flex">
<div class="inputNumber">
<label>Hours</label>
<input type="number" />
</div>
<div class="inputNumber second">
<label>Minutes</label>
<input type="number" />
</div>
</div>
</div>
CSS
.inputBox {
width: 30%;
padding: 2em;
text-align: center;
background-color: white;
border-radius: .3em;
}
.inputBox h3 {
font-size: 2em;
font-weight: 300;
}
.inputBox input[type="text"] {
width: 100%;
padding: .5em;
margin: 1em 0;
border-radius: .3em;
border: 1px solid grey;
box-sizing: border-box;
}
.inputBox input[type="number"] {
padding: .5em;
border-radius: .3em;
border: 1px solid grey;
box-sizing: border-box;
width: 100%;
}
label {
display: block;
text-align: left;
}
.flex {
display: flex;
flex-direction: row;
}
.inputNumber {
width: 50%;
}
.second {
margin-left: 5%;
}
two problems:
you are using className when you should be using class
change .inputBox width to 100%
also, you should ALWAYS try to post a working snippet that shows your problem. You will get back answers faster and ones that are more likely to work!
.inputBox{
width: 100%;
padding: 2em;
text-align: center;
background-color: white;
border-radius: .3em;
}
.inputBox h3{
font-size: 2em;
font-weight: 300;
}
.inputBox input[type="text"]{
width: 100%;
padding: .5em;
margin: 1em 0;
border-radius: .3em;
border: 1px solid grey;
box-sizing: border-box;
}
.inputBox input[type="number"]{
padding: .5em;
border-radius: .3em;
border: 1px solid grey;
box-sizing: border-box;
width: 100%;
}
label{
display: block;
text-align: left;
}
.flex{
display: flex;
justify-content: space-between;
}
<div class="inputBox">
<h3>Please set your alarm</h3>
<label for="text">Description</label>
<input type="text" id="text" />
<div class="flex">
<div class="inputNumber">
<label>Hours</label>
<input type="number" />
</div>
<div class="inputNumber">
<label>Minutes</label>
<input type="number" />
</div>
</div>
you can use display: grid on your parent and modify the first child of grid to span across the first line like:
.parentContainer {
/* this will create the grid for us with 1rem gap between children */
display: grid;
grid-template-columns: repeat(1, 1fr),
grid-gap: 1rem;
}
.theChildElementYouWantToFullWidth {
grid-column: 1 / span 3;
}
for more information check this doc from MDN on Grid styling!
View problem at:
https://jsfiddle.net/xa3u5w8j/5/
The reason why I want my button div to be flex is it has this CSS:
.button {
background-color: aqua;
text-align: center;
width: 150px;
height: 50px;
cursor: pointer;
display: flex;
}
And thus, removing the flex property will cause its text to mis-align.
I want all 3 labels to be aligned to the right, but it somehow is not working for the 3rd label. Any insight can help! Thanks
EDIT: Code
/* Gives the form left/right margin and sets text color */
.course-info {
margin: 0 20px 0 20px;
color: #9E7772;
}
/* Makes sure the form contents are lined up */
.course-info label {
display: inline-block;
width: 540px;
text-align: right;
margin: 20px 0 20px 0;
align-items: top;
}
/* Styles the input and textarea and make sure they line up */
.course-info input {
width: 400px;
background-color: white;
border-bottom: 3px solid #E0DEDE;
}
.course-info textarea {
word-break: break-all;
width: 394px; /* 400px(intended length) - 2*3px(border width) */
height: 100px;
border: 3px solid #E0DEDE;
display: inline-block;
}
/* Makes sure they don't break into diff lines */
.course-title label, .course-title input{
float: none;
display: inline-block;
}
.invitation-section {
display: flex;
justify-content: right;
}
/* Special length and height */
.invitation-link{
max-width: 250px; /* 400px - button width to align on the right side */
max-height: 20px;
}
.button-wrapper{
display: inline-block;
}
.button {
background-color: aliceblue;
width: 150px;
display: flex; /*This is necessary*/
}
<form class="course-info" onSubmit={handleSettingsChange}>
<label>
Course Title:
<input type="text" value="Whatever is here"/>
</label>
<label>
<span>Description:</span>
<textarea type="text">Random text here</textarea>
</label>
<label>
<div class="invitation-section">
<span>Invitation:</span>
<textarea readOnly
class="invitation-link" type="text">
</textarea>
<label class="button-wrapper">
<div class="button">Button</div>
</label>
</div>
</label>
</form>
label {
display: inline-block;
width: 140px;
text-align: right;
}
.button {
background-color: aqua;
text-align: center;
width: 150px;
height: 50px;
cursor: pointer;
display: flex;
}
.invitation-link {
max-width: 250px;
/* 400px - button width to align on the right side */
max-height: 20px;
}
.block {
margin-bottom: 10px;
}
label {
display: inline-block;
width: 140px;
text-align: right;
}
.button {
background-color: aqua;
text-align: center;
width: 150px;
height: 50px;
cursor: pointer;
display: flex;
}
.invitation-link {
max-width: 250px;
/* 400px - button width to align on the right side */
max-height: 20px;
}
.block {
margin-bottom: 10px;
}
.course-info textarea {
word-break: break-all;
width: 394px; /* 400px(intended length) - 2*3px(border width) */
height: 100px;
border: 3px solid #E0DEDE;
display: inline-block;
}
button {
display: inline-block;
margin-left: 10px;
margin-top:-2px;
background-color: aqua;
width: 80px;
height: 30px;
cursor: pointer;
}
<form class="course-info" onSubmit={handleSettingsChange}>
<div class="block">
<label> Course Title:</label>
<input type="text" value="Whatever is here" />
</div>
<div class="block">
<label>Description:</label>
<textarea type="text">Random text here</textarea>
</div>
<div class="block invitation-section">
<label>Invitation:</label>
<textarea readOnly class="invitation-link" type="text">
</textarea>
<button>
Copy
</button>
</div>
</form>
I have been banging my head against the wall on this one for a while and can't seem to find how to do this. I have a card with two rows (card-body) classes. each row represents a radio button (input) with a corresponding label. When the user clicks the radio button I want the background to change colors. Right now that is working, but the background is only working for the label and not the whole div that contains the card row. I'm looking for a HTML/CSS-only answer, as I think it's probably something simple that I'm doing wrong. Thanks!
CSS
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 0.25rem;
}
.card-body {
flex: 1 1 auto;
padding: 1.25rem;
}
.pick input[type="radio"] {
display: none;
/* comment this line to see the radio buttons */
}
.pick label {
display: inline-block;
background-color: red;
}
.pick input[type="radio"]:checked+label {
background-color: blue;
}
.card {
border-style: solid;
border-width: 5px;
}
label {
display: block;
width: 100%;
}
HTML
<div class="card">
<div class="card-body pick" for="i1">
<input type="radio" name="g1" id="i1" value="you" data-target="r65">
<label class="ben" for="i1" id="r1">you</label>
</div>
<div class="card-body pick" for="i2">
<input type="radio" name="g1" id="i2" value="me" data-target="r65">
<label class="ben" for="i2" id="r2">me</label>
</div>
</div>
JSFiddle: https://jsfiddle.net/j3mskfjv/11/
You need to set your labels to display: block with width of 100%, like so:
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 0.25rem;
}
.card-body {
flex: 1 1 auto;
}
.pick input[type="radio"] {
display: none;
/* comment this line to see the radio buttons */
}
.pick label {
display: inline-block;
background-color: red;
}
.pick input[type="radio"]:checked+label {
background-color: blue;
}
.card {
border-style: solid;
border-width: 5px;
}
.pick {
display: flex;
}
label {
display: block;
flex: 1;
padding: 1.25rem;
}
<div class="card">
<div class="card-body pick" for="i1">
<input type="radio" name="g1" id="i1" value="you" data-target="r65">
<label class="ben" for="i1" id="r1">you</label>
</div>
<div class="card-body pick" for="i2">
<input type="radio" name="g1" id="i2" value="me" data-target="r65">
<label class="ben" for="i2" id="r2">me</label>
</div>
</div>