简体   繁体   中英

Is it possible to customize radio button with react and styled-component?

I am trying to make a radio button using the radio type of the <input> . Instead of label, components are bundled together, and instead of using packages such as MUI , I try to use the <input> tag directly.

The functions I want are:

  1. A circle exists inside regardless of whether it is checked or not. Instead, it is displayed in gray when it is unchecked and blue when it is checked.

在此处输入图像描述

  1. I can change the color of the radio button. However, when checked, the color of the border of the outer circle does not change (the default behavior is that the color of both the outer circle and the inner circle changes).

I succeeded change the color using the accent-color property. However, the color of both the outer circle and the inner circle changes together. Is there a way to satisfy all of the above functions using <input type="radio"..> ?

There's no way (as far as I know) to reliably exert full control over the appearance of the input itself.

However, there is a common trick to overcome this limitation: hide the actual input and render a pseudo-element in its place, as in the example below.

I've wrapped the inputs in a <label> here so that clicks still trigger the native inputs to check/uncheck.

Note that because inputs may be replaced elements it's possible that input::after won't work in every browser . If it's a problem you could use an actual span (or whatever) instead.

Also: I haven't needed to solve this problem in a long time, so my method may be outdated. There are several articles and demos to be found that may give you other solutions or better ideas.

 .radio { --size: 30px; --padding: calc(var(--size) + 1em); position: relative; margin: .25em; min-height: var(--size); padding-left: var(--padding); cursor: pointer; }.radio input { visibility: hidden; position: absolute; } input[type=radio]::after { --color-border: lightgray; --color-dot: var(--color-border); content: ''; visibility: visible; position: absolute; top: 50%; transform: translateY(-50%); left: calc(var(--padding) * -1); width: var(--size); height: var(--size); border-radius: 50%; color: lightgray; background: radial-gradient(var(--color-dot) 0%, var(--color-dot) 40%, white 40%); box-shadow: 0 0 0 2px var(--color-border); pointer-events: none; } input[type=radio]:checked::after { --color-dot: blue; }
 <label class="radio"> <input type="radio" name="demo" value="1" checked /> One </label> <label class="radio"> <input type="radio" name="demo" value="2" /> Two </label> <label class="radio"> <input type="radio" name="demo" value="3" /> Three </label>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM