• CSS艺术之---负margin之美


    CSS中负边距(nagative margin)是布局中常常使用的一个技巧。仅仅要运用得当时常会产生奇异的效果。勘称CSS中的奇淫巧计,非常多CSS布局方法都依赖于负边距。掌握它对于前端童鞋来说还是非常重要的。

    一、原理

    文档流

    百度百科中的定义:文档流是文档中可显示对象在排列时所占用的位置。将窗口自上而下分成一行行, 并在每行中按从左至右的顺序排放元素,即为文档流。

    (自己的理解是从头到尾依照文档的顺序,该在什么位置就在什么位置,也能够依照上面的意思理解,自上而下,自左到右的顺序)

    那些没有脱离文档流的元素(指不是浮动元素也不是绝对定位、固定定位的元素等),其在页面中的位置是尾随者文档流的变化而变化的。看以下这幅图:

    这里写图片描写叙述

    负边距对这些由文档流控制的元素的作用是,会使它们在文档流中的位置发生偏移,但这样的偏移不同于相对定位。通过相对定位偏移后,其仍然会坚守着它原来占领的空间,不会让文档流的其他元素乘虚而入。而通过负边距进行偏移的元素,它会放弃偏移前占领的空间,这样它后面文档流中的其他元素就会“流”过来填充这部分空间。还是通过样例来说明吧。如今我们把上图中的块状元素、行内元素以及inline-block元素都设一个负边距 margin:-10px; 看看会发生什么:

    这里写图片描写叙述

    具体发生了什么变化自己体会体会,负的边距好像能减小元素在文档流中的尺寸一样,但其实。它的尺寸大小并没变,仅仅是文档流在计算元素位置的时候。会觉得负边距把元素的尺寸减小了。因此位置也就发生变化了。


    所以,一切仅仅要是由文档流决定的东西,负边距就能起作用了。

    总之中的一个句话,在文档流中,元素的终于边界是由margin决定的。margin为负的时候就相当于元素的边界向里收,文档流认的仅仅是这个边界。不会管你实际的尺寸是多少。

    负边距对元素宽度的影响

    负边距不仅能影响元素在文档流中的位置,还能添加元素的宽度!这个作用能实现的前提是:该元素没有设定width属性(当然auto是能够的)。
    比方下图的绿色部分是一个块状元素,它没有设定宽度。它被包裹在一个宽度为400px。且水平居中的父元素中。

    这里写图片描写叙述

    如今给这个元素的设一个margin-right:-100px;

    这里写图片描写叙述

    我们看到它的宽度的确变长100px;然后再给它设一个margin-left:-100px;

    这里写图片描写叙述

    我们看到它变得更宽了。
    怎么理解呢?子块状元素的宽度设置为auto;或者不设置(默认auto;)的时候,是会依据其margin边界来填充父元素的,若正常设置为margin:100px;那么子元素的宽度必定减小200px;反之若设置margin:-100px;那么其为了正常填充整个父元素其宽度须要添加200px。

    二、应用

    1、左右列固定。中间列自适应布局

    此例适用于左右栏宽度固定。中间栏宽度自适应的布局。因为网页的主体部分一般在中间,非常多网页都须要中间列优先载入。而这样的布局刚好满足此需求。

    CSS:

        body{
            margin: 0;
            padding: 0;
            min-width: 600px;
        }
        .container{
            width: 100%;
            float: left;
        }
        .main{
            margin: 0 210px;
            background-color: #1B6540;
            height: 200px;
        }
        .left,.right{
            float: left;
            width: 200px;
            height: 200px;
            background-color: #4FA46B;
        }
        .left{
            margin-left: -100%;
        }
        .right{
            margin-left: -200px;
        }

    HTML:

        <div class="container">
            <div class="main">
                main
            </div>
        </div>
        <div class="left">
            left
        </div>
        <div class="right">
            right
        </div>

    效果:

    这里写图片描写叙述

    2、去掉列表右边框

    项目中常常会使用浮动列表展示信息。为了美观通常为每一个列表之间设置一定的间距(margin-right),当父元素的宽度固定式,每一行的最右端的li元素的右边距就多余了,去除的方法一般是为最右端的li加入class,设置margin-right:0; 这样的方法须要动态推断为哪些li元素加入class,麻烦!

    。!利用负margin就能够实现以下这样的效果:

    CSS:

        *{
            padding: 0;
            margin: 0;
        }
        ul,li{
            list-style: none;
        }
        .test{
            width: 320px;
            margin: 20px auto;
            background-color: #1B6540;
        }
        .test ul{
            margin-right: -10px;
        }
        .test ul li{
            float: left;
            width: 100px;
            height: 100px;
            background-color: #4FA46B;
            margin-right: 10px;
            margin-bottom: 10px;
        }
        .clearfix:after{
            content: "";
            height: 0;
            display: block;
            clear: both;
        }

    HTML:

        <div class="test clearfix">
            <ul>
               <li>子元素1</li> 
               <li>子元素2</li> 
               <li>子元素3</li> 
               <li>子元素4</li> 
               <li>子元素5</li> 
               <li>子元素6</li> 
            </ul>
        </div>

    效果:

    这里写图片描写叙述

    3、负边距配合绝对定位水平垂直居中

    这个前提条件是已知子元素的宽高。

    这里写图片描写叙述

    CSS:

        .container{
            width: 500px;
            height: 500px;
            margin: 20px auto;
            background-color: #1B6540;
            position: relative;
        }
        .inner{
            width: 200px;
            height: 200px;
            position: absolute;
            left: 50%;
            top: 50%;
            margin-left: -100px;
            margin-top: -100px;
            background-color: #4FA46B;
        }

    HTML:

        <div class="container">
            <div class="inner">
    
            </div>
        </div>

    4、多列等高

    此例关键是给每一个框设置大的底部内边距,然后用数值类似的负外边距消除这个高度。

    这会导致每一列溢出容器元素,假设把外包容器的overflow属性设为hidden,列就在最高点被裁切。
    CSS:

        *{
            padding: 0;
            margin: 0;
        }
        .container{
            overflow: hidden;
            width: 500px;
            margin: 20px auto;
        }
        .left,.mid,.right{
            margin-bottom: -200px;
            padding-bottom: 200px;
        }
        .left {
            float: left;
            width:  100px;
            background: #4FA46B;
        }
        .mid {
            float: left;
            width: 300px;
            background: #1B6540;
        }
        .right {
            float: right;
            width: 100px;
            background: #4FA46B;
        }
        p {color: #FFF;text-align: center}

    HTML:

        <div class="container">
            <div class="left">
                <p style="height:50px">height:50px</p>
            </div>
            <div class="mid">
                <p style="height:100px">height:100px</p>
            </div>
            <div class="right">
                <p style="height:200px">height:200px</p>
            </div>
        </div>

    效果:

    这里写图片描写叙述

    5、去除列表最后一个li元素的border-bottom

    列表中我们常常会加入border-bottom值,最后一个li的border-bottom往往会与外边框重合,视觉上不雅观。往往要移除。

    CSS:

        *{padding: 0;margin: 0;}
        ul,li{list-style: none;}
        .container{
            width: 500px;
            margin: 20px auto;
            background-color: #84D0AA;
            border: 3px solid #FF6798;
            z-index: 999;
            overflow: hidden;
        }
        ul li{
            height: 30px;
            line-height: 30px;
            border-bottom: 1px dotted #fff;
            padding: 5px;
            margin-bottom: -1px;
        }

    HTML:

        <div class="container">
            <ul>
                <li>Test</li>
                <li>Test</li>
                <li>Test</li>
                <li>Test</li>
                <li>Test</li>
            </ul>
        </div>

    效果:

    这里写图片描写叙述

    注意:当中具有边框的父元素假设不加overflow:hidden;会导致出现边框与子元素li标签的边框重叠的情况,例如以下:

    这里写图片描写叙述

    我相信这个微小的瑕疵会逼死无数像我这样的强迫症患者..

    具体资源能够參考:The Definitive Guide to Using Negative Margins
    有什么好的问题或者资源欢迎补充

  • 相关阅读:
    人类思考的基本形式
    晚上睡不者原因
    东西方哲学比较
    逻辑推理的三种方法
    锻炼自己的注意力和逻辑思维能力
    预测和复盘自己的投资策略
    概念:名与实
    没有“界定问题”会出现什么问题
    问题、联系-条条大路通罗马
    程序问题调试与医生、汽车维修师
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7213920.html
Copyright © 2020-2023  润新知