如何创建响应三角形作为右边框?

Posted

技术标签:

【中文标题】如何创建响应三角形作为右边框?【英文标题】:How to create responsive triangle as right border? 【发布时间】:2015-09-10 12:37:19 【问题描述】:

我正在尝试为一个边框制作一个响应式三角形,该边框仅在hover 上可见。我尝试了下面的代码,但它不起作用,因为它使用静态border-width。当我有一个字符串(单行)链接时,它是完美的,但是当字符串更多(多于一行)时,它就失败了。

Example here

代码在这里:

<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;
        
      
    
  

最后一个链接失败。使用图像或图片不能解决问题。

【问题讨论】:

Responsive CSS triangle with percents width的可能重复 虽然上面链接的线程非常接近这个线程,但这里不能采用相同的方法,因为三角形大小与父元素的width 成正比(因此百分比padding可以用来保持纵横比),而这里它必须与父元素的height 成比例(百分比padding 总是相对于width 计算)。 【参考方案1】:

您不能使用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  >
  <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 的末尾以生成形状。父级有一个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-pathhover 上创建具有三角形效果的条形图。这里的缺点是浏览器对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 和伪元素组合,如下面的 sn-p,但已知渐变会产生锯齿状边缘,并且不推荐

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>

【讨论】:

【参考方案2】:

你有静态宽度的边框:

border-width: 19px 0 19px 11px;

但元素的高度会根据行数或文本大小而变化, 所以如果你更新到

border-width: 30px 0 30px 11px;

它可以解决 2 行文本的问题,但不适用于 1 行文本。 您必须检查元素的 JS heigt 并根据它更新:

border-width: 'dinamic result from JS'px 0 'dinamic result from JS'px  11px;

【讨论】:

以上是关于如何创建响应三角形作为右边框?的主要内容,如果未能解决你的问题,请参考以下文章

请问html怎么把文本框做成下拉框,或下拉框去掉右边的倒三角

带有边框的响应三角形到容器的高度和宽度[重复]

使用 CSS 创建响应式三角形

设置Android Spinner下拉框三角标位置靠右居中

具有悬停效果的响应三角形

三角形宽高设置