《CSS 揭秘笔记 -- 背景与边框》

背景与边框

半透明边框

问题

通常情况下,背景(色或图片)会延伸至元素边框外沿(但在边框下面),这种情况会导致边框和背景产生重叠,半透明边框呈现出来的是背景,无法实现半透明边框

解决方案

通过 background-clip 属性调整元素背景延伸范围

Demo

1
2
3
4
5
6
7
background-clip: [border-box] |[padding-box] | [content-box];

hsla(<色相>, <饱和度>, <明度>, <透明度>)
色相:0~360
饱和度:0%~1000%
明度: 0%(黑色)~100%(白色)
透明度:0~1
1
2
3
border: 10px solid hsla(175, 100%, 60%, .5);
background-clip: padding-box;
background: #03a9f4;

多重边框

实现多重边框

box-shadow 方案

Demo

1
box-shadow:none|| inset && [<x-offset> <y-offset> <blur-radius> <spread-radius> <color>];
1
2
3
4
5
6
7
8
9
10

div {
width: 100px;
height: 60px;
margin: 25px;
background: yellowgreen;
box-shadow: 0 0 0 10px #655,
0 0 0 15px deeppink,
0 2px 5px 15px rgba(0,0,0,.6);
}

outline 方案

Demo

1
outline:outline-width  || outline-style ||outline-color
1
2
border:10px solid #655;
outline: 5px solid deeppink;

对比

  • box-shadow 方案可以实现多层边框,但只能模拟实线边框
  • outline 方案只能实现两层边框,但边框的样式可以与 border 一样灵活,也可以通过 outline-offset 属性调整与边框的距离;另外,如果边框为圆角时,outline 无法贴合圆角

灵活的背景定位

背景图片定位在大小不固定的容器右下角,距底部和右边 20px

background 方案

Demo

1
2
background-position: <percentage> || <length> || [left | center| right] [, top | center | bottom]
background-origin: padding-box || border-box || content-box
1
2
3
4
5
6
background: url(code-pirate.svg) no-repeat bottom right #58a;
background-position: right 20px bottom 10px;

padding: 0 10px 20px 0;
background: url(code-pirate.svg) no-repeat bottom right #58a;
background-origin: content-box;

calc 方案

Demo

1
calc: (四则运算)
1
2
background: url(code-pirate.svg) no-repeat bottom right #58a;
background-position: calc(100% - 20px) calc(100% - 10px);

边框内圆角

实现一个内侧为圆角,外侧仍为直角的容器

两个元素解决方案

Demo

1
2
3
<div class="outer">
<div class="inner">边框内圆角效果</div>
</div>
1
2
3
4
5
6
7
8
9
10
.outer {
background-color: #655;
padding: 10px;
}

.inner {
border-radius: 5px;
background-color: tan;
padding: 10px;
}

一个元素解决方案

这种方案主要是利用 outline 不会跟着圆角走的特性,并通过 box-shadow 填充 outlineborder 之间的间隙,从而达到想要的效果

需要注意的是,box-shadow 的投影扩张值需大于 (√2 - 1)*rrborder-radius 长度

Demo

1
<div class="inner-round">边框内圆角效果</div>
1
2
3
4
5
6
7
8
.inner-round {
border-radius: 5px;
background-color: tan;
padding: 10px;

box-shadow: 0 0 0 2.5px #655; // 0.5 * 5 > (√2 - 1)*5
outline: 10px solid #655;
}

对比

两个元素的方案相对一个元素的方案更加灵活性,因为后者的 outline 无法像 border 一样灵活。

条纹背景

实现条纹背景效果,如水平条纹、垂直条纹、斜向条纹、同色条纹

解决方案

linear-gradient 配合 background-size

mark

根据上面的规范可知:

  • 默认第一个颜色的色标起始位置为 0%,最后一个颜色的色标起始位置为 100%
  • 如果某个色标的起始位置值比在它之前的色标的起始位置都要小,则该色标的起始位置会被设置它前面所以色标起始位置值的最大值
  • 如果所有色标都未设置起始位置,则会默认给每种色标平均分配空间
  • 如果多个色标的起始位置相同,那么它会之间会差生一个无限小的过渡区块,过度的起止色分别是第一个和最后一个指定值。从效果上看,颜色会在那个位置突然变化,而不是一个平滑的渐变过程
  • 水平条纹

    Demo

    1
    <div class="horizontal-stripes"></div>
    1
    2
    3
    4
    5
    6
    7
    8
    .horizontal-stripes {
    height: 60px;
    width: 300px;

    background-image: linear-gradient(#fb3 50%, #58a 50%);
    background-repeat: repeat;
    background-size: 100% 30px;
    }
  • 垂直条纹

    Demo

    1
    2
    3
    4
    5
    6
    7
    8
    .vertical-stripes {
    width: 300px;
    height: 60px;

    background-image: linear-gradient(to right, #fb3 50%, #58a 0);
    background-repeat: repeat;
    background-size: 75px 100%;
    }
  • 斜向条纹

    Demo

    1
    2
    <div class="diagonal-stripes-demo"></div>
    <div class="diagonal-stripes-demo1"></div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    div {
    width: 300px;
    height: 300px;
    display: inline-block;

    background-repeat: repeat;
    background-size: 42.4px;
    }
    .diagonal-stripes-demo {
    background-image: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
    }

    .diagonal-stripes-demo1 {
    background-image: repeating-linear-gradient(45deg, #fb3, #fb3 15px, #58a 0, #58a 30px);
    }
  • 同色系条纹

    Demo

    1
    <div class="subtle-stripes"></div>
    1
    2
    3
    4
    5
    6
    7
    .subtle-stripes {
    width: 300px;
    height: 300px;

    background-color: #58a;
    background-image: repeating-linear-gradient(45deg, hsla(0, 0%, 100%, .1), hsla(0, 0%, 100%, .1) 15px, transparent 0, transparent 30px);
    }