由於項目需求,需要在頁面中畫出一套蜂巢排版格式的列表。在經過網上的一番查閱資料,發現大多六邊形的畫法都是通過div覆蓋由旋轉的菱形遮掩為六邊形。這種六邊形雖然可以滿足一些基本的需求,但我暫時沒有想到如何滿足我想要的邊框動態效果。最後尋覓下發現了一款適合的樣式,在此基礎上做出樣式方面的改動,變為符合我 ...
由於項目需求,需要在頁面中畫出一套蜂巢排版格式的列表。在經過網上的一番查閱資料,發現大多六邊形的畫法都是通過div覆蓋由旋轉的菱形遮掩為六邊形。這種六邊形雖然可以滿足一些基本的需求,但我暫時沒有想到如何滿足我想要的邊框動態效果。最後尋覓下發現了一款適合的樣式,在此基礎上做出樣式方面的改動,變為符合我需求的蜂巢列表。作為一個前端新手,內容如有錯誤請多指正,謝謝大家。
參考地址:https://wow.techbrood.com/fiddle/13533
這裡主要是通過 svg 的 <path> 標簽去繪製邊框路徑,然後使用 <text> 插入單行文本,使用 <foreignObject> 插入可換行文本。
1.通過svg的x y width height四個參數構建svg實際占據的面積和位置。比如
<svg x="0" y="0" height="100%" width="100%">
就是占據了外層 <li> 的全部面積,這樣做的好處是可以後續通過控制 <li> 的大小來直接控制svg的整體大小,也可以寫具體的px來定位位置。
2.通過svg的viewBox屬性來設置內部的具體尺寸比例。比如
<li class="hex"> <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%"> <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" /> <text class="time" x='104' y='60' style='dominant-baseline:middle;text-anchor:middle;'> 10h </text> <foreignObject x='4' y='80' width="200" height="85"> <p class="title">abc-activiti-server</p> </foreignObject> <text class="num" x='104' y='180' style='dominant-baseline:middle;text-anchor:middle;'> 1個實例 </text> </svg> </li>
這裡的viewBox=“0 0 208 240”說白了其實就是從svg的最左上(0,0)坐標的位置到最右下(208,240)坐標的,內部橫向劃分207次縱向劃分239次的一個網格狀區域。這樣當我們想要將svg的任意子組件設置位置時,只需要給與指定的x y 即可。同時 <path> 的d屬性也是通過這個網格區域來定位描點位置的。
3.通過 <path> 的d屬性來進行邊框描繪。d屬性的寫法有多種,不必糾結於某種寫法,能實現即可。比如本次實現我使用的是 d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" 即M代表開始,每一個x,y代表一個點,預設是直線連接,最後Z結尾,會自動形成閉環路徑。
4.通過 <text> 寫一些簡短的問題,其中行內樣式 dominant-baseline 設置文本垂直居中, text-anchor 設置文本水平居中。過長的文本不會換行,所以要使用下麵這個標簽。
5.通過 <foreignObject> 嵌入XHTML元素,用以防止較長的文本內容,對標簽設置了寬高後,內部元素可進行換行。
html代碼部分
<ul> <li class="hex"> <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%"> <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" /> <text class="time" x='104' y='60' style='dominant-baseline:middle;text-anchor:middle;'> 10h </text> <foreignObject x='4' y='80' width="200" height="85"> <p class="title">abc-activiti-server</p> </foreignObject> <text class="num" x='104' y='180' style='dominant-baseline:middle;text-anchor:middle;'> 1個實例 </text> </svg> </li> <li class="hex"> <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%"> <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" /> </svg> </li> <li class="hex"> <svg class="red" x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%"> <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" /> </svg> </li> <li class="hex"> <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%"> <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" /> </svg> </li> <li class="hex"> <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%"> <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" /> </svg> </li> <li class="hex"> <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%"> <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" /> </svg> </li> <li class="hex"> <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%"> <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" /> </svg> </li> <li class="hex"> <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%"> <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" /> </svg> </li> <li class="hex"> <svg class="yellow" x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%"> <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" /> </svg> </li> <li class="hex"> <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%"> <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" /> </svg> </li> <ul>View Code
然後就是css部分,裡面用到的不常見樣式的具體用法做了簡單的文字描述,不太明白的可以嘗試百度一下,大多都有專門的圖文描述,這裡就不再做贅述了
ul,p { margin: 0; padding: 0; } ul { list-style: none; border: 1px solid #333333; overflow: hidden; } li.hex { float: left; font-size: 20px; } svg { width: 100%; color: #3bc292; } svg path { fill: transparent; /* 內部透明填充色 */ stroke: #3bc292; /* 邊框色 */ stroke-width: 6; /* 邊框寬度 */ stroke-linecap: round; /* 描邊端點表現形式 */ stroke-linejoin: round; /* 描邊轉角的表現方式 */ stroke-miterlimit: 4; stroke-dasharray: 20; /* 創建虛線,20px實線,20px虛線重覆 */ animation: dash 5s linear infinite; /* 動畫名 每次速度 勻速 無限次 */ transition: 0.3s; -moz-transition: 0.3s; /* Firefox 4 */ -webkit-transition: 0.3s; /* Safari 和 Chrome */ -o-transition: 0.3s; /* Opera */ } svg text { fill: #3bc292; /* 文本填充色 */ transition: 0.3s; -moz-transition: 0.3s; /* Firefox 4 */ -webkit-transition: 0.3s; /* Safari 和 Chrome */ -o-transition: 0.3s; /* Opera */ } svg text.time { font-size: 0.8em; } svg p.title { text-align: center; font-size: 1.5em; transition: 0.3s; -moz-transition: 0.3s; /* Firefox 4 */ -webkit-transition: 0.3s; /* Safari 和 Chrome */ -o-transition: 0.3s; /* Opera */ } svg text.num { font-size: 0.8em; } svg:hover path { stroke: #3bc292; fill: #69c2a3; } svg:hover text, svg:hover p.title { fill: #ffffff; color: #ffffff; } svg.red path { stroke: #f56f6f; animation-play-state: paused; } svg.red:hover path { fill: #f56f6f; } svg.yellow path { stroke: #f5b140; animation-play-state: paused; } svg.yellow:hover path { fill: #f5b140; } @keyframes dash { to { stroke-dashoffset: 120; /* 虛線在原路徑下的偏移量 */ } } /*** SPACING AND SIZING *****************************************************************/ @media (min-width: 1401px) { .hex { width: 12.5%; margin: 0 0.5%; } .hex:nth-child(13n+1) { margin-left: 2.5%; } .hex:nth-child(13n+8),.hex:nth-child(13n+9),.hex:nth-child(13n+10),.hex:nth-child(13n+11),.hex:nth-child(13n+12),.hex:nth-child(13n+13) { margin-top: -3%; margin-bottom: -3%; } .hex:nth-child(13n+8) { margin-left: 9.25%; } } @media (max-width: 1400px) and (min-width: 1201px){ .hex { width: 15%; margin: 0 0.5%; } .hex:nth-child(11n+1) { margin-left: 2.5%; } .hex:nth-child(11n+7),.hex:nth-child(11n+8),.hex:nth-child(11n+9),.hex:nth-child(11n+10),.hex:nth-child(11n+11) { margin-top: -3.6%; margin-bottom: -3.6%; } .hex:nth-child(11n+7) { margin-left: 10.5%; } } @media (max-width: 1200px) and (min-width: 901px){ .hex { width: 19%; margin: 0 0.3%; } .hex:nth-child(9n+1) { margin-left: 1%; } .hex:nth-child(9n+6),.hex:nth-child(9n+7),.hex:nth-child(9n+8),.hex:nth-child(9n+9) { margin-top: -4.6%; margin-bottom: -4.6%; } .hex:nth-child(9n+6) { margin-left: 10.5%; } } @media (max-width: 900px) and (min-width: 601px) { .hex { width: 24%; margin: 0 0.3%; } .hex:nth-child(7n+1) { margin-left: 0.8%; } .hex:nth-child(7n+5),.hex:nth-child(7n+6),.hex:nth-child(7n+7) { margin-top: -6%; margin-bottom: -6%; } .hex:nth-child(7n+5) { margin-left: 13.1%; } } @media (max-width: 600px) { .hex { width: 30%; margin: 0 1%; } .hex:nth-child(5n+1) { margin-left: 3%; } .hex:nth-child(5n+4),.hex:nth-child(5n+5) { margin-top: -6.5%; margin-bottom: -6.5%; } .hex:nth-child(5n+4) { margin-left: 19%; } }View Code