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

时间:2016-03-22 11:40:36

标签: html css css3 css-shapes linear-gradients

我用CSS伪元素创建了下面的箭头div。它对于固定高度工作正常但是当我将其高度设置为自动并增加文本时,它就像这样。现在是设置箭头以增加其与文本的高度。

我们可以通过使用jQuery来实现这一点,但是只能在CSS中实现吗?

Div with arrow on right

.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 个答案:

答案 0 :(得分:7)

使用线性渐变:

您可以使用几个有角度的线性渐变来完成,如下面的代码段所示。正如您从代码片段中看到的那样,它可以适应任何高度,即使内容环绕(或),如果它跨越多行。

形状创建如下:

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

这种方法的优点如下:

  • 它不需要任何额外的元素(真实的或伪的),因此标记中没有不必要的混乱,伪元素可以用于其他事物。
  • 从上一个div可以看出,即使width的{​​{1}}发生变化,它也会自行调整。
  • 右侧的三角形切口是透明的,因此如果需要,也可以通过切割看到页面的背景。

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

  • 与伪元素(仅适用于IE10 +)和
  • 相比,渐变具有较低的浏览器支持
  • 在一些非常宽的角度,有角度的两侧会有点锯齿状。



div

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




使用SVG:(推荐方法,但在下面添加,因为CSS要求提问)

使用SVG也可以实现相同的形状。使用SVG我们需要做的就是使用SVG的<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>元素创建一个路径,然后绝对地将path放在元素上(和path一起放置它在文本背后)。 SVG本质上是可扩展的,因此即使容器的宽度和/或高度增加它们也可以适应。

SVG的优点几乎与基于梯度的方法类似。 SVG优于基于渐变的方法的方式是,它具有更好的浏览器支持(应该在IE9 +中工作),并且锯齿状边缘也不太明显。

&#13;
&#13;
z-index: -1
&#13;
.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);
}
&#13;
&#13;
&#13;

注意:您可以详细了解SVG的<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>元素及其命令(例如pathMz this MDN Tutorial中的L等。我个人建议你看一下SVG,因为它可以用很少的努力创建很多复杂的形状:)

答案 1 :(得分:1)

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

&#13;
&#13;
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;
}
&#13;
<div>Hover to see resized element</div>
&#13;
&#13;
&#13;