如何创建响应三角形作为右边框?
How to create responsive triangle as right border?
我正在尝试为一个边框制作一个响应式三角形,该三角形仅在 hover
上可见。我尝试了下面的代码,但它不起作用,因为它使用静态 border-width
。当我有一个字符串(单行)时link它是完美的,但是当字符串更多(超过一行)时,它失败了。
代码在这里:
<ul>
<li><a href="#">Lorem ipsum</a></li>
<li><a href="#">Lorem ipsum</a></li>
<li><a href="#">Lorem ipsum dolor sit amet</a></li>
</ul>
SCSS 在这里:
ul{
width:120px;
li{
list-style-type: none;
a{
position:relative;
display:block;
padding:10px;
color:#00f;
text-decoration: none;
&:hover{
color:#fff;
background:#00f;
&:after{
content:'';
position: absolute;
top: 0;
right: -5px;
height: 0;
border-style: solid;
border-width: 19px 0 19px 11px;
border-color: #fff #fff #fff #00f;
}
}
}
}
}
最后一个 link 失败。使用图像或图片不是解决问题的方法。
您有静态宽度的边框:
border-width: 19px 0 19px 11px;
但元素的高度会根据行数或文本大小而变化,
所以如果你更新到
border-width: 30px 0 30px 11px;
它可以解决 2 行文本的问题,但不能解决 1 行文本的问题。
您将必须检查元素的 JS 高度并根据它更新 :
border-width: 'dinamic result from JS'px 0 'dinamic result from JS'px 11px;
您不能在此处使用 border
三角形方法创建三角形,因为元素的 height
是动态的。相反,您可以使用以下任何替代方法:
内联 SVG + 剪辑路径: 推荐
您可以使用内联 SVG 和 clip-path
来制作具有三角形效果的栏。 clip-path
仅在悬停在 a
标签上时应用,因此正常状态不受影响。 browser support 比 CSS 等价物好得多。
ul {
width: 120px;
}
li {
list-style-type: none;
}
a {
position: relative;
display: block;
padding: 10px;
color: #00f;
text-decoration: none;
}
a:hover {
-webkit-clip-path: url(#clip-shape);
-moz-clip-path: url(#clip-shape);
clip-path: url(#clip-shape);
background: crimson;
}
<svg width="0" height="0">
<defs>
<clipPath id="clip-shape" clipPathUnits="objectBoundingBox">
<polygon points="0,0 0.8,0 1,0.5 0.8,1 0,1" />
</clipPath>
</defs>
</svg>
<ul>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum dolor sit amet</a>
</li>
</ul>
变换:
您可以在伪元素上使用 transform: rotate(45deg)
来生成三角形,然后将其放置在 a
的末尾以生成形状。 parent 有一个 overflow: hidden
设置来切掉不需要显示的三角形部分。
ul {
width: 120px;
}
li {
list-style-type: none;
}
a {
position: relative;
display: inline-block;
color: blue;
text-decoration: none;
padding: 5px 25px 5px 5px;
overflow: hidden;
}
a:after {
content: '';
position: absolute;
top: 50%;
right: 0%;
height: 100%;
width: 100%;
background-color: inherit;
transform-origin: 100% 0;
transform: rotate(45deg);
z-index: -1;
}
a:before {
position: absolute;
content: '';
top: 0px;
left: 0px;
height: 100%;
width: calc(100% - 25px);
background-color: inherit;
z-index: -1;
}
a:hover {
background: crimson;
background-clip: content-box;
color: beige;
}
<!-- Library included just to avoid prefixes so that users with older browser can view -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<ul>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum dolor sit amet</a>
</li>
</ul>
或者,您可以使用两个应用了 transform: skew(45deg)
的伪元素(在相反的方向)来获得三角形。这里的父项也有 overflow: hidden
设置。
ul {
width: 120px;
}
li {
list-style-type: none;
margin-bottom: 10px;
}
a {
position: relative;
display: block;
padding: 10px;
color: #00f;
text-decoration: none;
overflow: hidden;
}
a:before,
a:after {
position: absolute;
content: '';
height: 50%;
width: 100%;
left: -15%;
z-index: -1;
}
a:before {
top: 0px;
transform: skew(45deg);
}
a:after {
bottom: 0px;
transform: skew(-45deg);
}
a:hover:after,
a:hover:before {
background: crimson;
}
a:hover{
color: beige;
}
<!-- Library included just to avoid prefixes so that users with older browser can view -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<ul>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum dolor sit amet</a>
</li>
</ul>
这些可能是最接近纯粹的 CSS 解决方案,具有良好的浏览器支持。但是,当高度进一步增加时,他们仍然需要对 padding-right
(对于 rotate
方法)和 left
(对于 skew
方法)等属性进行一些调整,因此不会推荐。
CSS 剪辑路径:
您可以利用多边形 clip-path
在 hover
上创建具有三角形效果的条形。这里的缺点是浏览器对 CSS clip-path 的支持很差。
ul {
width: 120px;
}
li {
list-style-type: none;
}
a {
position: relative;
display: block;
padding: 10px;
color: #00f;
text-decoration: none;
}
a:hover {
-webkit-clip-path: polygon(0% 0%, 80% 0%, 100% 50%, 80% 100%, 0% 100%);
background: crimson;
}
<ul>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum dolor sit amet</a>
</li>
</ul>
线性渐变:
您也可以使用 linear-gradient
和伪元素组合,如下面的代码片段所示,但已知渐变会产生锯齿状边缘,因此 不推荐使用 。
ul {
width: 120px;
}
li {
list-style-type: none;
}
a {
position: relative;
display: block;
padding: 10px;
color: #00f;
text-decoration: none;
}
a:after {
content: '';
display: none;
position: absolute;
right: -25px;
top: 0px;
width: 50px;
height: 100%;
background: linear-gradient(to top left, rgba(0, 0, 0, 0) 50%, crimson 50%), linear-gradient(to top right, crimson 50%, rgba(0, 0, 0, 0) 50%);
background-size: 50% 50%;
background-repeat: no-repeat;
background-position: 100% 100%, 100% 0%;
z-index: -1;
}
a:hover {
background: crimson;
}
a:hover:after {
display: block;
}
<!-- Library included just to avoid prefixes so that users with older browser can view -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<ul>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum dolor sit amet</a>
</li>
</ul>
我正在尝试为一个边框制作一个响应式三角形,该三角形仅在 hover
上可见。我尝试了下面的代码,但它不起作用,因为它使用静态 border-width
。当我有一个字符串(单行)时link它是完美的,但是当字符串更多(超过一行)时,它失败了。
代码在这里:
<ul>
<li><a href="#">Lorem ipsum</a></li>
<li><a href="#">Lorem ipsum</a></li>
<li><a href="#">Lorem ipsum dolor sit amet</a></li>
</ul>
SCSS 在这里:
ul{
width:120px;
li{
list-style-type: none;
a{
position:relative;
display:block;
padding:10px;
color:#00f;
text-decoration: none;
&:hover{
color:#fff;
background:#00f;
&:after{
content:'';
position: absolute;
top: 0;
right: -5px;
height: 0;
border-style: solid;
border-width: 19px 0 19px 11px;
border-color: #fff #fff #fff #00f;
}
}
}
}
}
最后一个 link 失败。使用图像或图片不是解决问题的方法。
您有静态宽度的边框:
border-width: 19px 0 19px 11px;
但元素的高度会根据行数或文本大小而变化, 所以如果你更新到
border-width: 30px 0 30px 11px;
它可以解决 2 行文本的问题,但不能解决 1 行文本的问题。 您将必须检查元素的 JS 高度并根据它更新 :
border-width: 'dinamic result from JS'px 0 'dinamic result from JS'px 11px;
您不能在此处使用 border
三角形方法创建三角形,因为元素的 height
是动态的。相反,您可以使用以下任何替代方法:
内联 SVG + 剪辑路径: 推荐
您可以使用内联 SVG 和 clip-path
来制作具有三角形效果的栏。 clip-path
仅在悬停在 a
标签上时应用,因此正常状态不受影响。 browser support 比 CSS 等价物好得多。
ul {
width: 120px;
}
li {
list-style-type: none;
}
a {
position: relative;
display: block;
padding: 10px;
color: #00f;
text-decoration: none;
}
a:hover {
-webkit-clip-path: url(#clip-shape);
-moz-clip-path: url(#clip-shape);
clip-path: url(#clip-shape);
background: crimson;
}
<svg width="0" height="0">
<defs>
<clipPath id="clip-shape" clipPathUnits="objectBoundingBox">
<polygon points="0,0 0.8,0 1,0.5 0.8,1 0,1" />
</clipPath>
</defs>
</svg>
<ul>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum dolor sit amet</a>
</li>
</ul>
变换:
您可以在伪元素上使用 transform: rotate(45deg)
来生成三角形,然后将其放置在 a
的末尾以生成形状。 parent 有一个 overflow: hidden
设置来切掉不需要显示的三角形部分。
ul {
width: 120px;
}
li {
list-style-type: none;
}
a {
position: relative;
display: inline-block;
color: blue;
text-decoration: none;
padding: 5px 25px 5px 5px;
overflow: hidden;
}
a:after {
content: '';
position: absolute;
top: 50%;
right: 0%;
height: 100%;
width: 100%;
background-color: inherit;
transform-origin: 100% 0;
transform: rotate(45deg);
z-index: -1;
}
a:before {
position: absolute;
content: '';
top: 0px;
left: 0px;
height: 100%;
width: calc(100% - 25px);
background-color: inherit;
z-index: -1;
}
a:hover {
background: crimson;
background-clip: content-box;
color: beige;
}
<!-- Library included just to avoid prefixes so that users with older browser can view -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<ul>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum dolor sit amet</a>
</li>
</ul>
或者,您可以使用两个应用了 transform: skew(45deg)
的伪元素(在相反的方向)来获得三角形。这里的父项也有 overflow: hidden
设置。
ul {
width: 120px;
}
li {
list-style-type: none;
margin-bottom: 10px;
}
a {
position: relative;
display: block;
padding: 10px;
color: #00f;
text-decoration: none;
overflow: hidden;
}
a:before,
a:after {
position: absolute;
content: '';
height: 50%;
width: 100%;
left: -15%;
z-index: -1;
}
a:before {
top: 0px;
transform: skew(45deg);
}
a:after {
bottom: 0px;
transform: skew(-45deg);
}
a:hover:after,
a:hover:before {
background: crimson;
}
a:hover{
color: beige;
}
<!-- Library included just to avoid prefixes so that users with older browser can view -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<ul>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum dolor sit amet</a>
</li>
</ul>
这些可能是最接近纯粹的 CSS 解决方案,具有良好的浏览器支持。但是,当高度进一步增加时,他们仍然需要对 padding-right
(对于 rotate
方法)和 left
(对于 skew
方法)等属性进行一些调整,因此不会推荐。
CSS 剪辑路径:
您可以利用多边形 clip-path
在 hover
上创建具有三角形效果的条形。这里的缺点是浏览器对 CSS clip-path 的支持很差。
ul {
width: 120px;
}
li {
list-style-type: none;
}
a {
position: relative;
display: block;
padding: 10px;
color: #00f;
text-decoration: none;
}
a:hover {
-webkit-clip-path: polygon(0% 0%, 80% 0%, 100% 50%, 80% 100%, 0% 100%);
background: crimson;
}
<ul>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum dolor sit amet</a>
</li>
</ul>
线性渐变:
您也可以使用 linear-gradient
和伪元素组合,如下面的代码片段所示,但已知渐变会产生锯齿状边缘,因此 不推荐使用 。
ul {
width: 120px;
}
li {
list-style-type: none;
}
a {
position: relative;
display: block;
padding: 10px;
color: #00f;
text-decoration: none;
}
a:after {
content: '';
display: none;
position: absolute;
right: -25px;
top: 0px;
width: 50px;
height: 100%;
background: linear-gradient(to top left, rgba(0, 0, 0, 0) 50%, crimson 50%), linear-gradient(to top right, crimson 50%, rgba(0, 0, 0, 0) 50%);
background-size: 50% 50%;
background-repeat: no-repeat;
background-position: 100% 100%, 100% 0%;
z-index: -1;
}
a:hover {
background: crimson;
}
a:hover:after {
display: block;
}
<!-- Library included just to avoid prefixes so that users with older browser can view -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<ul>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum</a>
</li>
<li><a href="#">Lorem ipsum dolor sit amet</a>
</li>
</ul>