代码示例

边框

半透明边框

  • 使用 rgba 或 hsla 格式的颜色生成半透明效果
  • 但是,会有问题……
div {
  // 白色背景和白色半透明边框重叠在一起!
  background: white;
  border: 10px dashed rgba(255, 255, 255, 0.5);
}

解决方案:修改background-clip属性。

  • border-box(默认)
  • padding-box(留出边框)
div {
  background-clip: padding-box;
}

多层边框

  • 层叠多个box-shadow
  • 利用「扩展阴影」属性
div {
  background: salmon;

  // 10px15px 均表示扩展阴影
  // 阴影的模糊值设为 0
  // 多层阴影按代码次序从上到下排列
  // 仍然可以设置正常阴影
  box-shadow:
    0 0 0 10px mistyRose,
    0 0 0 15px fireBrick,
    0 2px 5px 15px rgba(0, 0, 0, 0.6);
}

注意:

  • box-shadow不会占用布局空间
  • 向外扩展的阴影不会相应鼠标等事件
  • 可以设置阴影的inset属性,再设置额外的padding
div {
  background: salmon;
  box-shadow:
    inset 0 0 0 5px fireBrick,
    inset 0 0 0 15px mistyRose,
    inset 0 2px 5px 15px rgba(0, 0, 0, 0.6);
  padding: 15px;
}

如果只需要两层边框,也可以用outline属性:

PS:设置负的outline-offset可以把边框往里推。

div {
  background: salmon;
  border-radius: 10px;
  outline: 2px dashed white;
  outline-offset: -10px;
}

内部的 border-radius

综合利用outlinebox-shadow,生成外边尖角,内部圆角的效果。

div {
  background: salmon;

  // 内部的圆角效果
  border-radius: 1em;

  // 填满 outline  border-radius 之间的间距
  box-shadow: 0 0 0 0.7em mistyRose;

  margin: 1em;

  // 构建外部的尖角边框
  outline: 1em solid mistyRose;
}

背景

动态变化位置的背景图

CSS3 扩展了background-position的语法,支持背景图与四周的边距。

div {
  background: mistyRose url($bg) no-repeat bottom right;

  // 距离右边 20px,下边 10px
  background-position: right 20px bottom 10px;
}

默认background-positionpadding-box开始计算。也就是说,边框不会和背景图片叠加;topleft等值都是从padding-box的外边距开始测量。

可以通过修改background-origin,使背景从content-boxborder-box开始平铺。

div {
  background: mistyRose url($bg) no-repeat bottom right;

  // 背景图和边框之间留下了边距,保持美观
  background-origin: content-box;

  line-height: 80px;
  padding: 10px 20px;
}

也可以用 calc() 计算出边距,但不推荐。

div {
  background-position: calc(100% - 20px) calc(100% - 10px);
}

条纹背景

线性渐变 + background-size可以营造出美妙的条纹效果。

在渐变中,如果两个颜色的 stop 值相等,就会产生泾渭分明的边界:

div {
  // stop  0 表示与上一个 stop 值相同
  // 调整 stop 的值,可以修改两种颜色所占的比例
  background: linear-gradient(salmon 50%, lightSalmon 0);
}

渐变产生的效果等同于background-image,那么,就可以为渐变设置background-size

div {
  background:
    linear-gradient(
      salmon 33.3%,
      lightSalmon 0, lightSalmon 66.7%,
      mistyRose 0
    );
  background-size: 100% 50%;
}

调整渐变的方向产生纵向条纹:

div {
  background:
    linear-gradient(
      90deg,
      salmon 33.3%,
      crimson 0, crimson 66.7%,
      mistyRose 0
    );

  // size 的宽高前后次序也要调整
  background-size: 45px 100%;
}

同理的对角线条纹:

div {
  // 对角线要设置 4  stop 才有平铺的效果
  background:
    linear-gradient(
      45deg,
      salmon 25%,
      mistyRose 0, mistyRose 50%,
      salmon 0, salmon 75%,
      mistyRose 0
    );

  // 要设置成方块,类似铺方砖
  // 如果要让条纹的粗细为 15pxsize 需要 设置为 15 * 2 * 根号 2
  background-size: 42px 42px;
}

更好的方式:利用重复渐变repeat-linear-gradient

div {
  // 15px30px 取代了原先的 background-size
  background:
    repeating-linear-gradient(
      45deg,
      salmon, salmon 15px,
      mistyRose 0, mistyRose 30px
    );
}

由于repeat-linear-gradient设置条纹必须要有四个 stop,一般只用来设置斜向的条纹。垂直的条纹还是用linear-gradient + background-size的方式。

有时候相间的条纹为同色调,这时可以用「底色 + 阴影条纹」的方式:

div {
  background: salmon;

  // 透明度为 10% 的白色和纯透明组成的条纹
  background-image:
    repeating-linear-gradient(
      30deg,
      rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5) 15px,
      transparent 0, transparent 30px
    );
}

复杂的背景图案制作

原理:background-image可以设置多个。

横竖条纹的叠加:

div {
  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;
}

用写死的 stop 值调整边框的粗细:

div {
  background: salmon;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.6) 1px, transparent 0),
    linear-gradient(90deg, rgba(255, 255, 255, 0.6) 1px, transparent 0);
  background-size: 30px 30px;
}

结合径向渐变radial-gradientbackground-position,可以做成密集的点状背景图:

div {
  background: salmon;
  background-size: 30px 30px;

  // 位于画布中心的圆,半径为 30%
  background-image:
    radial-gradient(mistyRose 30%, transparent 0),
    radial-gradient(mistyRose 30%, transparent 0);

  // 第一个圆在中心,第二个圆被移动到边角
  background-position: 0 0, 15px 15px;
}

(伪)随机背景

重点:background-size的值设置成质数,不可整除,减少重复。

div {
  background-color: white;
  background-image:
    linear-gradient(90deg, salmon 11px, transparent 0),
    linear-gradient(90deg, fireBrick 23px, transparent 0),
    linear-gradient(90deg, mistyRose 41px, transparent 0);

  // 三组条纹的 size 不同,且按规律出现的概率非常小
  background-size: 41px 100%, 61px 100%, 83px 100%;
}

以一张完整的图片作为边框

解决方案:同时使用背景色和背景图,设置不同的background-clip

div {
  // 用背景图的方式(渐变)设置背景色,这样就可以用 background-clip
  background:
    linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8)),
    url($border);
  background-size: cover;

  // 背景色从 padding 开始,背景图从边框开始
  background-clip: padding-box, border-box;

  // 指定背景图开始平铺的位置
  background-origin: border-box;

  // 图片所占用的宽度
  border: 1em solid transparent;

  padding: 1em;
}

同理,可以设置条纹边框:

div {
  border: 1em solid transparent;
  background:
    linear-gradient(white, white) padding-box,
    repeating-linear-gradient(
      -45deg,
      red 0, red 12.5%,
      transparent 0, transparent 25%,
      #58a 0, #58a 37.5%,
      transparent 0, transparent 50%
    ) 0 / 5em 5em;
  padding: 1em;
}