zoukankan      html  css  js  c++  java
  • 三种方式实现动态元素水平居中

    三种方式实现动态元素水平居中

    今天临下班的时候隔壁组的同事拉住我跟我讨论一个问题,想要实现的功能如下:

    在一个div中有多个水平排列的div,但这些div的宽度不定,并且可以动态增加或者减少。要求这些div组始终居中排列。如图:

    看了一下他的代码,是用浮动来做的,但是所有的div都靠左排列。因为块下班了,两个人急急忙忙调试了一会儿没能得到正确的结果,于是下班后想好好研究一下。最终找到了三种实现的方式,写出来跟大家一起讨论讨论。

    尝试一:使用Float+margin:auto+js
    我就沿着他的float思路继续思考。如果使用float的话,被浮动的元素始终会靠左或者靠右排列,只有将其父元素居中,这些元素才有可能居中放置。不然的话要动态改动他们的margin-left或者margin-right才能实现效果。
    那么如何实现父元素居中呢,如果是定宽的元素那好办,直接"margin: 0 auto"就可以实现。但是这里的父元素的大小是不固定的,要随着子元素增减而改变。继续走下去的办法只有用JS去控制父元素的宽度。写了代码进行实验,是可以做到。

    复制代码
     1 <!DOCTYPE>
     2 <html>
     3     <head>
     4         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     5     <style type="text/css">
     6         #content{
     7             margin: 0 auto; //父元素水平居中
     8             height: 202px;
     9             background-color: lightblue;
    10         }
    11         #content div{
    12             width: 100px;
    13             height: 200px;
    14             float: left; //子元素向左浮动
    15             border: 1px solid blue;
    16             background-color:gray;
    17         }
    18         #toolbar{           
    19             margin: 20px auto;
    20             text-align: center;
    21         }
    22         #footer{
    23             clear: both;
    24         }   
    25     </style>
    26 
    27     <script type="text/javascript">
    28         function doLayout(){
    29             var contentDiv = document.getElementById("content");
    30             var children = contentDiv.children;
    31             var width = 0;
    32             for(var i = 0, l = children.length; i < l; i ++){
    33                 width += children[i].offsetWidth;
    34             }
    35 
    36             contentDiv.style.width = width+"px";
    37         }
    38         function addDiv(){
    39             var contentDiv = document.getElementById("content");
    40             var newDiv = document.createElement("Div");
    41             newDiv.innerHTML = "new added div";
    42             contentDiv.appendChild(newDiv);
    43             doLayout();
    44         }
    45     </script>
    46     
    47     </head>
    48     <body onload="doLayout()">
    49     <div id="page">
    50         <div id="header"><h1>自动水平居中</h1></div>       
    51         <div id="content">
    52             <div id="div1">                    
    53                 <p>13123</p>
    54                 <span>13123</span>
    55             </div>
    56             <div id="div2">                    
    57                 <a href="#">13123</a>
    58                 <p>13123</p>
    59                 <span>13123</span>
    60             </div>
    61         </div>       
    62         <div id="toolbar">
    63             <input type="button" value="Add Float Div" onClick="addDiv()"/>
    64         </div>
    65         <div id="footer">
    66             <p>没人关注的页脚</P>
    67         </div>
    68     </div>
    69     </body>
    70 </html>
    复制代码

    尝试二:使用inline-block

    使用JS当然可以解决这样的问题,但到底只使用css能不能实现呢,毕竟这应该属于一个布局的问题。于是想到了前几天看的一篇关于inline-block代替float实现瀑布流的文章,就想试试这里也能否使用inline-block实现这个水平居中的效果。

    于是开始查找inline-block的定义和用法:

    inline-block:This value causes an element to generate an inline-level block container. The inside of an inline-block is formatted as a block box, and the element itself is formatted as an atomic inline-level box.

    意思是:inline-block会触发元素呈现成一个行级别的块包含对象,这个对象内部的元素呈现成块级元素,而这个元素本身呈现成行级别的元素。 我的理解是,对与它的父元素以及兄弟元素,它是一个行级别的元素,可以与其他行级别元素同行放置;但对于它内部的元素,它是块级元素,及内部的元素不需要额外的设置来触发BFC。

    经过一定的尝试和调试,终于在text-align:center的配合下,基本实现了想要的效果:

    复制代码
     1 <!DOCTYPE>
     2 <html>
     3     <head>
     4         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     5     <style type="text/css">
     6         #content{
     7             text-align:center; //内部元素居中
     8             height: 200px;
     9             background-color: lightblue;
    10         }
    11         #content div{
    12             width: 100px;
    13             height: 200px;
    14             display:inline-block;
    15             border: 1px solid blue;
    16             background-color:gray;
    17         }
    18         #toolbar{           
    19             margin: 20px auto;
    20             text-align: center;
    21         }
    22         #footer{
    23             clear: both;
    24         }   
    25     </style>
    26 
    27     <script type="text/javascript">
    28         function addDiv(){
    29             var contentDiv = document.getElementById("content");
    30             var newDiv = document.createElement("Div");
    31             contentDiv.appendChild(newDiv);
    32         }
    33     </script>
    34     </head>
    35     <body>
    36     <div id="page">
    37         <div id="header"><h1>自动水平居中</h1></div>
    38 
    39         <div id="content">
    40             <div id="div1"> 
    41             </div>
    42             <div id="div2"> 
    43             </div>
    44         </div>
    45        
    46         <div id="toolbar">
    47             <input type="button" value="Add Float Div" onClick="addDiv()"/>
    48         </div>
    49         <div id="footer">
    50             <p>没人关注的页脚</P>
    51         </div>
    52     </div>
    53     </body>
    54 </html>
    复制代码

    但是在尝试放入了一些块级元素到各个div中的时候,发现当内部元素高度不一样的时候,各个块的排列就不能对齐了:

    这可能就是内部的块级元素产生了换行的原因吧,但是也不能确定,有时间仔细研究一下,也希望知道的高手能指点一下。

    但是我还是找到了解决的办法,就是vertical-align,在设置成top之后,每个元素内部都从顶端开始排布,所以也就能对齐了。

    复制代码
     1 <!DOCTYPE>
     2 <html>
     3     <head>
     4         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     5     <style type="text/css">
     6         #content{
     7             text-align:center;
     8             height: 202px;
     9             background-color: lightblue;
    10         }
    11         #content div{
    12             width: 100px;
    13             height: 200px;
    14             display:inline-block;
    15             border: 1px solid blue;
    16             vertical-align: top;
    17             background-color:gray;
    18         }
    19         #toolbar{           
    20             margin: 20px auto;
    21             text-align: center;
    22         }
    23         #footer{
    24             clear: both;
    25         }   
    26     </style>
    27 
    28     <script type="text/javascript">
    29         function addDiv(){
    30             var contentDiv = document.getElementById("content");
    31             var newDiv = document.createElement("Div");
    32             newDiv.innerHTML = "new added div";
    33             contentDiv.appendChild(newDiv);
    34         }
    35     </script>
    36     </head>
    37     <body>
    38     <div id="page">
    39         <div id="header"><h1>自动水平居中</h1></div>
    40        
    41             <div id="content">
    42                 <div id="div1">                    
    43                     <p>13123</p>
    44                     <span>13123</span>
    45                 </div>
    46                 <div id="div2">                    
    47                     <a href="#">13123</a>
    48                     <p>13123</p>
    49                     <span>13123</span>
    50                 </div>
    51             </div>
    52        
    53         <div id="toolbar">
    54             <input type="button" value="Add Float Div" onClick="addDiv()"/>
    55         </div>
    56         <div id="footer">
    57             <p>没人关注的页脚</P>
    58         </div>
    59     </div>
    60     </body>
    61 </html>
    复制代码

    至此,使用inline-block顺利解决了问题。但是在查阅资料的时候都说inline-block有浏览器兼容的问题,自己在chrome,firefox和IE10试了之后都没发现问题。也算是一种解决方案吧。

    尝试三:使用position:relative实现

    在查阅水平居中的过程当中,还看到有同学说可以使用position:relative加上float来实现,于是也尝试了一下。确实也是可以的:

    复制代码
     1 <!DOCTYPE>
     2 <html>
     3     <head>
     4         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     5     <style type="text/css">
     6         #content{
     7             float: left;
     8             position:relative;
     9             left: 50%;//父元素相对左50%
    10             height: 202px;
    11         }
    12         #content div{ 
    13             float: left;
    14             position:relative;
    15             right: 50%;//子元素相对右50% 这里写成left:-50%也能工作
    16             width: 100px;
    17             height: 200px;
    18             border: 1px solid blue;
    19             background-color:gray;
    20         }
    21         #toolbar{         
    22             clear:both;  
    23             margin: 20px auto;
    24             text-align: center;
    25         }
    26         #footer{
    27             clear: both;
    28         }   
    29     </style>
    30 
    31     <script type="text/javascript">
    32         function addDiv(){
    33             var contentDiv = document.getElementById("content");
    34             var newDiv = document.createElement("Div");
    35             newDiv.innerHTML = "new added div";
    36             contentDiv.appendChild(newDiv);
    37         }
    38     </script>
    39     </head>
    40     <body>
    41     <div id="page">
    42         <div id="header"><h1>自动水平居中</h1></div>
    43        
    44             <div id="content">
    45                 <div id="div1">                    
    46                     <p>13123</p>
    47                     <span>13123</span>
    48                 </div>
    49                 <div id="div2">                    
    50                     <a href="#">13123</a>
    51                     <p>13123</p>
    52                     <span>13123</span>
    53                 </div>
    54             </div>
    55        
    56         <div id="toolbar">
    57             <input type="button" value="Add Float Div" onClick="addDiv()"/>
    58         </div>
    59         <div id="footer">
    60             <p>没人关注的页脚</P>
    61         </div>
    62     </div>
    63     </body>
    64 </html>
    复制代码

    这里先普及一下polistion:relative的概念:
    relative :  对象不可层叠,但将依据left,right,top,bottom等属性在正常文档流中偏移位置。
    这个解释与一般的理解有点偏差,我最开始的时候也是理解成相对定位,以为是相对父节点的,但实际上相对的是正常情况下自己的位置。所以也就很容易解释,代码中的父节点相对其父节点向右移动50%后它的开始就正好在正中间,然后子元素都相对自身向左偏移50%,自然也就能将自己的中心放在整体的中间。也就实现了居中排放的效果。

    至此,这个自动水平居中的问题也算完美解决了。技术这种东西,都是取之于民用之于民,希望能够给大家一些帮助,也希望能跟大家一起探讨更多的问题。

     
     
    分类: Web开发CSS
    标签: CSS水平居中动态
  • 相关阅读:
    2018 ACM 网络选拔赛 徐州赛区
    2018 ACM 网络选拔赛 焦作赛区
    2018 ACM 网络选拔赛 沈阳赛区
    poj 2289 网络流 and 二分查找
    poj 2446 二分图最大匹配
    poj 1469 二分图最大匹配
    poj 3249 拓扑排序 and 动态规划
    poj 3687 拓扑排序
    poj 2585 拓扑排序
    poj 1094 拓扑排序
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3229666.html
Copyright © 2011-2022 走看看