美文网首页CSS
CSS揭秘系列一之"背景和边框"

CSS揭秘系列一之"背景和边框"

作者: Eastboat | 来源:发表于2019-10-08 18:41 被阅读0次

    工具函数

    //获取和遍历所有匹配特定css选择符的DOM元素
    function $$(selector, context) {
      context = context || document;
      var elements = context.querySelectorAll(selector);
      return Array.prototype.slice.call(elements);
    }
    
    //检测css属性支持情况
    function testProperty(property) {
      var root = document.getElement;
      if (property in root.style) {
        root.classList.add(property.toLowerCase());
        return root;
      }
      root.classList.add("no-" + property.toLowerCase());
      return false;
    }
    

    如果我们想要检测某个具体的属性值是否支持,那就需要把它赋给对应
    的属性,然后再检查浏览器是不是还保存着这个值。很显然,这个过程会改
    变元素的样式,因此我们需要一个隐藏元素

    var dummy = document.createElement("p");
    dummy.style.backgroundImage = "linear-gradient(red,tan)";
    if (dummy.style.backgroundImage) {
      root.classList.add("lineargradients");
    } else {
      root.classList.add("no-lineargradients");
    }
    
    //封装
    function testValue(id, value, property) {
      var dummy = document.createElement("p");
      dummy.style[property] = value;
      if (dummy.style[property]) {
        root.classList.add(id);
        return true;
      }
      root.classList.add("no-" + id);
      return false;
    }
    

    CSS 编码技巧

    1. 减少代码重复:代码可维护性的最大要素是尽量减少改动时要编辑的部分,当某些值相互依赖时,应该把他们的相互关系用代码表达出来

      1.代码易维护和代码量少不可兼得border-width: 10px 10px 10px 0;
      
      border-width: 10px;
      border-left-width: 0;
      
      2.
        颜色关键字
        currentColor
        3.
        继承
        inherit
        可以用在任何
        CSS
        属性中,而且它总是绑定到父元素的计算值
        .callout {
        position: relative;
      }
      .callout::before {
        content: "";
        position: absolute;
        top: -0.4em;
        left: 1em;
        padding: 0.35em;
        background: inherit;
        border: inherit;
        border-right: 0;
        border-bottom: 0;
        transform: rotate(45deg);
      }
      
      /* 行高是字号的1.5倍*/
      font-size: 20px;
      line-height: 1.5;
      
    1. 每个媒体查询都会增加成本, 尽最大努力实现弹性可伸缩的布局,并在媒体查询的各个断点区间内指定相应的尺寸

      
      避免不必要的媒体查询的小建议:
      
      1.使用百分比长度来取代固定长度
      
      2.当你需要在较大分辨率下得到固定宽度时,使用 max-width 而不是
      width ,因为它可以适应较小的分辨率,而无需使用媒体查询
      
      3.不要忘记为替换元素(比如 img 、 object 、 video 、 iframe 等)设
      置一个 max-width ,值为 100%
      
      4.background-size: cover,但是带宽并不是无限的,记住在移动网页中这么做往往是不明智的
      
      5.当图片(或其他元素)以行列式进行布局时,让视口的宽度来决定
        列的数量。弹性盒布局(即 Flexbox)或者 display: inline-block
        加上常规的文本折行行为,都可以实现这一点。
      
      6.在使用多列文本时,指定column-width(列宽)而不是指定column-count(列数)
        这样它就可以在较小的屏幕上自动显示为单列布局
      
      
    2. 合理使用简写

      background: url(tr.png) no-repeat top right / 2em 2em, url(br.png) no-repeat
          bottom right / 2em 2em, url(bl.png) no-repeat bottom left / 2em 2em;
      
      写成一个展开式属性background: url(tr.png) top right, url(br.png) bottom
          right, url(bl.png) bottom left;
      background-size: 2em 2em;
      background-repeat: no-repeat;
      
    3. 预处理语言,如果使用得当,它们在大型项目中可以让代码更加灵活

      
      1. CSS 的文件体积和复杂度可能会失控。即使是简洁明了的源代码,
      在经过编译之后也可能会变成一头从天而降的巨兽。
      
      2. 调试难度会增加,因为你在开发工具中看到的 CSS 代码并不是你写
      的源代码。不过这个问题已经大大好转了,因为已经有越来越多的
      调试工具开始支持 SourceMap。SourceMap 是一种非常酷的新技术,
      正是为了解决这个痛点而生的,它会告诉浏览器哪些编译生成的
      CSS 代码对应哪些预处理器 CSS 代码,精确到行号。
      
      
      3. 预处理器在开发过程中引入了一定程度的延时。尽管它们通常很快,
      但仍然需要差不多一秒钟的时间来把你的源代码编译成 CSS,
      
      4. 抽象都必然会带来更高的学习成本
      
      5. “所有重大的抽象机制在某种程度上都存在泄漏的情况。”
          预处理器是由人类写出来的,就像所有由人类写出来的大型程序一样,它们有它们自己的 bug。
          这些 bug 可能会潜伏很久,因为我们很少会怀疑预处理器的某个 bug 才是我们CSS 出错的幕后元凶。
      

    背景和边框

    半透明边框

    CSS 中的半透明颜色 rgba() 和 hsla()
    H:Hue(色调)。0(或 360)表示红色,120 表示绿色,240 表示蓝色,也可取其他数值来指定颜色。取值为:0 - 360
    S:Saturation(饱和度)。取值为:0.0% - 100.0%
    L:Lightness(亮度)。取值为:0.0% - 100.0%
    A:Alpha 透明度。取值 0~1 之间。

    如果不希望背景侵入边框所在的范围,我们要做的就是把它的值设为 padding-box ,这样浏览器就会用内边距的外沿来把背景裁切掉

    background-clip有三个属性值,
    
    即border-box、padding-box、content-box;
    border-box    背景被裁剪到边框盒。
    padding-box    背景被裁剪到内边距框。
    content-box    背景被裁剪到内容框。
    
    
    .one {
      width: 100px;
      height: 100px;
      background: red;
      border: 15px dashed hsla(214, 50%, 50%, 1);
      background-clip: padding-box;
    }
    
    background-clip的初始值是 border-box,意味着背景会被元素的border-box(边框的外沿框)裁切掉
      .two {
      width: 100px;
      height: 100px;
      background: red;
      border: 15px dashed hsla(214, 50%, 50%, 1);
    }
    
    image.png

    多重边框

    box-shadow 方案 : 只能模拟实线边框

    1. 接受第四个参数(称作“扩张半径”),通过指定正值或负值,可以让投影面积加大或者减小
    2. 你完全可以用 border 属性来生成完全一样的边框效果。不过 box-shadow 的好处在于,它支持逗号分隔语法,我们可以创建任意数量的投影
    .one {
      width: 100px;
      height: 100px;
      background: red;
      box-shadow: 0 0 0 10px hsla(214, 50%, 50%, 1);
    }
    .two {
      width: 100px;
      height: 100px;
      background: yellowgreen;
      box-shadow: 0 0 0 10px #655, 0 0 0 20px deeppink,
        0 2px 5px 25px rgba(0, 0, 0, 0.6);
    }
    
    image.png

    outline 方案 : 可以产生虚线边框效果

    outline 它只适用于双层“边框”的场景。在某些情况下,你可能只需要两层边框,那就可以先设置一层常规边框,再加上 outline(描边)属性来产生外层的边框

    .one {
      width: 100px;
      height: 100px;
      background: yellowgreen;
      border: 10px solid #655;
      outline: 10px solid deeppink;
    }
    .two {
      width: 140px;
      height: 140px;
      background: yellowgreen;
      outline: 2px dashed deeppink;
      outline-offset: -10px;
    }
    
    注意:通过outline
      属性实现的“边框”不会贴合元素的圆角,不过这一行为在未来可能会发生变化
      .three {
      width: 140px;
      height: 140px;
      background: yellowgreen;
      outline: 2px dashed deeppink;
      border-radius: 20px;
    }
    
    image.png

    灵活的背景定位

    background-position

    对于具有固定尺寸的容器来说,使用 CSS 2.1 来做到这一点是可能的,
    但很麻烦:可以基于它自身的尺寸以及我们期望它距离右下角的偏移量,计
    算出背景图片距离左上角的偏移量,然后再把计算结果设置给 background-
    position,,借助现代的 CSS 特性,我们已经拥有了更好的解决方案

    .one {
      width: 200px;
      height: 200px;
      background: url("../logo.jpg") no-repeat #58a;
      background-size: 50px 50px;
      background-position: right bottom;
    }
    .two {
      width: 200px;
      height: 200px;
      background: url("../logo.jpg") no-repeat #58a;
      background-size: 50px 50px;
      background-position: right 50px bottom 50px;
    }
    
    image.png

    兼容性的回退方案:在不支持 background-position 扩展语法的浏览器中,背景图片会紧
    贴在左上角(背景图片的默认位置)

    #app {
      width: 200px;
      height: 200px;
      background: url("../img.jpg") no-repeat bottom right #58a; //回退方案
      background-position: right 20px bottom 10px;
    }
    
    backgroung-origin

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

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

    上面定义方式的缺点:每次都要改动三个值,所以有一个更简单的办法可以实现这个需求:让它自动地跟着我们设定的内边距走,不用另外声明偏移量的值

    默认情况下,background-position 是以 padding box 为准的,这样边框才不会遮住背景图片

    background-position: top left;
    
    top left 默认指的是 padding box 的左上角,这样边框才不会遮住背景图片
    
    盒模型如下图
    
    image.png

    将 backgroung-origin 设置为content-box,background-position 中使用的边角关键字将会以内容区的边缘作为基准(也就是说,此时背景图片距离边角的偏移量就跟内边距保持一致了):如下代码

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

    案例展示:

    .three {
      width: 200px;
      height: 200px;
      padding: 20px;
      background: url("../logo.jpg") no-repeat #58a;
      background-size: 50px 50px;
      background-position: right 20px bottom 20px;
      //padding改动,background-position的偏移量也要改动
    }
    
    .four {
      width: 200px;
      height: 200px;
      padding: 20px;
      background: url("../logo.jpg") no-repeat #58a;
      /* background: url('../logo.jpg') no-repeat #58a right bottom; */
      background-size: 50px 50px;
      background-position: right bottom;
      background-origin: content-box; //设置为以内容区为基准,padding不在影响它
    }
    
    image.png
    background-origin.gif
    calc()方案

    左上角偏移的思路来考虑,其实就是希望它有一个 100% - 20px 的水平偏移量,以及 100% - 10px 的垂直偏移量

    width: 200px;
    height: 200px;
    background: url("../logo.jpg") no-repeat #58a;
    background-size: 50px 50px;
    background-position: calc(100% - 20px) calc(100% - 10px); //左上角偏移
    

    边框内圆角

    box-shadow, outline, "多重边框"

    一个容器,只在内侧有圆角,而边框或描边的四个角在外部,仍然保持直角的形状

    .parent {
      width: 200px;
      height: 60px;
      background: #655;
      padding: 0.8em;
    }
    
    .child {
      font-size: 10px;
      background: tan;
      border-radius: 10px;
      padding: 2em;
      text-align: center;
    }
    
    image.png

    这个方法很好,但要求我们使用两个元素,如果我们只需要一个元素呢?

    .parent1 {
      margin: 100px;
      width: 200px;
      background: tan;
      border-radius: 10px;
      padding: 10px;
      box-shadow: 0 0 0 10px #655;
      outline: 12px solid #655;
    }
    
    .parent2 {
      margin: 100px;
      width: 200px;
      background: tan;
      border-radius: 10px;
      padding: 10px;
      box-shadow: 0 0 0 10px #655;
      outline: 12px solid red;
    }
    
    GIF.gif

    条纹背景

    CSS 线性渐变,background-size

    水平条纹

    假设我们有一条基本的垂直线性渐变,颜色从 #fb3 过渡到 #58a

    <style>
      .app {
        width: 300px;
        height: 300px;
      }
      .one {
        background: linear-gradient(#fb3, #58a);
      }
      .two {
        background: linear-gradient(#fb3 30%, #58a 30%);
        background-size: 100% 30px;
      }
    </style>
    <div class="app one"></div>
    
    <div class="app two"></div>
    

    如果我们把第二个色标的位置值设置为 0,那它的位置就总是会被浏览器调整为前一个色标的位置值,如果要创建超过两种颜色的条纹,也是很容易的

    <style>
      .app {
        width: 300px;
        height: 300px;
      }
      .three {
        background: linear-gradient(
          rgb(0, 183, 255) 33.3%,
          yellow 0,
          blue 66.6%,
          green 0
        );
        background-size: 100% 60px;
      }
    </style>
    <div class="app three"></div>
    
    垂直条纹
    background: linear-gradient(to right, /* 或 90deg */ #fb3 50%, #58a 0);
    background-size: 30px 100%;
    
    斜向条纹
    更好的斜向条纹
    灵活的同色系条纹

    复杂的背景图案

    伪随机背景

    连续的图像边框

    相关文章

      网友评论

        本文标题:CSS揭秘系列一之"背景和边框"

        本文链接:https://www.haomeiwen.com/subject/mekipctx.html