Skip to content

Latest commit

 

History

History
552 lines (394 loc) · 16.9 KB

背景和边框.md

File metadata and controls

552 lines (394 loc) · 16.9 KB

背景和边框

半透明边框 background-clip

在 css 中,如果想实现半透明边框,很久之前使用的方案是采用背景来实现。

虽然我们很早就已经拥有 rgba 或者 hsla 的属性来实现半透明颜色,但是以下代码在以前依然不能实现半透明边框

<div>This is a div box</div>
* {
  box-sizing: border-box;
}
body {
  color: white;
  background-color: gray;
  height: 100vh;
}
div {
  height: 200px;
  width: 200px;
  border: 10px solid hsla(0, 0%, 100%, 0.8);
  background-color: white;
  color: black;
}

image-20210912121106545

可以看到实际效果中,并没有 border 的颜色。

这是因为盒子的背景颜色默认被扩展到边框,所以我们没办法看到设置好的 border

遇到这种问题,我们可以通过设置background-clip属性来达到我们想要的效果。

background-clip 设置元素的背景(背景图片或颜色)是否延伸到边框、内边距盒子、内容盒子下面。

如果没有设置背景图片(background-image)或背景颜色(background-color),那么这个属性只有在边框( border)被设置为非固实(soild)、透明或半透明时才能看到视觉效果(与 border-styleborder-image 有关),否则,本属性产生的样式变化会被边框覆盖。

background-clip 默认为border-box;我们将其设置为padding-box就可以让背景颜色不延伸到边框部分,这样就可以显示出我们设置好的半透明边框。

background-clip: padding-box;

image-20210912131533947

所有属性:

  • border-box 背景延伸至边框外沿(但是在边框下层)。

  • padding-box 背景延伸至内边距(padding)外沿。不会绘制到边框处。

  • content-box 背景被裁剪至内容区(content box)外沿。

  • text 背景被裁剪成文字的前景色。

最后一个属性挺好玩的,它可以只让背景只延伸到文字,类似于这样

image-20210912132238073

background-clip: text;
-webkit-background-clip: text;
color: transparent;

多重边框

在以前,我们很有可能通过各种丑陋的 hack(不理想方式)来实现多重边框,现在我们有两种方法帮助我们实现

  • box-shadow 阴影
  • outline 外边框

box-shadow

Box-shadow 的第四个参数为扩张半径,一个正值的扩张半径加上两个为零的偏移量以及为零的模糊值,可以让投影变成像一道实线边框

image-20210912133832105

background-color: yellowgreen;
box-shadow: 0 0 0 10px red;

box-shadow 还支持分割语法,我们可以创建任意数量的投影。

box-shadow: 0 0 0 10px red, 0 0 0 15px blue;

image-20210912133806996

阴影是层层叠加的,上面的代码,我们让最外层多了 5px 的阴影,从而变得就像双边框一样。

注意事项

  • 阴影并不会受 box-sizing 属性的影响,也就是它不占用空间,我们可以使用 margin 或者 padding 来模拟出它需要占用的空间。

  • 阴影不会影响到鼠标事件,因为它在元素的外圈。我们可以使用 insert 属性来绘制内阴影,此时还需要增加 padding 来让盒子撑开,因为阴影不占用空间,如果不使用内边距,视觉上盒子就小了一圈。

    background-color: yellowgreen;
    padding: 15px;
    box-shadow: inset 0 0 0 5px blue, inset 0 0 0 15px red;
    image-20210912135749296

outline

需要双层边框的情况下,我们可以使用 border+outline 来产生外层的边框

border: 10px solid blue;
outline: 5px solid red;

image-20210912140632362

使用 outline 的方式非常灵活,还可以配合 outline-offset 来设置 outline 与一个元素边缘或边框之间的间隙,从而模拟出一些缝边效果。

border: 1px solid transparent;
border-radius: 20px;
outline: 1px solid black;
outline-offset: -1px;

image-20210912142109834

如果减小 outline-offset,还可以让 outline 变得像内边框,border 像外边框

outline-offset: -11px;

image-20210912144948312

注意事项

即使 border 设置成圆角,outline 可能还是直角的。

背景定位

现在我有这样的盒子

div {
  margin: 100px auto;
  background: no-repeat url(./九尾.jpg) white bottom right;
  height: 200px;
  width: 200px;
}

它的效果是这样的

image-20210912151311100

我希望那张背景图片往左边移动 20px,往上移动 20px,类似于以下情况。

image-20210912152125721

要怎么做?

background-position 方案

最新的 background-position 已经支持平移量了,我们可以直接写

background: no-repeat url(./九尾.jpg) white bottom 20px right 20px;

如果想要兼容部分浏览器,那我们需要提供一个回退方案

background: no-repeat url(./九尾.jpg) white;
background-position: bottom 20px right 20px;

background-origin 方案

在设置平移量的时候,有一种非常普遍的现象,就是我希望背景图片的平移量跟 padding 值保持一致,如果用 background-position 的方案,那我们的代码就是这样的。

padding: 20px;
background: no-repeat url(./九尾.jpg) white bottom 20px right 20px;

想要达到的效果是这样的

image-20210912153307341

这样维护性就不够了,要修改就要改三个地方,我们有更加方便的办法,设置 background-origin。

background-origin 规定了指定背景图片background-image 属性的原点位置的背景相对区域.

我们经常会设置 background-position,那么 bottom、right 的位置是从哪里开始计算的呢?这跟 background-origin 有关。

background-origin 的属性是这样的

  1. border-box 背景图片的摆放以 border 区域为参考
  2. padding-box 背景图片的摆放以 padding 区域为参考(默认)
  3. content-box 背景图片的摆放以 content 区域为参考

举个例子:盒模型是这样的

image-20210912152841377

默认情况下,背景图片的位置是以 padding box 为基准的,也就是说,bottom、right 是 padding box 的下方、右方。

所以我们直接改变 background-origin 的属性,就可以达到我们想要的效果

padding: 20px;
background: no-repeat url(./九尾.jpg) white bottom right;
background-origin: content-box; /* 以 content-box 为平移标准 */

calc 方案

Background-position 支持使用百分比的方式来写

background-position: 10% 50%; /* 从左到右10%,从上到下50% */

基于这个特点,我们可以使用 calc 来帮助我们计算平移量,所以代码就是这样写

background: no-repeat url(./九尾.jpg) white;
background-position: calc(100% - 20px) calc(100% - 20px);

边框内圆角(outline+boxshadow)

下面我们需要实现这样一个需求,边框内圆角效果

image-20210912215734322

我们当然可以使用两个盒子来做,但有没有一个盒子就模拟出来的呢?首先我们想到之前学过的 outline 或 box-shadow 来配合 border,比如我们现在用 outline 写

div {
  margin: 100px auto;
  background: tan;
  border-radius: 15px;
  outline: 10px solid #655;
  height: 200px;
  width: 200px;
}

出来的效果是这样的

image-20210912220118890

可以看到,虽然 border-radius 定义了圆角边框,但是 outline 却是直角的,而且还留了缝边空隙。

那我们用 box-shadow 试试

div {
  margin: 100px auto;
  background: tan;
  border-radius: 15px;
  /* outline: 10px solid #655; */
  box-shadow: 0 0 0 10px #655;
  height: 200px;
  width: 200px;
}

2021-09-12.220421

box-shadow 居然会继承 border-radius,所以这种方案肯定也是不行的。(据说未来会让 outline 继承 border-radius)

那我现在把两者结合一下,让 box-shadow 来补上空缺出来的缝边不就好了?

所以最终的代码是这样的

div {
  margin: 100px auto;
  background: tan;
  border-radius: 15px;
  outline: 10px solid #655;
  box-shadow: 0 0 0 7px #655;
  height: 200px;
  width: 200px;
}

条纹图案

linear-gradient

CSS linear-gradient() 函数用于创建一个表示两种或多种颜色线性渐变的图片。其结果属于数据类型,是一种特别的数据类型。

横向条纹

我们可以使用纯 CSS 来模拟条纹图案,下面我们来看一下其演变,首先这里是一个渐变色背景的 div

div {
  margin: 100px auto;
  border: 1px solid black;
  background: linear-gradient(#fb3, #58a);
  height: 200px;
  width: 200px;
}

它长这样

image-20210912222640979

如果我们把色标拉近一些,可以看到,实色的区域变多了,而渐变的区域变少了

background: linear-gradient(#fb3 20%, #58a 80%);

image-20210912225143077

上图中实色区域大概占 40%,渐变色区域占 60%。

百分比是设置实色的色标位置,意思是从这个高度百分比的位置开始渐变,这个位置之前的就是实色

如果我们将其渐变色的色标高度都设置成 50%,就会变成一个盒子内有两个各占 50%高度的实色

background: linear-gradient(#fb3 50%, #58a 50%);

image-20210912222901153

此时如果手动将 background-size 的高度设置短一些,它就会变成这样的效果。

background-size: 100% 30px;

image-20210912223151350

因为默认下的背景是重复且平铺的,所以整个容器都充满了水平条纹。

如果修改色标,还可以产生不等宽的条纹

background: linear-gradient(#fb3 20%, #58a 20%);

image-20210912224119359

“如果某个色标的位置值比整个列表中在它之前的色标的位置值都要小,则该色标的位置值会被设置为它前面所有色标位置值的最大值。” ——CSS 规范

借用上面的规范,我们可以直接将属性设置成这样,也能达到上面的效果,这样维护性更高

background: linear-gradient(#fb3 20%, #58a 0);

以下代码还可以产生三种颜色

background: linear-gradient(#fb3 33.3%, #58a 0, #58a 66.6%, yellowgreen 0);
background-size: 100% 30px;

image-20210912230858001

竖向条纹

竖向条纹的情况也很多,我们需要手动告诉渐变色,应该从左到右渐变,那么在横向条纹的基础上做一点修改就行了

background: linear-gradient(
  to right,
  /*这里设置从左到右渐变*/ #fb3 33.3%,
  #58a 0,
  #58a 66.6%,
  yellowgreen 0
);
background-size: 30px 100%; /*这里设置宽度*/

2021-09-12.231322

斜向条纹

background: linear-gradient(
  45deg,
  #fb3 25%,
  #58a 0,
  #58a 50%,
  #fb3 0,
  #fb3 75%,
  #58a 0
);
background-size: 32px 32px;

image-20210912232915600

使用repeating-linear-gradient的简写

background: repeating-linear-gradient(
  45deg,
  #fb3,
  #fb3 15px,
  #58a 0,
  #58a 30px
);

image-20210912233141767

复杂条纹

复杂条纹就是利用多个渐变条纹的组合体

div {
  width: 200px;
  height: 200px;
  background: white;
  background-image: linear-gradient(
      90deg,
      rgba(200, 0, 0, 0.5) 50%,
      transparent 0
    ), linear-gradient(rgba(200, 0, 0, 0.5) 50%, transparent 0);
  background-size: 30px 30px;
}

image-20210926134641791

网格

div {
  width: 200px;
  height: 200px;
  background: #58a;
  background-image: linear-gradient(white 1px, transparent 0), linear-gradient(90deg, white
        1px, transparent 0);
  background-size: 50px 50px;
}

image-20210926135037037

波点

radial-gradient

radial-gradient()CSS 函数创建了一个图像,该图像是由从原点发出的两种或者多种颜色之间的逐步过渡组成。它的形状可以是圆形(circle)或椭圆形(ellipse)。这个方法得到的是一个 CSS数据类型的对象,其是 的一种。

波点背景

div {
  width: 200px;
  height: 200px;
  background: #655;
  background-image: radial-gradient(tan 30%, transparent 0), radial-gradient(tan
        30%, transparent 0);
  background-size: 50px 50px;
  background-position: 0 0, 25px 25px;
}

image-20210926142743008

为了达到效果,第二层背景的定位值必须是贴片宽高的一半。

棋盘

div {
  width: 200px;
  height: 200px;
  background: #eee;
  background-image: linear-gradient(
      45deg,
      rgba(0, 0, 0, 0.25) 25%,
      transparent 0,
      transparent 75%,
      rgba(0, 0, 0, 0.25) 0
    ), linear-gradient(45deg, rgba(0, 0, 0, 0.25) 25%, transparent 0, transparent
        75%, rgba(0, 0, 0, 0.25) 0);
  background-size: 50px 50px;
  background-position: 0 0, 25px 25px;
}

image-20210926144612192

蚂蚁行军边框

div {
  width: 200px;
  padding: 1em;
  border: 1px solid transparent;
  background: linear-gradient(white, white) padding-box, repeating-linear-gradient(
        -45deg,
        black 0,
        black 25%,
        white 0,
        white 50%
      ) 0 / 0.6em 0.6em;
  animation: ants 12s linear infinite;
}
@keyframes ants {
  to {
    background-position: 100%;
  }
}

蚂蚁行军图