使用CSS创建具有动态高度和向内箭头的div

3
我使用 CSS 伪元素创建了下面的箭头 div。对于固定高度,它可以正常工作,但当我将其高度设置为自动并增加文本时,它变成了这样。现在有办法让箭头随着文本增加而增加高度吗?
我们可以使用 jQuery 来实现这一点,但是在 CSS 中是否有可能仅通过 CSS 实现?
带箭头的 div 在右侧
.label-box-st1::after {
  border-bottom: 73px solid #800080;
  border-right: 45px solid rgba(0, 0, 0, 0);
  border-top: 73px solid #800080;
  content: "";
  position: absolute;
  right: -43px;
  top: 0;
  width: 20px;
}
2个回答

7

使用线性渐变:

您可以像下面的代码片段一样使用一对倾斜的线性渐变来实现。如您从代码片段中所见,它可以适应任何高度,即使内容换行(或)跨越多行。

形状的创建如下:

  • 一对线性渐变(使用to [side] [side]语法),颜色占近50%,其余50%为透明。这两个渐变在Y轴上都有50%大小(即元素高度的一半),在X轴上有20px大小(意味着三角形有固定的宽度)。
  • 这些线性渐变位于元素的右上角和右下角,以产生三角形效果。
  • 还有一个线性渐变(实际上是纯色的),其Y轴尺寸为父级高度的100%,X轴尺寸比100%20px(使用calc)。这会产生三角形区域以外的彩色区域。

这种方法的优点如下:

  • 不需要任何额外的元素(真实或伪元素),因此标记中没有不必要的杂乱内容,伪元素可以用于其他事情。
  • 如最后一个div所示,即使divwidth改变,它也会自适应。
  • 右侧的三角形切口是透明的,因此如果需要,还可以看到页面的背景。

这种方法唯一的两个缺点如下:

  • 与伪元素相比,渐变具有较低的浏览器支持(仅在IE10+中工作)。
  • 在某些非常宽的角度下,倾斜的边缘会有点锯齿状。

.shape {
  position: relative;
  width: 200px;
  color: white;
  padding: 8px;
  margin: 4px;
  background: linear-gradient(to bottom right, rgb(128, 0, 128) 49%, transparent 51%), linear-gradient(to top right, rgb(128, 0, 128) 49%, transparent 51%), linear-gradient(to right, rgb(128, 0, 128), rgb(128, 0, 128));
  background-size: 20px 50%, 20px 50%, calc(100% - 20px) 100%;
  background-position: 100% 0%, 100% 100%, 0% 0%;
  background-repeat: no-repeat;
}
.shape.wide {
  width: 300px;
}
<div class='shape'>Some div with small content</div>

<div class='shape'>Some div with large content that wraps around into multiple lines</div>

<div class='shape'>Some div with large content that wraps
  <br>around into multiple lines
  <br>even spanning multiple lines</div>

<div class='shape'>Some div with
  <br>large content that wraps
  <br>around into multiple lines
  <br>even spanning
  <br>multiple lines</div>

<div class='shape wide'>Some div with
  <br>large content that wraps
  <br>around into multiple lines
  <br>even spanning
  <br>multiple lines</div>


使用SVG:(推荐的方法,但以下将根据问题要求提供CSS)

同样的形状也可以使用SVG来实现。使用SVG只需要创建一个路径,使用SVG的path元素,并相对于元素绝对定位(同时设置z-index: -1使其在文字后面)。SVG本质上是可扩展的,因此它们可以适应容器的宽度和/或高度的增加。

SVG的优点与基于渐变的方法几乎相似。SVG比渐变方法更好的地方在于浏览器支持更好(应该在IE9+中有效),且锯齿的边缘也不太明显。

.shape {
  position: relative;
  width: 200px;
  color: white;
  padding: 8px;
  margin: 4px;
}
.shape.wide {
  width: 300px;
}
.shape svg {
  position: absolute;
  height: 100%;
  width: 100%;
  top: 0px;
  left: 0px;
  z-index: -1;
}
.shape path {
  fill: rgb(128, 0, 128);
}
<div class='shape'>
  <svg viewBox='0 0 1 1' preserveAspectRatio='none'>
    <path d='M0,0 1,0 0.9,0.5 1,1 0,1z' />
  </svg>
  Some div with small content</div>

<div class='shape'>
  <svg viewBox='0 0 1 1' preserveAspectRatio='none'>
    <path d='M0,0 1,0 0.9,0.5 1,1 0,1z' />
  </svg>  
  Some div with large content that wraps around into multiple lines</div>

<div class='shape'>
  <svg viewBox='0 0 1 1' preserveAspectRatio='none'>
    <path d='M0,0 1,0 0.9,0.5 1,1 0,1z' />
  </svg>  
  Some div with large content that wraps
  <br>around into multiple lines
  <br>even spanning multiple lines</div>

<div class='shape'>
  <svg viewBox='0 0 1 1' preserveAspectRatio='none'>
    <path d='M0,0 1,0 0.9,0.5 1,1 0,1z' />
  </svg>  
  Some div with
  <br>large content that wraps
  <br>around into multiple lines
  <br>even spanning
  <br>multiple lines</div>

<div class='shape wide'>
  <svg viewBox='0 0 1 1' preserveAspectRatio='none'>
    <path d='M0,0 1,0 0.9,0.5 1,1 0,1z' />
  </svg>  
  Some div with
  <br>large content that wraps
  <br>around into multiple lines
  <br>even spanning
  <br>multiple lines</div>

注意: 您可以在这个MDN教程中了解更多关于SVG的path元素及其命令(如MzLA等)。我个人建议您研究SVG,因为它可以用非常少的工作量创建许多复杂的形状 :)


1
除了Harry的答案外,您还可以使用倾斜的伪元素来创建这种形状。

div {
  height: 20vh;
  width: 50%;
  background: #800080;
  position: relative;
  transition: all 0.4s;
  cursor:pointer;
}
div:before,
div:after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 50%;
  background: #800080;
  z-index: -1;
}
div:before {
  top: 0;
  transform: skewX(-45deg);
  transform-origin: bottom left;
}
div:after {
  top: 50%;
  transform: skewX(45deg);
  transform-origin: top left;
}
/*demo only*/

div:hover {
  width: 80%;
  height: 50vh;
}
<div>Hover to see resized element</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接