Я пытаюсь создать блок с гладким изогнутым вырезом в правом верхнем углу, как показано на рисунке ниже:
На данный момент моя реализация выглядит так:
Как видите, текущая кривая не такая плавная, как хотелось бы — по сути, это не кривая, а квадрат с прямыми углами. Вот мой текущий код:
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
font-family: Arial, sans-serif;
}
.curved-block {
width: 300px;
background-color: white;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
position: relative;
overflow: hidden;
padding: 5px;
}
.curved-block::after {
content: '';
position: absolute;
top: 0;
right: 0;
width: 40px;
height: 40px;
background-color: #f0f0f0;
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cpath d='M0 0 h25 c5 0, 10 0, 13 3 s2 7, 2 12 v25 h-40 z' fill='%23000000'/%3E%3C/svg%3E");
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cpath d='M0 0 h25 c5 0, 10 0, 13 3 s2 7, 2 12 v25 h-40 z' fill='%23000000'/%3E%3C/svg%3E");
mask-size: cover;
-webkit-mask-size: cover;
}
.icon {
position: absolute;
top: 8px;
right: 8px;
width: 23px;
height: 23px;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
font-weight: bold;
background-color: #0056b3;
border-radius: 50%;
color: white;
z-index: 2;
}
<div class = "curved-block">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<span class = "icon">+</span>
</div>
Я изо всех сил пытаюсь добиться более плавной и естественной кривой в маске SVG. Как я могу изменить путь SVG, чтобы создать кривую, которая больше похожа на кривую на желаемом результирующем изображении? Заранее благодарим вас за ваши предложения.
Я сделал это здесь: https://css-shape.com/inverted-radius/
Вы можете легко скопировать код и настроить переменные:
.inverted-radius {
--r: 15px; /* the radius */
--s: 30px; /* the size of the corner*/
height: 150px;
margin: 10px;
background: #3FB8AF;
border-radius: var(--r);
--_m:/calc(2*var(--r)) calc(2*var(--r))
radial-gradient(#000 70%,#0000 72%) no-repeat;
mask:
right calc(var(--s) + var(--r)) top var(--_m),
right calc(var(--s) + var(--r)) var(--_m),
radial-gradient(var(--s) at 100% 0,#0000 99%,#000 101%)
calc(-1*var(--r)) var(--r) no-repeat,
conic-gradient(at calc(100% - var(--s) - 2*var(--r)) calc(var(--s) + 2*var(--r)),
#0000 25%,#000 0);
}
<div class = "inverted-radius"></div>
Поскольку вы используете равномерно закругленные углы, вы также можете комбинировать CSS clip-path
с фильтром «слизь» SVG.
body {
font-family: Arial, sans-serif;
margin: 0;
background-color: #f0f0f0;
padding: 3em;
}
:root{
--icon-space: 2em;
--drop-shadow: drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.75))
}
.curved-block-outer {
position: relative;
}
.curved-block {
background-color: #fff;
padding: 0.5em 2.5em 0.5em 0.5em;
clip-path: polygon( 0% 0%, calc(100% - var(--icon-space)) 0%, calc(100% - var(--icon-space)) var(--icon-space), 100% var(--icon-space), 100% 100%, 0% 100%);
}
/* round corners via SVG filter; add drop shadow */
.curved-block-filter {
filter: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='goo'><feGaussianBlur in='SourceGraphic' stdDeviation='7.5' result='blur'/><feColorMatrix in='blur' mode='matrix' values='1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9' result='goo'/><feComposite in='SourceGraphic' in2='goo' operator='atop'/></filter></svg>#goo") var(--drop-shadow);
}
.icon {
position: absolute;
right: 0;
top: 0;
z-index: 10;
width: 1.5em;
height: 1.5em;
display: block;
text-align: center;
font-size: 1em;
line-height: 1.6em;
font-weight: bold;
background-color: #0056b3;
border-radius: 50%;
color: #fff;
filter: var(--drop-shadow);
}
<div class = "curved-block-outer ">
<span class = "icon">+</span>
<div class = "curved-block-filter">
<div class = "curved-block">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
</div>
Мы в основном
К сожалению, нам нужны некоторые дополнительные элементы-обертки, иначе мы не сможем применить тень, или кнопка «плюс» также будет затронута фильтрами.
Вы можете сослаться на фильтр, встроив SVG в свой HTML.
<svg class = "flt_svg">
<filter id = "goo">
<feGaussianBlur in = "SourceGraphic" stdDeviation = "7.5" result = "blur" />
<feColorMatrix in = "blur" mode = "matrix" values = "1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result = "goo" />
<feComposite in = "SourceGraphic" in2 = "goo" operator = "atop" />
</filter>
</svg>
и примените его в CSS следующим образом:
filter: url("#goo")
или вы можете закодировать SVG в dataURL и встроить его непосредственно в CSS.
filter: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='goo'><feGaussianBlur in='SourceGraphic' stdDeviation='7.5' result='blur'/><feColorMatrix in='blur' mode='matrix' values='1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9' result='goo'/><feComposite in='SourceGraphic' in2='goo' operator='atop'/></filter></svg>#goo")
Значение stdDeviation='7.5'
указывает радиус границы/закругления.
См. также
Спасибо, отличный ответ и очень познавательно. Спасибо за статьи и пояснения, в будущем смогу проделывать подобные трюки.