CSS揭秘笔记(2):背景与边框

第2章:背景与边框

1.半透明边框

  • 背景知识:RGBA/HSLA颜色
    -给一个容器设置白色背景和一道半透明白色边框,body的背景会从他的半透明框上透上去
background:white;
border: 10px solid hsla(0,0,100%,0.5)
image.png

结果却不是我们想要的。为什么呢
因为背景色渗透到边框下的区域了。需要更改一下默认值(默认是border-box)

background:white;
border: 10px solid hsla(0,0,100%,0.5);
background-clip:padding-box;
image.png

2. 多重边框

  • box-shadow的基本用法

box-shadow方案

box-shadow方案还能接受第四个参数(称作扩张半径),通过指定正值或者负值,可以让投影面积加大或者减少。一个正确的扩展半径加上俩个为0的偏移量以及0 的模糊值,得到的投影其实就像是一道实线边框。

background:yellowgreen;
box-shadow:0 0 10px #655;
image.png

另外,他还支持逗号,我们可以创建任何数量的投影。

background:yellowgreen;
box-shadow:0 0 0 10px #655, 0 0 0 15px deeplink;
image.png

唯一需要注意的就是,box-shadow是层层叠加的,第一层投影位于顶层,以此类推。因此你需要按照这个规律来调整扩展半径。

-注意事项:

  • 1:投影的行为跟边框不一致,因为他不会影响布局,而且也不会收到box-sizing的影响
  • 2:上述方法创建的假的边框出现在元素的外圈。他们并不会响应鼠标事件,比如悬停或者点击。如果这一点非常重要,你可以给box-shadow属性加上inset关键字,来使投影绘制在元素的内圈,请注意,此时你需要增加额外的内边距来腾出足够的空隙。

3:outline方案

在某些情况下,你可能只需要两层边框,那就可以先设置一层常规边框,再加上outline(描边)属性来产生外层的边框。这种方式一大优点就是在于边框样式十分灵活,不像box-shadow只能模拟实现边距。(假如我们需要产生虚线边距效果,box-shadow就没辙了)如果想得到上图2-6的效果,代码可以这样写;

background:yellowgreen;
border: 10px solid #655;
outline: 5px solid deeppink;

描边的另外一个好处就是你可以通过outline-offset属性来控制他跟元素边缘之间的间距,这个属性甚至可以接受负值。


image.png

注意事项:

  • 他只适用于双层边框的场景,因为outline并不能接受逗号分割的多个值,如果我们需要获取更多层的边框,前一种方案是我们唯一的选择。
  • 边框不一定会贴合border-radius属性产生的圆角,如果此元素是圆角的,他的描边可能还是直角的(这种行为呗css工作组认为是一个bug,因此未来可能会改为贴合border-radius圆角)
image.png
  • 根据css基本ui特性规范所述,“描边可以不是矩形”,但如果你想适应这个方法,请切记最好在不同浏览器中完整的测试最终效果。

3:灵活的背景定位

1: background-position的扩展语法方案

background-position已经得到扩展,它允许我们指定背景图片距离任意角的偏移量,只要我们在偏移量前面指定关键字。举个例子,如果想让背景图片跟右边距保持20px的偏移量,同时跟底边保持10px的偏移量,可以这样做。

background:url(code-priate.svg) no-repeat #58a;
background-pistion: right 20px bottom 10px;
image.png

但是,在不支持background-position扩展语法的浏览器中,背景图片会紧贴左上角,如图所示。


image.png

提供一个会退方案,就是把老套的bottom right 定位值写进background的简写属性中。

background: url(code-private.svg) no-repeat bottom right #58a;
background-position: right 20px bottom 10px;

2:background-origin方案

在给背景图片设置距离某个角的偏移量时候,有一种情况及其常见:偏移量与容器的内边距一致,如果采用上面提到的background-position的扩展语法方案,代码看起来是这样的:

padding: 10px;
background:url(code-private.svg) no-repeat #58a;
background-position: right 10px bottom 10px;
image.png

这样就可以看到,他虽然起作用了,但是代码不够DRY, 每次改动内边距的值时,我们都需要在其他三个地方更新这个值。
所以还有一个更简单的办法实现这个需求:
题外话---默认情况下,background-position是以padding box 为准的,这样边距才不会遮住背景图片,因此top left 默认指的就是padding box 的左上角。background-position属性默认值也是padding-box,如果把他的属性改为content-box,我们在background-postion属性中使用的边角关键字将会以内容区的边缘作为基准(也就是说,此时背景图片距离边角的偏移量就跟内边距保持一致了)

padding: 10px;
backgroung: url("code-private.svg") no-repeat #58a bottom right ; /*或100%100%*/
backgroung-origin: content-box;

他的效果同上。另外如果你想让偏移量与内边距稍微有些不同,那么可以使用background-origin: content-box的同时,再通过background-position的扩展语法来设置这些额外的偏移量

3: calc()方案

上述问题我们可以通过这个函数轻而易举的解决:

background:url('code-private.svg') no-repeat;
background-position: calc(100% - 20px) calc(100% - 10px)

注意:两边各有一个空白符

4: 边框内圆角

  • 背景知识: box-shadow, outline“多重边框”
    要实现如下效果,我们通常用两个元素来实现


    image.png
image.png

但是我们如果只使用一个元素可以达到吗?

解决方案

background:tan;
border-radius: .8em;
padding: 1em;
box-shadow: 0 0 0 .6em #655;
outline: .6em solid #655;

5: 条纹背景

  • 背景知识:css线性渐变,background-size
width:100px;
height:100px;
background: linear-gradient(#fb3 40%, #58a 80%);

效果如图:


image.png

如果两个距离过近甚至相等,渐变就会越来越小。直至没有。
例如

width:100px;
height:100px;
background: linear-gradient(#fb3 450%, #58a 50%);
image.png

i因为渐变是一种由代码生成的图像,所以我们可以像对待其他背景一样的方式对待他们,而且还可以通过background-size来调整他的尺寸。

background: linear-gradient(#fb3 50%, #58a 50%);
width: 100px;
height: 100px;
background-size: 100% 20px;

效果如下:


image.png

由于背景方式默认是重复的,所以效果如上图,如果要创建不等宽的条纹,只需要调整色标的位置值即可。

background: linear-gradient(#fb3 30%, #58a 30%);
width: 100px;
height: 100px;
background-size: 100% 30px;

效果图如下


image.png

注意:如果某个色标的位置值比整个列表中他之前的色标的位置值都要小,则该色标的位置值将会被设置为它前面所有色标的位置值的最大值。这意味着,如果我们把第二个色标的位置值设置为0,那它的位置就总会被浏览器调整为前一个色标的位置值,这个结果正是我们想要的。

background: linear-gradient(#fb3 30%, #58a 0);
width: 100px;
height: 100px;
background-size: 100% 30px;

效果如图:


image.png

如果要创建超过两种的条纹也是很容易的举例子

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

如图:


image.png

垂直条纹

和水平条纹代码基本一致,差别在于我们需要在开头添加一个额外参数来指定渐变的方向。

background: linear-gradient(to right, #fb3 30%, #58a 0, #58a 66.6%, yellow 0);
width: 100px;
height: 100px;
background-size: 30px 100%;

效果如下:


image.png

斜向条纹

 background: linear-gradient(45deg, #fb3 30%, #58a 0, #58a 66.6%, yellow 0);
 width: 100px;
 height: 100px;
 background-size: 30px 30px;

结果如图,并不是我们想要的效果:


image.png

为什么,因为背景是重复的,相当于我们把每一个贴片的内部渐变旋转了45度,而不是把整个重复的背景都旋转了。
思考一下,一个小贴片中包含了四种颜色,如下图


image.png

只有这样才能做到无缝贴合。
因此代码需要更改为如下代码:
    background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
    width: 100px;
    height: 100px;
    background-size: 30px 30px;

如图:


image.png

根据勾股定理,如果想要产生等宽的渐变效果,需要做如下计算


image.png

image.png
    background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
    width: 100px;
    height: 100px;
    background-size: 42.42px 42.42px;
image.png

更好的斜向条纹

image.png

做一个对比,上述斜条纹可以通过如下代码进行实现

    width: 100px;
    height: 100px;
    background-size: 42.42px 42.42px;
    background: repeating-linear-gradient(45deg, #fb3 0, #fb3 14px, #58a 0, #58a 28px)

效果如下:


image.png

这种方式的好处就是修改颜色时候只需要修改两处而不是原来的三处,最大的好处就是可以随意指定角度了。需要注意的是,这里在创建双条纹时候,仍然需要指定四个色标值,意味着我们最好用前面的方法实现水平或者垂直条纹,而用这种方式来实现斜条纹。

灵活的同色系条纹

日常应用中,我们想要的条纹图案并不是由差异极大的几种颜色组成的,这些颜色往往属于同一个色系。只是在明度方面有着轻微的差异,这样在实际应用中对于这样的案例,可以通过代码体现出主色调和副色调之间的关系还可以在修改时候只用修改一处。代码如下

    width: 100px;
    height: 100px;
    background-size: 42.42px 42.42px;
    background: #58a;
    background-image: repeating-linear-gradient(30deg, hsla(0, 0%, 100%, 0.1), hsla(0, 0%, 100%, 0.1) 14px, transparent 0, transparent 28px)

效果如下图:


image.png

6:复杂的背景图案,

  • 渐变知识:css渐变,条纹背景

7:伪随机背景

8:连续的图像边框

9:自适应的椭圆

border-radius是用空格分开多个值,四个值是从左上角开始以顺时针顺序应用到元素的各个拐角。另外他也提供了完全不同的水平和垂直半径。通过斜扛 / 来区分的。

四分之一椭圆

  • 无非就是一个角的水平和垂直半径都需要是100%,而其他三个角都不能设置为圆角。
border-radius: 100% 0 0 0 ;

10平行四边形

-背景知识:基本的CSS变形

    margin: 0 auto;
    width: 200px;
    height: 200px;
    background: #58a;
    transform: skewX(45deg)

注意:这个属性对属性为行内的元素是不生效的,所以最好更改为其他的属性


image.png

你会发现,文本内容也发生变化了,显然这是我们不想要的,解决方法如下

1. 嵌套元素方案

  • 我们可以对容器在进行一次反向的skew变形,从而抵消容器的变形效果。

2. 伪元素方案

另一种思路就是把所有的样式(背景,边框等)应用到伪元素上面,然后在对伪元素进行变形

  .btn {
    position: relative;
    background: none;
    border: none;
  }
  .btn::before {
    content: '';
    position: absolute;
    background: #58a;
    transform: skewX(45deg);
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: -1;
  }

这个思路适用于其他任何样式,当我们想变形一个元素而不变形他的内容的时候就可以用到他。

11 菱形图片

基于变形的方案

<div class="outer">
   <div class="inner">菱形文本</div>
</div>
 .outer {
    margin: 100px auto;
    width: 100px;
    height: 100px;
    border: 1px solid green;
    transform: rotate(45deg);
    overflow: hidden;
  }

  .inner {
    max-width: 100%;
    height: 100%;
    background: gray;
    transform: rotate(-45deg);
    line-height: 100px;
    text-align: center;
  }

效果如图:


image.png

但是我们想让图片的宽度于外框对角线的长度相等,而不是与边长相等。这里又要用到勾股定理了。边长 * 1.414。如果用sale放大1.414倍会更改合理,因为宽度变宽是以左上角为中心点,而scale等默认是以中心点进行缩放的,前者需要在变换位移,后者不用,所以代码改为如此,

 .outer {
    margin: 100px auto;
    width: 100px;
    height: 100px;
    border: 1px solid green;
    transform: rotate(45deg);
    overflow: hidden;
  }

  .inner {
    max-width: 100%;
    height: 100%;
    background: gray;
    transform: rotate(-45deg) scale(1.42);
    line-height: 100px;
    text-align: center;
  }

效果如下:


image.png

裁切路径方案

上述方法对图片宽高有要求,假如图片不符合要求,上述方案就会出现bug,可见这种方式是由一种hack处理方式------------不够简洁,不够直观,也不够健壮。
clip-path: polygon(...) // 多边形

<img class="img" src="https://upload.jianshu.io/admin_banners/web_images/4609/5c252cdb56c9924a035c052cf56753f096a1d6e8.jpg"
      alt="">
.img {
    width: 200px;
    height: 200px;
    clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%)
  }

效果如图:


image.png

还可以参与动画实现

  .img {
    width: 200px;
    height: 200px;
    clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
    transition: 1s clip-path;
  }
  .img:hover {
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%)
  }

12. 切角效果

解决方案

  1. css背景渐变
 .third {
    width: 100px;
    height: 100px;
    background: #58a;
    background: linear-gradient(-45deg, transparent 15px, #58a 0);
    margin: 0 auto;
  }

效果如图:


image.png

如果想要两个角被切掉的效果,最初的想法是这样的

 .third {
    width: 100px;
    height: 100px;
    background: #58a;
    background: linear-gradient(-45deg, transparent 15px, #58a 0), linear-gradient(45deg transparent 15px, #655, 0);
    margin: 0 auto;
  }

发现行不通,原因:默认情况下,这两层渐变都会调填满整个元素,因此他们会相互覆盖。需要让他们都缩小一半,于时我们用background-size来让每个渐变只占元素背景的一般

弧形切角

13 梯形标签页

生成梯形

.thirteen {
    transform: perspective(.5rem) rotateX(5deg);
    width: 100px;
    height: 100px;
    margin: 0 auto;
    background: #58a;
  }

效果如下


image.png

由于这里我们是对整个元素进行3d变形的,因此上面的文字也是变形的。并且对元素采用3d变形以后,元素的内部变形是“不可逆转”的。所以我们可以采用利用伪类的方式来实现生成梯形。有些类似于上面的平行四边形。

.thirteen {
    position: relative;
    color: white;
    padding: 0.5em 1em .35em;
    display: inline-block;
  }

  .thirteen::before {
    content: '';
    background: #58a;
    top: 0;
    right: 0;
    left: 0;
    bottom: 0;
    z-index: -1;
    position: absolute;
    transform: perspective(.5rem) rotateX(5deg);
  }

效果如图


image.png

这样可以实现,但是有一个问题,如果我们没有设置transform-origin的属性时候,应用变形效果会让这个元素以自身的中心线为轴进行空间上的旋转。因此,元素投射到2d屏幕上的尺寸会发生多种变化。
。。。。

14简单的饼图

1:基于transform的解决方案

  • 这个方案在结构上是最佳解决方法:它只需要一个元素作为选择器,而其他部分由伪元素/变形元素/和css渐变来实现。




©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • 所有图都在body背景设置为green下的截图,请不要把最外层的绿色当成边框 半透明边框 如果我们想给一个容器设置...
    hcxowe阅读 3,912评论 0 6
  • 我还记得国外某位大牛在一篇文章中写道,CSS is fine, it's just really hard。读完他...
    garble阅读 1,083评论 0 0
  • css3图案库:http://lea.verou.me/css3patterns/http://bennettfe...
    noyanse阅读 352评论 0 0
  • 半透明边框 RGBA/HSLA颜色H:Hue(色调)。0(或360)表示红色,120表示绿色,240表示蓝色,也可...
    牛牛_lz阅读 388评论 0 1
  • 选择qi:是表达式 标签选择器 类选择器 属性选择器 继承属性: color,font,text-align,li...
    love2013阅读 2,304评论 0 11