I am try to make a div have borders like the following drawing:
我试着让一个div有如下的边框:
This is what I have tried:
这就是我所尝试的:
div {
height: 100px;
width: 100px;
border-bottom-right-radius:100px 10px;
border:1px solid #000;
}
<div></div>
What is an effect way to accomplish this?
达到这个目的的有效方法是什么?
3 个解决方案
#1
27
Using :before
and :after
The top border is created with the :before
:
-
Its height is the same as the border radius
它的高度等于边界半径
-
It is positioned just outside with
top
and lines up with the left border thanks toleft
它的位置就在外面,顶部和左边的边界排成一行
-
Its width is calculated with
calc
to precisely line up the top of the curve它的宽度用calc计算,以精确地排列在曲线的顶部
-
The curve can be refined with
transform: skewX(-60deg)
曲线可变换细化:skewX(-60deg)
The left border is created with the :after
:
- It is given a 100% height minus the height of the before and the thickness of the border with
calc
- 它的高度是100%减去之前的高度和边界的厚度
Examples
Number 1 - a bit pointy
div {
border-bottom-right-radius: 100px 20px;
border: 1px solid #000;
border-top: none;
height: 500px;
width: 200px;
position: relative;
border-left: none;
}
div:before,
div:after {
content: '';
display: block;
position: absolute;
left: -1px;
}
div:before {
height: 20px;
width: 100%;
width: calc(100% + 1px);
border-bottom-right-radius: 100px 20px;
border-bottom: 1px solid #000;
border-right: solid 1px #000;
top: -1px;
}
div:after {
height: calc(100% - 18px);
border-left: 1px solid #000;
top: 19px;
}
<div></div>
Number 2 - smoothed out point with skew
div {
border-bottom-right-radius: 100px 20px;
border: 1px solid #000;
border-top: none;
height: 200px;
width: 200px;
position: relative;
border-left: none;
}
div:before,
div:after {
content: '';
display: block;
position: absolute;
left: -1px;
}
div:before {
height: 20px;
width: 100%;
width: calc(100% - 36px);
border-bottom-right-radius: 100px 20px;
border-bottom: 1px solid #000;
border-right: solid 2px #000;
top: 0px;
left: 17px;
transform: skewX(-60deg);
}
div:after {
height: calc(100% - 19px);
border-left: 1px solid #000;
top: 20px;
}
<div></div>
#2
7
I could do it using DIVs, but I am pretty sure that exists a more elegant way to do it:
我可以用DIVs来做,但是我很确定这是一种更优雅的方法:
#container {
border:none;
height:100px;
border-right: solid 1px #000;
}
#square_top {
border-bottom-right-radius:100px 10px;
border:none;
border-bottom: solid 1px #000;
height:10px;
}
#square_bottom {
border-bottom-right-radius:100px 10px;
border:none;
border-bottom: solid 1px #000;
border-right:solid 1px #000;
border-left:solid 1px #000;
height:10px;
}
#square {
height: 90px;
border-left:solid 1px #000;
}
<div id="container">
<div id="square_top"></div>
<div id="square">TEXT HERE</div>
</div>
<div id="square_bottom"></div>
#3
4
Although CSS can do this, there is another approach that allows more flexibility : SVG
虽然CSS可以做到这一点,但是还有另一种方法可以提供更大的灵活性:SVG
This approach allows :
这种方法允许:
- The shape addapts its size to the size of the content
- 形状根据内容的大小增加大小
- Responsive
- 响应
- Allows any kind of background (image, gradients, semitransparent color...)
- 允许任何类型的背景(图像、渐变、半透明颜色…)
- Allows any kind of filling for the shape (image, gradients, semitransparent color...)
- 允许任何形状的填充(图像,梯度,半透明的颜色…)
- easier to control the the top and bottom curves :
- 容易控制上下曲线:
body {background: url('http://lorempixel.com/output/people-q-g-640-480-9.jpg');background-size: cover;}
div {
position: relative;
width: 30%;
padding: 5%;
color: #fff;
text-align: center;
}
svg {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
z-index: -1;
}
<div>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<svg viewbox="0 0 50 100" preserveAspectRatio="none">
<path d="M1 9 C49 10 49 1 49 1 V90 C49 91 49 99 1 99z" stroke-width="0.5" stroke="#000" fill-opacity="0.5" />
</svg>
</div>
#1
27
Using :before
and :after
The top border is created with the :before
:
-
Its height is the same as the border radius
它的高度等于边界半径
-
It is positioned just outside with
top
and lines up with the left border thanks toleft
它的位置就在外面,顶部和左边的边界排成一行
-
Its width is calculated with
calc
to precisely line up the top of the curve它的宽度用calc计算,以精确地排列在曲线的顶部
-
The curve can be refined with
transform: skewX(-60deg)
曲线可变换细化:skewX(-60deg)
The left border is created with the :after
:
- It is given a 100% height minus the height of the before and the thickness of the border with
calc
- 它的高度是100%减去之前的高度和边界的厚度
Examples
Number 1 - a bit pointy
div {
border-bottom-right-radius: 100px 20px;
border: 1px solid #000;
border-top: none;
height: 500px;
width: 200px;
position: relative;
border-left: none;
}
div:before,
div:after {
content: '';
display: block;
position: absolute;
left: -1px;
}
div:before {
height: 20px;
width: 100%;
width: calc(100% + 1px);
border-bottom-right-radius: 100px 20px;
border-bottom: 1px solid #000;
border-right: solid 1px #000;
top: -1px;
}
div:after {
height: calc(100% - 18px);
border-left: 1px solid #000;
top: 19px;
}
<div></div>
Number 2 - smoothed out point with skew
div {
border-bottom-right-radius: 100px 20px;
border: 1px solid #000;
border-top: none;
height: 200px;
width: 200px;
position: relative;
border-left: none;
}
div:before,
div:after {
content: '';
display: block;
position: absolute;
left: -1px;
}
div:before {
height: 20px;
width: 100%;
width: calc(100% - 36px);
border-bottom-right-radius: 100px 20px;
border-bottom: 1px solid #000;
border-right: solid 2px #000;
top: 0px;
left: 17px;
transform: skewX(-60deg);
}
div:after {
height: calc(100% - 19px);
border-left: 1px solid #000;
top: 20px;
}
<div></div>
#2
7
I could do it using DIVs, but I am pretty sure that exists a more elegant way to do it:
我可以用DIVs来做,但是我很确定这是一种更优雅的方法:
#container {
border:none;
height:100px;
border-right: solid 1px #000;
}
#square_top {
border-bottom-right-radius:100px 10px;
border:none;
border-bottom: solid 1px #000;
height:10px;
}
#square_bottom {
border-bottom-right-radius:100px 10px;
border:none;
border-bottom: solid 1px #000;
border-right:solid 1px #000;
border-left:solid 1px #000;
height:10px;
}
#square {
height: 90px;
border-left:solid 1px #000;
}
<div id="container">
<div id="square_top"></div>
<div id="square">TEXT HERE</div>
</div>
<div id="square_bottom"></div>
#3
4
Although CSS can do this, there is another approach that allows more flexibility : SVG
虽然CSS可以做到这一点,但是还有另一种方法可以提供更大的灵活性:SVG
This approach allows :
这种方法允许:
- The shape addapts its size to the size of the content
- 形状根据内容的大小增加大小
- Responsive
- 响应
- Allows any kind of background (image, gradients, semitransparent color...)
- 允许任何类型的背景(图像、渐变、半透明颜色…)
- Allows any kind of filling for the shape (image, gradients, semitransparent color...)
- 允许任何形状的填充(图像,梯度,半透明的颜色…)
- easier to control the the top and bottom curves :
- 容易控制上下曲线:
body {background: url('http://lorempixel.com/output/people-q-g-640-480-9.jpg');background-size: cover;}
div {
position: relative;
width: 30%;
padding: 5%;
color: #fff;
text-align: center;
}
svg {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
z-index: -1;
}
<div>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<p>Some text</p>
<svg viewbox="0 0 50 100" preserveAspectRatio="none">
<path d="M1 9 C49 10 49 1 49 1 V90 C49 91 49 99 1 99z" stroke-width="0.5" stroke="#000" fill-opacity="0.5" />
</svg>
</div>