Как сделать box-shadow прозрачным?
Делаю а-ля radio кнопок и появилась маленькая проблема. Для активного цвета box-shadow нужно сделать так, чтобы цвет подстраивался в зависимости от заднего фона, можно ли это сделать прямым css без добавление новых элементов? Некоторые могут сейчас написать, сделай переменную для фона и просто подставляй. Ок! Допустим сделаю, а что если я захочу использовать такие же кнопки на другом фоне, постоянно мне менять? Бред!
body {
background-color: #fff;
}
.list {
display: flex;
gap: 15px;
}
.color {
width: 25px;
height: 25px;
border-radius: 100%;
background-color: red;
cursor: pointer;
}
.color.checked {
box-shadow: inset 0 0 0 2px #fff;
border: 2px solid red;
}
<div class="list">
<div class="color"></div>
<div class="color"></div>
<div class="color checked"></div>
<div class="color"></div>
</div>
Ответы (2 шт):
Вырезать дырку в элементе можно через clip-path, но рисовать кольцо довольно сложно.
А вот если колечко сделать отдельным элементом, то получается дырка засчёт inset.
body {
background-color: #fff;
}
.list {
display: flex;
gap: 15px;
background-image: linear-gradient(0deg, #000, #fff);
}
.color {
width: 25px;
height: 25px;
border-radius: 100%;
background-color: red;
cursor: pointer;
}
.color.checked {
position: relative;
margin: 4px;
width: 17px;
height: 17px;
}
.checked::after {
content: "";
position: absolute;
inset: -4px;
background: transparent;
border: 2px solid red;
border-radius: inherit;
}
<div class="list">
<div class="color"></div>
<div class="color"></div>
<div class="color checked"></div>
<div class="color"></div>
</div>
Я бы использовал для этого background-image
, а точнее radial-gradient
.
.custom-radio input[type="radio"] {
display: none;
}
.custom-radio-check {
--custom-radio-size: 25px;
--custom-radio-color: red;
--custom-radio-stroke-width: 2px;
--custom-radio-stroke-offset: 2px;
--custom-radio-stroke-color: red;
display: inline-block;
width: calc(var(--custom-radio-size) + (var(--custom-radio-stroke-width) + var(--custom-radio-stroke-offset)) * 2);
height: calc(var(--custom-radio-size) + (var(--custom-radio-stroke-width) + var(--custom-radio-stroke-offset)) * 2);
background-image:
radial-gradient(circle, var(--custom-radio-color) calc(69% - .5px), transparent calc(69% + .5px)),
radial-gradient(circle,
transparent calc(69% - var(--custom-radio-stroke-width) - .5px),
var(--custom-radio-stroke-color) calc(69% - var(--custom-radio-stroke-width) + .5px),
var(--custom-radio-stroke-color) calc(69% - .5px),
transparent calc(69% + .5px)
);
background-repeat: no-repeat;
background-position: center center;
background-size: var(--custom-radio-size) var(--custom-radio-size);
transition: background-size .3s ease;
cursor: pointer;
}
.custom-radio input[type="radio"]:checked ~ .custom-radio-check {
background-size:
var(--custom-radio-size) var(--custom-radio-size),
100% 100%;
}
<label class="custom-radio">
<input type="radio" name="test[]" />
<div class="custom-radio-check"></div>
</label>
<label class="custom-radio">
<input type="radio" name="test[]" />
<div class="custom-radio-check"></div>
</label>
<label class="custom-radio">
<input type="radio" name="test[]" checked />
<div class="custom-radio-check"></div>
</label>
<label class="custom-radio">
<input type="radio" name="test[]" />
<div class="custom-radio-check"></div>
</label>
Или же сделать дополнительно псевдоэлемент, который будет больше родителя (на величину отступа) и будет иметь бордер.
.custom-radio:not(:last-child) {
margin-right: 1ch;
}
.custom-radio input[type="radio"] {
display: none;
}
.custom-radio-check {
--custom-radio-size: 24px;
--custom-radio-color: red;
--custom-radio-stroke-width: 2px;
--custom-radio-stroke-offset: 2px;
--custom-radio-stroke-color: red;
display: inline-block;
width: var(--custom-radio-size);
height: var(--custom-radio-size);
background-color: var(--custom-radio-color);
border-radius: 50%;
position: relative;
cursor: pointer;
}
.custom-radio-check::before {
content: '';
display: block;
width: calc(var(--custom-radio-size) + var(--custom-radio-stroke-offset) * 2);
height: calc(var(--custom-radio-size) + var(--custom-radio-stroke-offset) * 2);
border: var(--custom-radio-stroke-color) solid var(--custom-radio-stroke-width);
border-radius: inherit;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
opacity: 0;
transition: opacity .3s ease;
}
.custom-radio input[type="radio"]:checked ~ .custom-radio-check::before {
opacity: 1;
}
<label class="custom-radio">
<input type="radio" name="test[]" />
<div class="custom-radio-check"></div>
</label>
<label class="custom-radio">
<input type="radio" name="test[]" />
<div class="custom-radio-check"></div>
</label>
<label class="custom-radio">
<input type="radio" name="test[]" checked />
<div class="custom-radio-check"></div>
</label>
<label class="custom-radio">
<input type="radio" name="test[]" />
<div class="custom-radio-check"></div>
</label>