【问题标题】:Creating a div with dynamic height and an arrow facing inwards using CSS使用 CSS 创建具有动态高度和朝内箭头的 div
【发布时间】:2016-03-22 11:40:36
【问题描述】:

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

我们可以通过使用 jQuery 来做到这一点,但是否可以只在 CSS 中做到这一点?

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

【问题讨论】:

    标签: html css css-shapes linear-gradients


    【解决方案1】:

    使用线性渐变:

    您可以使用几个有角度的线性渐变来做到这一点,如下面的 sn-p 所示。从 sn-p 中可以看出,即使内容环绕(或)跨越多行,它也可以适应任何高度。

    形状创建如下:

    • 一对线性渐变(使用to [side] [side] 语法),几乎为50% 着色,其余50% 为透明。这两个渐变在 Y 轴上的大小为 50%(即元素高度的一半),在 X 轴上的大小为 20px(意味着三角形的宽度是固定的)。
    • 这些线性渐变位于元素的右上方和右下方,以产生三角形效果。
    • 另一个线性渐变(实际上是纯色),其 Y 轴大小为父级的 100% 高度,X 轴大小为 20px 小于 100%(使用 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 元素创建一个路径,然后将 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>

    注意:您可以在this MDN Tutorial 中阅读有关 SVG 的 path 元素及其命令(如 MzLA 等)的更多信息。我个人建议你看看 SVG,因为它有助于以非常少的努力创建许多复杂的形状 :)

    【讨论】:

      【解决方案2】:

      除了 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;
      }
      &lt;div&gt;Hover to see resized element&lt;/div&gt;

      【讨论】:

        猜你喜欢
        • 2012-12-13
        • 2016-06-18
        • 1970-01-01
        • 2012-12-16
        • 2014-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多