三種方式實現動態元素水平居中

今天臨下班的時候隔壁組的同事拉住我跟我討論一個問題,想要實現的功能以下:javascript

在一個div中有多個水平排列的div,但這些div的寬度不定,而且能夠動態增長或者減小。要求這些div組始終居中排列。如圖:css

看了一下他的代碼,是用浮動來作的,可是全部的div都靠左排列。由於塊下班了,兩我的急急忙忙調試了一下子沒能獲得正確的結果,因而下班後想好好研究一下。最終找到了三種實現的方式,寫出來跟你們一塊兒討論討論。html

嘗試一:使用Float+margin:auto+js
我就沿着他的float思路繼續思考。若是使用float的話,被浮動的元素始終會靠左或者靠右排列,只有將其父元素居中,這些元素纔有可能居中放置。否則的話要動態改動他們的margin-left或者margin-right才能實現效果。
那麼如何實現父元素居中呢,若是是定寬的元素那好辦,直接"margin: 0 auto"就能夠實現。可是這裏的父元素的大小是不固定的,要隨着子元素增減而改變。繼續走下去的辦法只有用JS去控制父元素的寬度。寫了代碼進行實驗,是能夠作到。java

 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-blockchrome

使用JS固然能夠解決這樣的問題,但到底只使用css能不能實現呢,畢竟這應該屬於一個佈局的問題。因而想到了前幾天看的一篇關於inline-block代替float實現瀑布流的文章,就想試試這裏也可否使用inline-block實現這個水平居中的效果。瀏覽器

因而開始查找inline-block的定義和用法:app

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.ide

意思是:inline-block會觸發元素呈現成一個行級別的塊包含對象,這個對象內部的元素呈現成塊級元素,而這個元素自己呈現成行級別的元素。 個人理解是,對與它的父元素以及兄弟元素,它是一個行級別的元素,能夠與其餘行級別元素同行放置;但對於它內部的元素,它是塊級元素,及內部的元素不須要額外的設置來觸發BFC。佈局

通過必定的嘗試和調試,終於在text-align:center的配合下,基本實現了想要的效果:ui

 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%,天然也就能將本身的中心放在總體的中間。也就實現了居中排放的效果。

至此,這個自動水平居中的問題也算完美解決了。技術這種東西,都是取之於民用之於民,但願可以給你們一些幫助,也但願能跟你們一塊兒探討更多的問題。

相關文章
相關標籤/搜索