When using CSS, targeting the parent <label> element of a selected <input> element

Update: it seems that I cannot utilize <> brackets as it hides names?...

I have come across similar versions of this query, but none of them address my specific problem, which I believe is quite simple. I am constructing the following radio button group in react:

    const options = ["YTD", "Week", "Month", "Pre AS", "Post AS"]
    const buttons =
        <form>
            <div className="radio-group">
                {options.map((d, i) => {
                    return (
                        <label>
                            <input
                                type={"radio"}
                                value={options[i]}
                                checked={timeframeNew === options[i]}
                                onChange={this.handleTimeframeNewChange}
                            />
                            <span>{options[i]}</span>
                        </label>
                    )
                })}
            </div>;

and here is my current CSS for styling the buttons to look nice...

input[type=radio] { 
  position: absolute;
  visibility: hidden;
  display: none;
}

label {
  color: #333;
  background: #EEE;
  display: inline-block;
  cursor: pointer;
  font-weight: bold;
  padding: 5px 20px;
  border: 2px solid orange;
}

input[type=radio]:checked + label {
  color: red;
  background: #333;
}

label + input[type=radio] + label {
  border-left: solid 2px blue;
}

.radio-group {
  border: solid 2px green;
  display: inline-block;
  margin: 20px;
  border-radius: 10px;
  overflow: hidden;
}

Regrettably, the CSS is not functioning as expected. Especially, the selection - input[type=radio]:checked + label does not work because there is no label directly after an input. The only way I have managed to successfully make my react onChange handler function operate is by placing the input within the label, like so, and then returning the label in each .map loop.

*Since the return must be a single element, if I want to remove the out of the label, I would then need to encompass them both in a div or a span, and for some reason doing so disrupts my onChange handler...

So my inquiry is, how how how can I, in CSS, select the label that corresponds to the clicked input. I aim to modify the entire label's color and background when it is / isn't clicked, so selecting the span doesn't assist (since that solely alters the text's color/background, not the entire label.

Thank you in advance!!

Answer №1

One of the limitations of CSS is that it can only select child and sibling elements, not parent elements. In order to customize radio buttons and checkboxes, I usually hide the default ones and create custom styles like the following:

.button-group{
  font-size:0; /*Prevents a space from occuring between buttons*/
}
.button-group input{
  position:absolute; 
  visibility:hidden; /* display:none causes some browsers to ignore the input altogether */
}
.button-group input+span{
  display:inline-block;
  line-height:20px;
  font-size:1rem;
  vertical-align:top;
  padding:0 10px;
  color:#000;
  border-left:1px solid #a00;
}
.button-group label:first-child input+span{
  border-radius:10px 0 0 10px;
  border-left:0;
}
.button-group label:last-child input+span{
  border-radius:0 10px 10px 0;
}
.button-group input:not(:checked)+span{
  background-color:#faa;
}
.button-group input:not(:checked)+span:hover{
  background-color:#f66;
}
input[type=radio]:checked+span{
  background-color:#f33;
}
<div class="button-group">
  <label>
    <input type="radio" value="1" name="myfield" />
    <span>Option 1</span>
  </label>

  <label>
    <input type="radio" value="2" name="myfield" />
    <span>Option 2</span>
  </label>

  <label>
    <input type="radio" value="3" name="myfield" />
    <span>Option 3</span>
  </label>
</div>

Answer №2

One possible method to achieve this using CSS alone is by utilizing the :has-selector

For example:

<label>
  Option A
  <input type="radio" name="bar" value="1" />
</label>

<label>
  Option B
  <input type="radio" name="bar" value="2" />
</label>
label:has(input:checked) {
  background: blue;
}

Answer №3

*When trying to remove a label as the return element, it is necessary to enclose both elements in a div or span. However, I encountered an issue where this broke my onChange handler...

To avoid rendering multiple elements within a div or span, you can utilize

<React.Fragment> <input /> <span /> </ReactFragment>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Conceal zoom-in function in video element for Edge and Internet Explorer

I'm trying to get rid of the zoom in control on the video tag that only shows up in Edge and Internet Explorer. I've attached a snapshot for reference. I've searched for a solution but haven't had any luck. https://i.sstatic.net/7Lx8k. ...

Every time I try to useNavigate, I end up with a

Welcome.js import CreatePopUp from "./popup"; import createWelcomePage from "./welcomePage"; import {BrowserRouter , Route} from "react-router-dom"; import {Routes} from "react-router" f ...

What are the steps to recreate the layout of my image using HTML?

What's the best way to create a layout in HTML that expands to fit the entire screen? ...

Ways to evenly space out the elements in my Bootstrap 4 navbar

I am struggling to evenly space my elements in the navbar. I have tried various solutions from other sources but haven't found anything that works for me. <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <div cla ...

Having trouble with installing "npm install semantic-ui-react semantic-ui-css"? Any ideas on how to fix it?

Encountered an error while trying to install Semantic UI React and Semantic UI CSS: npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: [email protected] npm ERR! Found: [ema ...

How can I implement zoom functionality using a button click in React Leaflet version 4.2.0?

**Is it possible to add a button next to the map in React-Leaflet that allows me to change the zoom level of the map with a click? For example, imagine I have a map displaying a country at zoom level 7. Above the map, there are buttons for different citie ...

Add the onclick function to $(document).ready for applying the desired functionality

I've been trying to create a fading effect for 3 divs on my page, similar to the one in this example: http://jsfiddle.net/x4qjscgv/6/ However, I want the fade animation to trigger only when a user clicks a button. I attempted to use the document.getE ...

Unable to align the row in the center

I'm having trouble centering a row with 4 columns. It seems off when I look at the picture below, specifically at the vertical border under the "most read" blue square. html file: <div class="block-section"> <div class="sm-section-wrapper" ...

Bug with updating items in a React modal

When updating during the process, the same id value is being updated every time. What could be causing this issue? For instance, the field with id number 3 is updated with every update operation. The index value is being used in the loop for the update pro ...

Employing the powerful Math.pow() function within the setState() method

In this ReactJS code example, the goal is to update the value of a div element with every click of a button using the Math.pow() method. However, it seems that the method is not working as intended. Can someone explain why? The handlerButton function in ...

What is the best way to ensure that two divs in the same row float in opposite directions?

Check out this JSFiddle to see what I have done so far: JSFiddle Link html <div class="results"> <h2>Some data</h2> <ul style="margin:0;padding:0;"> <li class="resultsListItem" style="list-style-type: none;"> ...

Creating a banner using four grid elements, with each element containing four child elements, is a simple process that can

Can you assist me in recreating my idea from an image? I am having trouble understanding how to select and place other elements, and then return them to their original positions after deselecting... I attempted to use a grid but it did not work properly. ...

Javascript dynamically generates CSS animations

I need assistance creating a div with a CSS3 animated timer inside it when a button is clicked. Here is the code I have been working on: http://jsfiddle.net/arcco96/y5nov6rz/1/. Unfortunately, the div is not being created as expected. I believe the code sh ...

What's preventing me from tapping on hyperlinks on my mobile device?

I'm currently working on a website (saulesinterjerai.lt) and everything seems to be functioning properly, except for the fact that on mobile devices, the links aren't clickable and instead navigates to other layers. How can I disable this behavio ...

Tips for effectively utilizing Higher Order Components with React Hooks?

What is the optimal method for utilizing HOC when needing to retrieve data from a hook? There are two approaches: Passing the data received from the hook as a parameter to the HOC HOC: export const withAuth = ( isAuth: boolean, { ComponentForAut ...

What role does the sequence play in matrix transitions that involve rotating and translating simultaneously?

Attempting to animate a matrix3d with both rotation and translation concurrently has yielded unexpected results for me. It seems that changing the order of applying rotation and translation produces vastly different outcomes. http://jsfiddle.net/wetlip/2n ...

Parent div contains three child divs without automatically resizing

I'm new to web design and I'm curious about how to achieve a layout like this: <div id="container_m"> <div id="left"> <p>My name is Barnabas</p> </div> <div id="right"> <p>For ...

Removing the outline border from a Material IconButton when clicked using styled Components: A guide

Is there a way to remove the outline border that appears when using a material iconButton and it is clicked? I've tried various methods without success. Can styled components help achieve this? Take a look at the image below. Image https://i.sstati ...

Building a drop-down menu with descriptions in React is a simple process that involves using

I am currently working on implementing a dropdown list with descriptions in React. Here is an image for reference: https://i.sstatic.net/R8CYN.png Is there a different approach using bootstrap or Material-UI that I could use to achieve this? Currently, I ...

What is the correct syntax for implementing scrollTop and transform CSS effects in jQuery?

I find myself in a bit of a quandary, as this question may seem rather simple but it's causing me some confusion. I'm trying to navigate the CSS transform syntax within a jQuery script that calculates window height. Here is the code in question: ...