【问题标题】:Extended borders with CSS使用 CSS 扩展边框
【发布时间】:2016-08-12 15:41:08
【问题描述】:

我一直在用一些嵌套的 div 测试扩展/投影边框的想法,下面有一个工作示例。

基本上,我想要实现的是垂直和水平边框延伸到盒子外面,里面有内容。有点像草拟的样子。如果可能的话,我希望它能够完全响应。

在我的代码中,我设置了负边距的高度,以便获得我在视觉上寻找的效果,但对于我想要做的事情来说,我的标记似乎过于臃肿。它横向响应,但纵向我只是隐藏了溢出。

这样做时我脑海中闪过的另一个想法是有 4 个 div,每个边框边 1 个(上、右、下、左),然后将每个 div 偏移一定量以达到效果。有点像一个“摇晃”的 div 集群。这 4 个 div 将由父容器携带并响应。

这可以比我在小提琴中做的更简单吗?有没有办法让它在垂直和水平上都灵活(完全响应)?是否有可能在每个边框边都有可变的扩展名(例如一侧为 2px,另一侧为 4px)?

废话不多说,这就是我目前所拥有的:

body {
  margin: 0;
  padding: 0;
  width: 100%;
  font-family: Helvetica, Arial, sans-serif;
  /* text-align: center; */
}

.container {
  margin: 50px auto 0;
  padding: 0;
  width: 75%;
  height: 200px;
  position: relative;
}

.box-vert {
  margin: -10px 0;
  padding: 0;
  overflow: visible;
  height: 200px;
  position: absolute;
  border: 1px solid #C5C5C5;
  border-top: none;
  border-bottom: none;
}

.box-horz {
  height: 180px;
  margin: 10px -10px;
  overflow: visible;
  border: 1px solid #C5C5C5;
  border-left: none;
  border-right: none;
  padding: 0;
}

.box-inner {
  margin: 0 10px;
  padding: 20px;
  background-color: #ECECEC;
  height: 140px;
  float: left;
  overflow: hidden;
}

.box-inner h1 {
  margin: 0 0 10px;
  text-transform: uppercase;
  font-weight: 200;
  letter-spacing: 3px;
  font-size: 30px;
  color: #009688;
}

.box-inner p {
  margin: 0;
  line-height: 1.4;
  font-size: 14px;
  color: #666;
}
<div class="container">
  <div class="box-vert">
    <div class="box-horz">
      <div class="box-inner">
        <h1>Title Text Here</h1>
        <p>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Cras mattis consectetur purus sit amet fermentum. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vestibulum id ligula porta felis euismod semper.</p>
      </div>
    </div>
  </div>
</div>

【问题讨论】:

  • 您可以制作一个图像并将其用作边框并重复它。

标签: html css border css-shapes


【解决方案1】:

您可以使用单个元素和背景渐变来完成此操作,如下面的 sn-p。输出是响应式的(您可以在全页视图中看到)并且可以根据内容的大小自行调整。

这种方法有点复杂,因为它是用单个元素完成的,所以这里有一个解释:

  • 向元素的所有边添加 15 像素的内边距,以将文本流限制在较小的区域(即,在我们要创建的边框内)。
  • 添加了 4 个线性渐变背景图像(每个边框一个),并且它们的背景大小设置为每个边框的粗细为 1px,但其宽度/高度为 100%。
  • 对于顶部和底部边框,粗细/高度为 1px(或我们需要的任何值),边框的宽度将与容器的宽度相同,因此将 background-size 设置为 100% 1px
  • 对于左右边框,厚度/宽度为1px,高度为容器高度的100%,所以background-size设置为1px 100%
  • 然后定位这些渐变线,使其位于父级内部的偏移处。也就是说,上边框应该在 y 轴上偏移 10px(或者我们需要的任何值,但它应该小于填充),左边框应该在 x 轴上偏移 10px。同样,底部和右侧边框应从容器的底部和右侧边缘偏移 10px,因此使用 calc 函数来定位它们。
  • 对于元素的背景,我们不能在这种方法中使用简单的background-color,因为它会填满整个 div(超出边界)。我们甚至不能使用背景剪辑,因为这也会剪辑边框。因此,我们再次必须使用一个线性梯度,其大小比容器的尺寸小所有边的填充量。因此,此渐变的背景大小为calc(100% - 20px) calc(100% - 20px),位置也应相应偏移。
  • 可以通过更改渐变颜色来更改边框和背景颜色。

div {
  padding: 15px;
  margin-bottom: 10px;
  line-height: 1.4;
  font-size: 14px;
  color: #666;
  background: linear-gradient(#C5C5C5, #C5C5C5), linear-gradient(#C5C5C5, #C5C5C5), linear-gradient(#C5C5C5, #C5C5C5), linear-gradient(#C5C5C5, #C5C5C5), linear-gradient(#ECECEC, #ECECEC);
  background-size: 100% 1px, 1px 100%, 100% 1px, 1px 100%, calc(100% - 20px) calc(100% - 20px);
  background-position: 0px 10px, calc(100% - 10px) 0px, 0px calc(100% - 10px), 10px 0px, 10px 10px;
  background-repeat: no-repeat;
}

/* Just for demo */

h1 {
  margin: 0 0 10px;
  text-transform: uppercase;
  font-weight: 200;
  letter-spacing: 3px;
  font-size: 30px;
  color: #009688;
}
body {
  margin: 0;
  padding: 0;
  width: 100%;
  font-family: Helvetica, Arial, sans-serif;
  /* text-align: center; */
}
<div>
  <h1>Title Text here</h1>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</div>

<div>
  <h1>Title Text here</h1>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
  survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
  software like Aldus PageMaker including versions of Lorem Ipsum.</div>

如果您需要在每一侧进行可变扩展,只需根据以下逻辑更改填充、背景大小和位置:

  • 假设您需要边框在顶部延伸 6px,在右侧延伸 8px,在底部延伸 10px,在左侧延伸 12px,并且边框和文本之间的间距为 4px。然后使用以下逻辑设置填充。

    padding: [border-ext-top + space-between-borders-n-text]
             [border-ext-right + space-between-borders-n-text]
             [border-ext-bottom + space-between-borders-n-text]
             [border-ext-left + space-between-borders-n-text];
  • 背景图像渐变(产生边框)设置为遵循与填充相同的从上到右下到左的顺序。所以,如下设置background-position

    background-position: 0px [border-ext-top], 
                         calc(100% - [border-ext-right]) 0px, 
                         0px calc(100% - [border-ext-bottom]), 
                         [border-ext-left] 0px, 
                         [border-ext-left] [border-ext-top];
  • 由于paddingbackground-position 已更改,因此创建内部填充的渐变大小也应更改,以免溢出边框。

    background-size: 100% 1px, 1px 100%, 100% 1px, 1px 100%,
                     calc(100% - [border-ext-left + border-ext-right]) calc(100% - [border-ext-top + border-ext-bottom]);

div {
  padding: 10px 12px 14px 16px;
  margin-bottom: 10px;
  line-height: 1.4;
  font-size: 14px;
  color: #666;
  background: linear-gradient(#C5C5C5, #C5C5C5), linear-gradient(#C5C5C5, #C5C5C5), linear-gradient(#C5C5C5, #C5C5C5), linear-gradient(#C5C5C5, #C5C5C5), linear-gradient(#ECECEC, #ECECEC);
  background-size: 100% 1px, 1px 100%, 100% 1px, 1px 100%, calc(100% - 20px) calc(100% - 16px);
  background-position: 0px 6px, calc(100% - 8px) 0px, 0px calc(100% - 10px), 12px 0px, 12px 6px;
  background-repeat: no-repeat;
}

/* Just for demo */

h1 {
  margin: 0 0 10px;
  text-transform: uppercase;
  font-weight: 200;
  letter-spacing: 3px;
  font-size: 30px;
  color: #009688;
}
body {
  margin: 0;
  padding: 0;
  width: 100%;
  font-family: Helvetica, Arial, sans-serif;
  /* text-align: center; */
}
<div>
  <h1>Title Text here</h1>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</div>

<div>
  <h1>Title Text here</h1>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
  survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
  software like Aldus PageMaker including versions of Lorem Ipsum.</div>

【讨论】:

  • 这是一个了不起的人!感谢您如此彻底地解释了您在这里所做的事情以及两个不同的示例。一流的。
  • 如每个答案所述,有几种不同的方法可以做到这一点。现在真正的问题是,在更大规模、标记等方面最有效的使用是什么。基本上,这是最好的方式?
  • @Ce。恐怕我不能公正地回答这个问题。我的首选是渐变,因为它不需要负边距,没有隐藏的溢出,并且保留伪以供其他潜在用途,但这里没有正确/错误的答案。最好的可能是最适合您的网站的 ;)
【解决方案2】:

另一种解决方案是在 .container 中使用 4 个 span 元素,并使用 before 和 after 伪元素。

我已经为出站边框使用了几种颜色,您可以理解,哪个 css 规则操纵了边框。

span 元素相对于父元素是绝对定位的。所以这个解决方案是完全响应的。

现在您可以分别操作每条边界线。理论上,所有的边界线都可以有不同的高度/宽度,这取决于线是水平线还是垂直线。

body {
  margin: 0;
  padding: 0;
  width: 100%;
  font-family: Helvetica, Arial, sans-serif;
}

.container {
  margin: 50px auto 0;
  padding: 0;
  width: 75%;
  position: relative;
}
.container > span:before, .container > span:after {
  content: " ";
  display: block;
  position: absolute;
  background-color: #ccc;
}
.container > span:nth-child(1):before, .container > span:nth-child(1):after {
  width: 10px;
  height: 1px;
  left: 100%;
  background-color: red;
}
.container > span:nth-child(1):before {
  bottom: 0;
}
.container > span:nth-child(1):after {
  top: 0;
}
.container > span:nth-child(2):before, .container > span:nth-child(2):after {
  width: 10px;
  height: 1px;
  right: 100%;
  background-color: blue;
}
.container > span:nth-child(2):before {
  bottom: 0;
}
.container > span:nth-child(2):after {
  top: 0;
}
.container > span:nth-child(3):before, .container > span:nth-child(3):after {
  width: 1px;
  height: 10px;
  bottom: 100%;
  background-color: orange;
}
.container > span:nth-child(3):before {
  right: 0;
}
.container > span:nth-child(3):after {
  left: 0;
}
.container > span:nth-child(4):before, .container > span:nth-child(4):after {
  width: 1px;
  height: 10px;
  top: 100%;
  background-color: green;
}
.container > span:nth-child(4):before {
  right: 0;
}
.container > span:nth-child(4):after {
  left: 0;
}

.box-inner {
  padding: 20px;
  background-color: #ECECEC;
  height: 140px;
  border: 1px solid #ccc;
}

.box-inner h1 {
  margin: 0 0 10px;
  text-transform: uppercase;
  font-weight: 200;
  letter-spacing: 3px;
  font-size: 30px;
  color: #009688;
}

.box-inner p {
  margin: 0;
  line-height: 1.4;
  font-size: 14px;
  color: #666;
}
<div class="container">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <div class="box-inner">
    <h1>Title Text Here</h1>
    <p>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Cras mattis consectetur purus sit amet fermentum. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vestibulum id ligula porta felis euismod semper.</p>
  </div>
</div>

【讨论】:

    【解决方案3】:

    您可以使用单个元素和几个伪元素来实现此目的。下面是一个快速演示。

    div {
      position: relative;
      height: 300px;
      width: 80%;
      margin: 30px;
      background: tomato;
    }
    div:before {
      content: "";
      position: absolute;
      top: -2px;
      left: -30px;
      width: calc(100% + 60px);
      height: 100%;
      border-top: 2px solid cornflowerblue;
      border-bottom: 2px solid cornflowerblue;
    }
    div:after {
      content: "";
      position: absolute;
      left: -2px;
      top: -30px;
      height: calc(100% + 60px);
      width: 100%;
      border-left: 2px solid cornflowerblue;
      border-right: 2px solid cornflowerblue;
    }
    <div>
      <h4>Hello, World!</h4>
      Some Text
    </div>

    【讨论】:

    • 漂亮而简单。感谢您的贡献。我将继续并将其标记为答案,因为我认为这是最简单的实现,并且在更大规模的情况下效果最好,比如悬停时的变化等。
    【解决方案4】:

    你也可以使用,background-clip除了background-image渐变),background-size

    https://developer.mozilla.org/en-US/docs/Web/CSS/background-clip

    https://developer.mozilla.org/en-US/docs/Web/CSS/background-size

    https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient

    div {
      width:400px;/* whatever*/
      padding:20px;/* you need this ! use same units as for bg-position for better control  */
      margin:2em;/* whatever */
      background:/* draw images needed  to fake borders and bg-color */ 
        linear-gradient(to top, black,black) 1em 0 repeat-y ,
        linear-gradient(to top, black,black) calc( 100% - 1em) 0 repeat-y,
        linear-gradient(to left, black,black) 0 1em repeat-x,
        linear-gradient(to left, black,black) 0 calc(100% - 1em)  repeat-x ,
        linear-gradient(30deg,gray,lightgray) no-repeat;
      
      background-size: 3px 100%, 3px 100%, 100% 3px ,100% 3px , auto auto ;
      background-clip: border-box,border-box,border-box,border-box,content-box;
    }
    /* add some contet in html to test behavior , you may style it too */
    p {
      margin:0;
      padding:0.5em;
      text-align:justify
    }
    <div>
     <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit met isi.</p>
    </div>

    实际上与 harry 非常相似,只是与用于仅在内容区域内通过渐变绘制背景颜色的 background-clip 属性不同。

    【讨论】:

      【解决方案5】:
      <ul>
      <li><img src="#" class="logo"></li>
      </u
      

      【讨论】:

      • 请不要只发布代码,添加描述以获得更多帮助
      猜你喜欢
      • 2012-06-19
      • 1970-01-01
      • 2021-10-20
      • 2015-05-21
      • 2020-02-01
      • 1970-01-01
      • 2022-11-16
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多