Steps to design a unique input radio button with embedded attributes

In my current project, I am utilizing react styled components for styling. One issue that I have encountered is with the text placement within a box and the need to style it differently when checked.

What have I attempted so far?

I created an outer div and placed a radio input inside it with a display:none property. My intention was to style the outer element while keeping the radio button hidden. However, this approach rendered the radio button unclickable. Is there a solution to this problem? A react-specific solution would be highly appreciated.

.radio__input{
  display:none;
}

.radiobox{
  width:60px;
  height:60px;
  border:1px solid black;
}
//I want the div radiobox to be styled when one radiobox is selected

<div class="radiobox">
  <input type="radio" class="radio__input" name="radio"/>
  XS
</div>
<div class="radiobox">
  <input type="radio" class="radio__input" name="radio"/>
  S
</div>

Answer №1

I have implemented unique IDs for each radio button, allowing the <label> element's for attribute to link the labels with the corresponding radio buttons. This setup ensures that clicking on the label also checks the associated input. After setting up the functionality, I proceeded to style the radio buttons in their initial and checked states. It is important to note that CSS can only target elements based on the checked state of an input if they are siblings or children. Unfortunately, directly styling a parent element like the .radiobox container using pure CSS is not possible.

.radiobox {
  position: relative;
  width: 50px;
  height: 50px;
  border: 1px solid;
  display: flex;
  justify-content: center;
  align-items: center;
  display: inline-block;
}

input[type="radio"] {
  appearance: none;
}

input[type="radio"] + label {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

input[type="radio"]:checked + label {
  background: blue;
}
<div class="radiobox">
  <input type="radio" id="s" name="radio"/>
  <label for="s">S</label>
</div>

<div class="radiobox">
  <input type="radio" id="m" name="radio"/>
  <label for="m">M</label>
</div>

Answer №2

It is vital to have the radio button accessible while still maintaining its functionality.

An effective way to style radio buttons is by targeting their <label> element and using the CSS Adjacent sibling combinator based on the radio button's state.

Considerations for improving accessibility include:

  • Using <fieldset> to give an accessible name to the option group, even if it seems self-explanatory like "Green"
  • Ensuring focus visibility, which can be achieved by displaying the radio button within the fieldset
  • Providing each radio button with an accessible name, including hidden text inside labels

.color-options {
  display: flex;
  padding: .2em;
  gap: .4em;
}

.color-options:focus-within {
  outline: .2em solid blue;
}

.color-option {
  width: 2em;
  height: 2em;
}

input:checked+.color-option {
  outline: .2em solid darkseagreen;
}

/* credits to Scott O'Hara 
   https://www.scottohara.me/blog/2017/04/14/inclusively-hidden.html */
.visually-hidden {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}
<fieldset>
  <legend>Color</legend>

  <div class="color-options">
    <input type="radio" name="color" value="gray" id="color-gray" class="visually-hidden">
    <label class="color-option" style="background-color: gray" for="color-gray">
    <span class="visually-hidden">
    Gray
    </span>
  </label>

    <input type="radio" name="color" value="black" id="color-black" class="visually-hidden">
    <label class="color-option" style="background-color: black" for="color-black">
    <span class="visually-hidden">
    Black
    </span>
  </label>

    <input type="radio" name="color" value="darkgreen" id="color-darkgreen" class="visually-hidden">
    <label class="color-option" style="background-color: darkgreen" for="color-darkgreen">
    <span class="visually-hidden">
    Dark Green
    </span>
  </label>

  </div>
</fieldset>

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

Material-UI: The call stack has exceeded the maximum range, causing an Uncaught RangeError

I am currently utilizing the Dialog and Select components offered by Material-UI in conjunction with React. Here is a quick example: import React from 'react'; import { Dialog, MenuItem, Select } from '@material-ui/core'; class Examp ...

A guide on how to identify the return type of a callback function in TypeScript

Looking at this function I've created function computedLastOf<T>(cb: () => T[]) : Readonly<Ref<T | undefined>> { return computed(() => { const collection = cb(); return collection[collection.length - 1]; }); } Thi ...

What is a reliable method to retrieve the text from the current LI if all LI elements in the list share the

I'm encountering an issue with retrieving the text from LI elements because I have 10 list items and they all have the same class name. When I attempt to fetch the text using the class name or id, I only get the text of the last item. Here is my code ...

The className property of a Material UI form input component

Following along with this specific tutorial to delve into the concept of dynamic forms. It specifies using a custom name and id properties for input elements. <input type="text" name={ageId} data-id={idx} id={ageId} value={cats[idx].age} c ...

react-router: The 'history' type is not found in the current context

Here is some code snippet from App.tsx: interface AppProps{ history: any } export default class App extends React.Component<AppProps,...> { public state = { target: this.props.history.push('/') }; private route() { if (! ...

Issue with text input field causing the Enter key to not create a new line

In the example above, the text is placed in the middle of the text area. Here is the CSS code : .form-control { height: 300px; display: block; width: 100%; padding: 0.375rem 0.75rem; font-size: 1rem; font-weight: 400; line-heig ...

Accessing JSON data from a URL for use within a specific context

I am currently utilizing the request module within Express to fetch a JSON file from a specified link. var url = 'https://api.github.com/users/google/repos'; request.get({ url: url, json: true, headers: {'User-Agent': &apo ...

Encountered a circular structure error (SVGSVGElement) while attempting to convert in React App Tracking Manager (

I am encountering a challenge while attempting to integrate Google Tag Manager into my React Web App. The issue arises from the circular structure of SVGSVGElement. https://i.stack.imgur.com/wXZg5.png To incorporate custom SVG icons in my component, I ha ...

Finding the maximum value among multiple variables in AngularJS

After performing calculations, I have assigned specific values to variables. console.log("Gain_weight is "+ Gain_weight); console.log("Gain_smoking is "+ Gain_smoking); console.log("Gain_exercising is "+ Gain_exercising); console.log("Gain_foodhabits ...

AngularJS is encountering an issue where it cannot locate the App Module

Whenever I attempt to execute this code, I encounter errors. Below is the code followed by the error message: index.html: <!DOCTYPE html> <html> <head> <meta id="meta" name="viewport" content="width=device-width, initial-scale=1 ...

Place the retrieved data from the API directly into the editor

I've integrated the LineControl Editor into my app and everything is functioning perfectly, except for when I attempt to insert text into the editor. Here's the link to the LineControl GitHub page: https://github.com/suyati/line-control/wiki Fo ...

Error in electron-builder: Module 'dmg-license' was not found

Seeking a straightforward method to create an electron app for macOS from a Linux machine. Unfortunately, the electron-builder -m command is not functioning properly. Here is the complete output of the command: electron-builder -m • elec ...

Refreshing and reloading within the same jQuery function

My PHP application involves the use of 2 PHP files. chart.php - This page includes a Google chart. <div id="chart_div" style="height:100%;width:100%"> </div> <script type="text/javascript"> google.charts.load('current', ...

Unable to view the image in browsers other than Internet Explorer

On a webpage, there is a feature where clicking on the "Add More" link should display an input box and a "Delete" button image. Surprisingly, this functionality works perfectly on IE browsers, but not on Mozilla or Chrome. In non-IE browsers, only the text ...

Retrieving parameters from within iframe (child)

I currently have an embedded Iframe within a website, with both residing on different domains that I own. My goal is to pass a query parameter to the src attribute of the iframe. <iframe id="iframe" title="Survey" allowtr ...

Experiencing Troubles with Design Customization in Flowbite-React

I'm currently diving into the world of theme customization with Flowbite-React by following their guide on creating a reusable component with a custom theme. Unfortunately, I seem to be encountering some difficulties in getting it to function properly ...

Error: The dataProvider function toJSON is not recognized

import restProvider from 'ra-data-simple-rest' const dataProvider= process.env.REACT_APP_API+'/api/link' <Admin dataProvider={restProvider(dataProvider) }> <Resource name='endpoint' options={{label:'MyLab ...

Is there a way to include values in the body of an HTTP GET request using Angular?

I've created a function in my service that looks like this: /** * Retrieve all data * @param sendSelectedValues string */ getAllActPlanBalanceYearData(sendSelectedValues: any): Observable<any> { const url = `/yearlyvalues/act-and ...

Exploring Vue's feature of passing props and emitting events within nested components

Within my coding project, I am facing the challenge of properly implementing a parent component containing a form that includes a birthday component. This birthday component consists of two separate components within it. My task is to effectively pass prop ...

Avoid causing the newline character to display

var i = 'Hello \n World' console.log(i) /* Output: Hello World */ /* Desired output: Hello \n world */ var j = 'javscr\u0012ipt' console.log(j) /* Output: javscr ipt */ /* Desired output: javscr\u0012ipt */ ...