css-深入理解margin和padding

最近一阶段从新学习了css,发现真的有很多很多的地方都是空白的,今天我们来总结一下margin和padding的一些不为人知的秘密!

一利用float和margin实现布局

我们首先来实现一个两列示布局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        div{
            width: 100px;
            height: 100px;
            float: right;
            background: red;
        }
        p{
            margin-right: 110px;
        }
    </style>
</head>
<body>
    <div>hello</div>
    <p>你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好</p>
</body>
</html>

大概的效果是这样的

随着我们整体的width不断改变p标签自动适应,这个也是我们最长用的两列布局或三列布局的原理。

然后如果我们有这种需求,我们需要这种布局(如图):

 

那么我们一般怎么做呢?我们可能会把所有的li都加上margin-left然后我们在吧第一个li加上margin负给拉回来,这样子来实现布局,但是这种方法有很多很多的问题,我们如果元素不是三个,变成四个或更多,我们就需要每一个都添加margin负拉回来,所以这种方法并不可取,我们来看下面这段代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div{
            width: 1200px;
            background: #eee;
            margin: auto;
        }
        ul{
            overflow: hidden;
            padding:0; 
            margin-right: -20px;
        }
        li{
            height: 200px;
            width: 386.66px;
            margin-right: 20px;
            list-style:none;
            background: red;
            float: left;
        }
    </style>
</head>
<body>
    <div class='div'>
        <ul>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
</body>
</html>

我们可以通过设置ul的overflow:hidden;然后margin-right负来控制容器,这样达到li不换行实现布局,其实做后一个li的margin被ul拉回来了

这门来做一个测试,我们给所有的li加一个border,之后添加li的数量

border:1px solid #000;
box-sizing: border-box;

注意,一定要添加第二行代码限制width,然后多出的1px的border会把你的width撑开,这样子你的container就会因为比内部小于6px的大小使每行第三个li下去!

效果如下:

这样我们就能够得到我们想要的布局啦,撒花!!!

有的时候我们会遇到一些需要水平垂直居中的场景,必须做一个类似alert弹框提醒之类的,我们需要水平垂直居中

说到居中,我们第一的反应一定是定位,之后我们top,left为50%然后margin负,这种方法也是大家比较熟悉的,但是唯一的问题就是我们需要知道元素的高和宽改改变元素的margin负,这个也是这种方法的唯一弊端,下面我们用margin:auto来实现元素居中。

代码如下:

<!DOCTYPE html>
<html>
<head>
    <style>
        span{
            position: absolute;
            width: 200px;
            height: 200px;
            left: 0;
            top: 0;
            bottom: 0;
            right: 0;
            margin:auto;
            background: red;
        }
    </style>
</head>
<body>
    <span class='span'></span>
</body>
</html>

 

这样我们就可以不需要元素的width和height的具体来改变margin负,而用margin:auto来实现了布局。

如果你不明白这种实现原理,建议去看看盒模型!

二margin重叠问题

首先我们知道margin重叠只发生在block元素上(不考虑float和absolute),其次父元素和子元素重叠的时候父元素没有设置border-top或者padding-top。

最后还有一个比较少见的就是我们的父元素和子元素的第一个元素不存在inline元素分隔。

注:margin-bottom的条件多一条就是父元素并没有设置height

下面我们来

    <div class='father' >
        <div class='son'>hello</div>
    </div>
        .father{
            background: red;
        }
     .son{
       margin-top:80px;
}

我们得到这样的效果

我们给父元素添加了背景元素,子元素margin:80px,但是我们并没有看到子元素margin,效果就像是给父元素margin一样,我们来改变style样式

     .father{
            background: red;
            margin-top: 80px;
        }
        .son{
            
        }
     .father{
            background: red;
            margin-top: 80px;
        }
        .son{
            margin-top: 80px;
        }

我们发现效果是一样的,我们得到结论,因为发生了margin合并,所以失效,那么我们怎么才能得到我们想要的子元素margin效果呢?

我们只需要给父元素添加border-top:1px solid #fff;我们得到效果如下

 

这样我们就得到了我们想要的效果了!,那么这个margin合并对于我们开发有什么用?

我们常规开发表单的时候,我们习惯的是把出了第一个元素的所有元素都添加margin-top: 20px ,但是这种做法并不是太好,因为我们都知道数据基本上都是从后台查出来的,我们并不知道会有多少条出局,可能空数据或者数据量过多就会造成布局变乱,footer紧贴input的样式发生,那么我们就可以使用margin合并来解决这个问题:

      .input{
            margin-top: 30px;
            margin-bottom: 30px;
        }

我们把所有的li添加class为input,我们利用margin合并实现两个li间距只30px的间距,这样就解决了这个问题!

下面我们来说一下padding

首先我们说一下inline元素的padding,inline元素的padding会改变元素的width,height不会改变,但是会改变元素的背景颜色。什么意思呢?我们来看下面的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .span{
            padding: 0px;
        }
        .div{
            padding: 20%;
            border:1px solid #000;
        }
        .div span{
            display: block;
            width: 100px;
            height: 100px;
            float: left;
            background: red;
        }
    </style>
</head>
<body>
    <p>hello</p>
    <span>
        <span>123</span>
        <span class='span'>hello</span>
        <span>123</span>
    </span>
</body>
</html>

效果如下:

 

然后我们改变.span的padding

padding: 100px;

 

随着我们inline元素的padding改变,我们发现元素的height并没有撑开而是把上面的hello覆盖了。

结下来我们来利用padding来实现两个效果图:

有时候我们想实现最下面的效果,但是我们用|只能够实现最上面的效果:不多说直接上代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        span{
            padding: 10px 6px 0px;
            border-left: 2px solid #000;
            margin-left: 12px;
            font-size: 0;
        }
    </style>
</head>
<body>
    <div>登录|退出</div>
    <div>注册 登录</div>
    <div>注册<span></span>登录</div>
</body>
</html>

这样我们利用span标签就能实现分隔符号了,那么我们用padding还能实现什么呢?

我们常常有一些简单的样式,如果用图片可能会多多少少影响加载性能,虽然性能不是很大,但是如果我们能用css实现的话何乐而不为呢?

我们实现一个这样的效果图:

其实还是比较简单的,我们直接上代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .span{
            width: 150px;
            height: 30px;
            padding: 15px 0;
            border-top: 30px solid;
            border-bottom: 30px solid;
            background-color: currentColor;
            background-clip: content-box; 
        }
    </style>
</head>
<body>
    <div class='span'></div>
</body>
</html>

 

 这样我们就实现了最基本的padding来写一些简单的button!

 

posted @ 2016-10-18 10:47  JcScript  阅读(620)  评论(6编辑  收藏  举报