使用纯CSS解决方案动态添加多个盒子阴影

19

我想要实现多重下划线效果,发现使用盒阴影是最好的方法。具体来说,我尝试了以下方法并取得了成功:

输入图片说明

我使用了以下CSS进行操作:

h1{
    box-shadow: 0 2px 0px 0px #F03A47, 0 4px 0px 0px #FFF, 0 6px 0px #276FBF, 0 8px 0px 0px #FFF, 0 10px 0px #AF5B5B;
    float: left;
}

但是,我希望能够根据需要打开或关闭特定的下划线效果。因此,我想出了以下方法,并将类添加到我的HTML中:

然而,我希望实现一种效果,可以根据需要打开或关闭特定的下划线。因此,我想到了这个方法,并将类添加到我的HTML中:

h1{
    float: left;
}
.red{
    box-shadow: 0 2px 0px 0px #F03A47, 0 4px 0px 0px #FFF;
}
.blue{
    box-shadow: 0 6px 0px #276FBF, 0 8px 0px 0px #FFF;
}
.brown{
    box-shadow: 0 10px 0px #AF5B5B, 0 12px 0px 0px #FFF;
}

然而它产生的效果是这样的:

输入图像描述在此处

我尝试按不同顺序添加类,并使用JavaScript动态添加它们,但我仍然得到相同的结果。 我做错了什么吗,还是有其他方法可以实现开关效果?


那么很明显白色条纹(使用#fff)不是一个选项...对吧? - Roko C. Buljan
1
你不能像那样分别处理它们,但是你可以为组合制作CSS选择器,例如.red.blue.red.blue.brown.red.brown.blue.brown等。此外,我还没有尝试过在box-shadow中使用它,但你可以看看CSS变量是否允许你缩写每个类的值。 - Patrick Roberts
调用一个函数来根据传入的参数添加盒子阴影是否可行?例如:addUnderlines(['red', 'blue']) - Ethan
@David 即使你不能创建透明间隙。 - Roko C. Buljan
请查看并评论任何答案,并让我们知道是否有不清楚或缺失的地方。如果没有,那么如果您能接受帮助您最多的答案,那就太好了。 - Asons
6个回答

18
这可以通过使用伪元素(pseudo elements)来实现:

h1 {
  display:inline-block;
  border-bottom:2px solid #e8353b;
  position:relative;
}
  h1:before {
    content:"";
    height:2px;
    width:100%;
    background:#2762be;
    display:block;
    position:absolute;
    bottom:-6px;
  }
  h1:after {
    content:"";
    height:2px;
    width:100%;
    background:#a3514f;
    display:block;
    position:absolute;
    bottom:-10px;
  }
<h1>Hello there</h1>


10

使用 <span> 的有趣方式 :)

您可以添加任意数量的 <span>,并在 CSS 中扩展颜色调色板:

.borders {
  display: inline-block;
}
.borders span {
  display: block;
  height: 2px;
  margin: 2px;
}
.borders span:nth-child(1) { background: red; }
.borders span:nth-child(2) { background: blue; }
.borders span:nth-child(3) { background: green; }
/* Add more here */
<h1 class="borders">
  Hi there
  <span></span>
  <span></span>
  <span></span>
</h1>

或者,如果你只需要3个边框,并且不想插入额外的HTML元素:

在你的第一个类中使用border-bottom,然后在第二个类上使用:before,在第三个类上使用:after

h1 {
  position: relative;
  display: inline-block;
}

.red{
  box-shadow: 0 2px 0 red;
}

.blue:after, .green:before{ content: ""; position: absolute; width: 100%; left: 0; }

.blue:after{
  bottom: -6px;
  border-bottom: 2px solid blue;
}

.green:before{
  bottom: -10px;
  border-bottom: 2px solid green;
}
<h1 class="red blue green">Hi there</h1>


1
<hr> 这个东西基本上和使用表格进行布局是一样的。但更糟糕的是,与布局表格不同的是,它甚至不合法。 - BoltClock
@bolt 谢谢。HR 在流元素内是完全允许的,H1 就是这样的元素,一个块级元素。虽然浏览器样式规则没有定义,但实际上你可以为 HR 标签设置样式。我本应该使用 SPAN,但现在就这样吧。除了作为语义上的“分隔符”之外,我找不到任何关于 HR 不被允许或已被弃用的有效论据。有什么想法吗? - Roko C. Buljan
2
“内容模型:短语内容。” 因此,H1中不允许使用HR,因为H1的内容模型不期望流元素。 - BoltClock

3
你可以使用linear-gradient,这将完全透明。
请注意,在组合类时,它们不会合并属性值。在元素上设置的最后一个属性将覆盖任何先前的属性,无论它们是否在具有不同名称的类中设置,因此你的线条变成了全棕色。

body {
  background: lightgray
}

h1{
    float: left;
    padding-bottom: 8px;
    background-size: 100% 2px;                         /* thickness 2px */
    background-repeat: no-repeat;
    background-position: 
      left bottom, left bottom 4px, left bottom 8px;   /* gutter 2px */ 
    background-image:
      linear-gradient(to right, blue, blue),           /* bottom line */
      linear-gradient(to right, green, green),         /* middle line */
      linear-gradient(to right, red, red);             /* top line */
  }
  
h1.red{
    background-image:
      linear-gradient(to right, blue, blue), 
      linear-gradient(to right, green, green),      
      linear-gradient(to right, transparent,transparent);
}
h1.blue{
    background-image:
      linear-gradient(to right, transparent,transparent),
      linear-gradient(to right, green, green),      
      linear-gradient(to right, red, red);      
}
h1.green{
    background-image:
      linear-gradient(to right, blue, blue), 
      linear-gradient(to right, transparent,transparent),
      linear-gradient(to right, red, red);      
}
<h1>Hello there</h1>

<h1 class="green">Hello there</h1>

<h1 class="red">Hello there</h1>

<h1 class="blue">Hello there</h1>

你可以通过简单地省略不需要的线条来轻松重新定位线条并消除任何间隙。

body {
  background: lightgray
}

h1{
    float: left;
    padding-bottom: 8px;
    background-size: 100% 2px;                         /* thickness 2px */
    background-repeat: no-repeat;
    background-position: 
      left bottom, left bottom 4px, left bottom 8px;   /* gutter 2px */ 
    background-image:
      linear-gradient(to right, blue, blue),           /* bottom line */
      linear-gradient(to right, green, green),         /* middle line */
      linear-gradient(to right, red, red);             /* top line */
  }
  
h1.red{
    background-image:
      linear-gradient(to right, blue, blue), 
      linear-gradient(to right, green, green);     
}
h1.blue{
    background-image:
      linear-gradient(to right, green, green),      
      linear-gradient(to right, red, red);      
}
h1.green{
    background-image:
      linear-gradient(to right, blue, blue), 
      linear-gradient(to right, red, red);      
}
<h1>Hello there</h1>

<h1 class="green">Hello there</h1>

<h1 class="red">Hello there</h1>

<h1 class="blue">Hello there</h1>


2
您只需要使用1个伪元素即可实现此功能。
以下是我的操作步骤(包含控制间距的注释):

h1 {
    display: inline-block;
    /* controls the last line */
    border-bottom: 2px solid #a3514f;
}

h1:after {
    content: "";
    display: block;
    /* controls space between 1st and 2nd line */
    height: 2px;
    width: 100%;
    /* controls space between 2nd and 3rd line */
    margin-bottom: 2px;
    border-bottom: 2px solid #2762be;
    border-top: 2px solid #e8353b;
}
<h1>Hello there</h1>


这篇文章是基于@APAD1的答案写的,采用了他使用边框的想法。

这种方法的优点是整个::after都是<h1>的内容的一部分,而不是在外面。


1
OP要求:“然而,我希望能够实现根据需要打开和关闭特定的下划线效果。” - Roko C. Buljan
@RokoC.Buljan 去掉边框。很容易。或者使用类来控制边框高度。 - Ismael Miguel

1

你可以使用伪元素和边框添加最多五行。

每个类别都会添加一行新的内容。

*,
*:before,
*:after {
  box-sizing: border-box;
}
h1 {
  display: inline-block;
  padding-bottom: 2px;
  position: relative;
}
h1:before,
h1:after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 6px;
  bottom: -10px;
}
h1:after {
  bottom: -18px;
}
.one {
  border-bottom: 2px solid red;
}
.two:before {
  border-top: 2px solid blue;
}
.three:before {
  border-bottom: 2px solid green;
}
.four:after {
  border-top: 2px solid brown;
}
.five:after {
  border-bottom: 2px solid orange;
}
<h1 class="one two three four five">Lorem ipsum</h1>


0

只是尝试使用伪元素、边框、阴影等方式获取尽可能多的行数。

您最多可以获得9行,可以使用9个独立类进行设置/取消设置。

其中一些只能在固定的已知背景颜色(在本例中为白色)下工作。

.base {
  font-size: 60px;
  position: relative;
  display: inline-block;
}

.base:before,
.base:after {
  content: "";
  position: absolute;
  left: 0px;
  width: 100%;
  height: 10px;
  padding: 10px 0px;
  background-clip: content-box;
}

.base:before {
  bottom: -90px;
}
.base:after {
  bottom: -170px;
}

.a {
  border-bottom: solid 10px lightgreen;
}

.b {
  box-shadow: 0px 10px white, 0px 20px green;
}

.c:before {
  border-top: solid 10px lightblue;
}

.d:before {
  background-color: red;
}

.e:before {
  border-bottom: solid 10px yellow;
}

.f:before {
  box-shadow: 0px 10px white, 0px 20px green;
}

.g:after {
  border-top: solid 10px tomato;
}

.h:after {
  background-color: magenta;
}

.i:after {
  border-bottom: solid 10px gray;
}

.j:after {
  box-shadow: 0px 10px white, 0px 20px brown;
}
<h1 class="base a b c d e f g h i j">Hello world</h1>


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