Radiant UI: Radio Button featuring a stylish svg circle

Hey everyone, I’ve been attempting to customize the Material-UI radio button using CSS modules but haven’t had much luck. It seems like the easiest solution would be to use the makeStyles function from Material-UI, however, I am required to work with CSS modules.

This is the standard Material-UI radio button:

https://i.sstatic.net/Hh6gu.png

I need to create this instead: https://i.sstatic.net/cwSTU.png.

Although Material-UI doesn't provide a check mark option, I believe I can achieve it with SVG. However, I’m struggling to figure out how to implement it. Any guidance or assistance would be greatly appreciated.

UPDATE: I realized that I could insert an SVG as a component using the Radio component's checkedIcon property, which I found in the Material-UI icons documentation here.

While this took care of my needs for the checked 'Active' state, I faced difficulties creating the 'Hover' effect. Initially, I thought I needed an SVG for this as well, only to realize that I could simply draw a circle using ::before or ::after as a pseudo element and style it to fit within the main circle, same goes for the 'Focus' state.

Answer №1

If you want to customize the appearance of the Checkbox component, you can make use of the icon and checkedIcon properties as described in the Checkbox API documentation (https://material-ui.com/api/checkbox/#props). You have the flexibility to pass any kind of component that renders your SVG graphic.

In response to a query about improving the visual presentation, I created a small demo inspired by the Material-UI checkbox demo. The demo incorporates CSS Modules to address additional requirements such as focus states. While not perfect, it aims to convey the concept (similar to hover states).

Here is an excerpt from the component:

import React from 'react';
// The CSS will be injected into the page by webpack, parcel, or other tools
import styles from './CssModulesCheckboxes.css';
import Checkbox from '@material-ui/core/Checkbox';

function StyledCheckbox(props) {
  return (
    <Checkbox
      checkedIcon={<span className={styles.checkedIcon} />}
      icon={<span className={styles.icon} />}
      inputProps={{ 'aria-label': 'decorative checkbox' }}
      {...props}
    />
  );
}

export default function CssModulesButton() {
  return (
    <div>
      <StyledCheckbox />
      <StyledCheckbox defaultChecked />
      <StyledCheckbox defaultChecked disabled />
    </div>
  );
}

And here is a snippet from the CSS module:

.icon {
  border-radius: 3px;
  width: 16px;
  height: 16px;  
  // Additional styling properties...
}

// Hover effects on input...

.checkedIcon {
  background-color: #137cbd;
  // More customized styles...
}

// Disabled state for checked icon...

To see this sample in action on CodeSandbox, visit: https://codesandbox.io/s/css-modules-vdbi8

Answer №2

Give this code snippet a try:

Here is the HTML:

<div>
  <input type="radio" name="my-radio" id="radio-option-1"/>
  <label for="radio-option-1"> <span></span> Select Me </label>
</div>

<div>
  <input type="radio" name="my-radio" id="radio-option-2"/>
  <label for="radio-option-2"> <span></span> Choose Me 2</label>
</div>

<div>
  <input type="radio" name="my-radio" id="radio-option-3" active/>
  <label for="radio-option-3"> <span></span> Pick Me 3 (Active)</label>
</div>

<div>
  <input type="radio" name="my-radio" id="radio-option-4" disabled/>
  <label for="radio-option-4"> <span></span> Got Me 4 (Inactive)</label>
</div>

The CSS styles are as follows:

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

label {
  cursor:pointer;
  color: #555;
}

input[type="radio"] + label span {
    display: inline-block;
    vertical-align: middle;
    width: 45px;
    height: 45px;
    border: 2px solid #ff0000;
    border-radius: 10px;
    background-color: #ffffff;
    text-align: center;
}

input[type="radio"][disabled] + label span {
  background-color: #ececec;
  border: #ececec;
}

input[type="radio"][active] + label span {
   background-color: #ff0000;
}
input[type="radio"][active] + label span:hover {
  background-color: #ff0000;
  border: 2px solid #ff0000;
}

/* input[type="radio"] + label span:hover {
  text-align: center;
  vertical-align: bottom;
} */

input[type="radio"] + label span:focus {
  background-color: #ffffff;
}
input[type="radio"]:not([active]):not([disabled]):not(:checked) + label span:focus::before {
   content: '';
   display: inline-block;
   width: 70%;
   height: 70%;
   border-radius: 50%;
   background-color: #ff0000;
   border: 2px solid #ff0000;
   margin-top: calc(100% - 76%);
}

input[type="radio"]:not([active]):not([disabled]):not(:checked) + label span:hover::before {
   content: '';
   display: inline-block;
   width: 70%;
   height: 70%;
   border-radius: 50%;
   background-color: #ffffff;
   border: 2px solid #ff0000;
   margin-top: calc(100% - 85%);
}

input[type="radio"] + label span  {
  border-radius: 50%;
}

input[type="radio"][disabled] + label span::before,
input[type="radio"][active] + label span::before,
input[type="radio"]:checked + label span::before {
   content: "✓";
   color: #ffffff;
   text-align: center;
   font-size: 40px;
}

input[type="radio"]:checked + label span {
    background-color: #ff0000;
    text-align: center;
}

Check out the demo here: https://jsfiddle.net/40ktw6jv/58/

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

Does the html label prevent propagation from occurring?

Can anyone explain why the toggle function is not being executed when clicking inside the box with the black border, but works when clicking outside of it (although not on the checkbox)? var checks = document.querySelectorAll("ul li"); for (var i = 0 ...

Using React Router to Identify Whether an Element is Displayed within an Outlet or Directly as a Child of a Route

My current project utilizes React Router v6 to handle routing. I have set up different routes for mobile and desktop devices in order to display varying amounts of information based on screen size. Mobile /site/id: Only displays the Detailview Desktop / ...

What is the best way to customize media queries in a child theme?

Is it possible to override a media query in my Wordpress child theme? Currently, the media query is set at max-width: 1024px, but I would like it to be triggered at a smaller size, maybe around 700px. The issue arises when attempting to create a new media ...

Style the modal body to display as a block on both desktop and mobile devices using CSS

My goal is to ensure that the modal-body is vertically aligned for optimal visibility on both mobile phones and PCs. I am utilizing bootstrap for this purpose. <div class="modal-body" style="display: inline-block;"> <div> ...

Implementing border-right leads to alignment problems

I'm currently working on creating a list with bootstrap-Accordion using react-bootstrap. I'm applying a background color and border left to the selected item. The problem I'm facing is: Whenever I activate a bar, the text shifts to the rig ...

Capture the keydown event for an input field

I am encountering an issue with my multipage form that consists of <input /> fields. I also have a set of "hotkeys" next to the form which are implemented using a custom hook (window.attachEventListener("keydown", handler)) to listen for an ...

Multiple buttons in a single field

I am attempting to replace a Dropdown list with a series of buttons that will streamline the choices previously displayed by the dropdown list. Specifically, we are using graphic png files for the types of buttons. We experimented with checkboxing and ra ...

Using React TypeScript to create interactive maps with Highcharts

I'm currently attempting to implement the WorldMap example using TypeScript in Highcharts, but I am encountering difficulties with the series within the Highcharts Options: (Highcharts, Highstock, Highmaps, Gantt) Series options for specific data and ...

What is the best way to associate dates with a particular ID within a textfield's value?

I am working with an array of objects called dates, and each object in the array looks like this: {id: 9898, date: 10/06/2020}. Within this array, there are multiple objects with the same id, and I want to display dates with the same id in a TextField com ...

The background image fails to load due to a quotation mark in the URL

I am currently facing some challenges with a project where the process of converting text into URLs is not functioning properly. This issue arises when certain URLs contain a quote mark, for example somethi'n.png. The problem occurs when using these ...

React Native not refreshing state data

I'm working with a FlatList that contains the code snippet below: <FlatList ........... refreshing={this.state.refresh} onRefresh={() => { this.setState({ ...

The design I created includes a horizontal scroll feature and certain elements are not properly aligned in the

Oh man, I'm really frustrated right now. I want all my elements to be centered horizontally on smaller devices, but some of them are slightly off to the side. And to top it off, there's a horizontal scroll appearing - it's like something is ...

What is the best way to target and style anchor links in CSS that are not empty?

Hi there! I am on the hunt for a CSS selector that will target all anchor links that are not empty and contain content. I currently have a selector to identify all links with an anchor attribute, like in this example: a[href*=\#] { background-co ...

Aligning Font Awesome icons inside md-buttonsFinding the perfect alignment for

I am attempting to center font awesome icons within a button so that they align perfectly with the text on a toolbar. Below is the code snippet I am working with: <div ng-app="app"> <md-toolbar> <div class="md-toolbar-tools" md-tall ...

What is the best way to transform React API data into props that can be utilized in different components?

I've been struggling with this issue for quite some time now, unable to understand how to manipulate the data in a way that allows me to use it in other components. Although I can display the data correctly, I'm advised to structure it within a f ...

Why does the useEffect() from before continue to run for a long period after the component has already been rendered?

At the moment, my ReactJs code looks like this as I work on implementing a stopwatch: const App: React.FC = () => { const [seconds, setSeconds] = useState(0); const [isPaused, setIsPaused] = useState(false); const secondsToTimerFormat = (seconds: ...

Leveraging environment variables within the create-react-app package.json for proxy configuration

I am currently working on a create-react-app project and I need to set the "proxy" property in the package.json file to the value of an environment variable called "REACT_APP_API_BASE_URL". This variable is stored in the .env.development.local file. Despit ...

Loss of styling is observed with jQuery's html() function

Here is the HTML code I am working with: <div class="myList"> <select> <option value="1">Item1</option> <option value="2">Item2</option> </select> </div> Everything looks great in terms of CS ...

Unable to successfully delete a row from MySQL DB using the API call

I am attempting to make an API call from the backend to perform a DELETE query on my MySQL database. However, when I execute it in the browser, I receive an error saying 'Cannot GET ...' I am passing the ID of the row retrieved from the database ...

The stickiness of elements causes scrollbars to disappear in Chrome 77 on OSX

In this scenario, I have set up two tables where the first one has a sticky header achieved with position: sticky; top: 0px; https://codepen.io/seunje/pen/JjjRVLm The sticky header works perfectly fine, but there is an issue with scrollbars disappea ...