時間選擇器元件之關於table走過的彎路
為了提高開發者的研發效率,提升產品品質,我們提供一套基於餓了麼UI實現的UI元件庫,TMAP-UI---旨在解決的元件地圖場景下應用的問題。
最近在新增TMAP-UI
元件庫的開發過程中,時間選擇器是開發者反饋需求較多的一個元件,今天把在開發過程中遇到的一些問題分析給大家。element-ui
有原生的時間選擇器,但是,在我們的互動設計師是根據地圖實際應用場景中的特性抽象元件,element-ui
的樣式以及互動操作都無法滿足設計需求,需要基於原始碼進行二次開發,最小成本實現這個通用元件。今天主要聊下開發中遇到的一些關於table的實現問題,對table一探究竟…
關於table特點
首先,我們先來基本瞭解一下table
<table> <caption>A summary of the UK's most famous punk bands</caption> <thead> <tr> <th scope="col" class="fixed-width-test2">Band</th> </tr> </thead> <tbody> <tr> <th scope="row">Buzzcocks</th> <td>1976</td> <td>9</td> <td>Ever fallen in love (with someone you shouldn't've)</td> </tr> </tbody> </table>
一個基本的table佈局主要由table
、tbody
、th
、td
等標籤組成。W3C標準中,table的每個標籤都自帶了display
樣式。例如td標籤預設就會有display:table-cell
的樣式,在這個預設樣式下,新增margin的設定是不會生效的。更詳細標籤對應樣式可以檢視W3C標準。
關於時間選擇器
時間選擇器設計圖
根據上圖為設計師給出的時間選擇器的設計圖,選擇時間範圍是一個重要的新增功能。
實現它的步驟拆分成以下幾步:
-
1.實現基本表格佈局
-
2.新增日期範圍選擇的樣式
實現基本表格佈局
首先我們需要按照設計圖調整日期間的間距和每個日期的單元格大小。所以,需要對於每個子格設定寬、高和margin
從上圖左側可以看出,樣式在style成功設定的情況下,右側盒模型的寬和margin
都沒有生效。
我首先猜測是不是哪裡的樣式壓蓋了,又或者是樣式本身因為某些原因導致沒有生效。
於是使用常用的樣式壓蓋方法,在沒生效的樣式後新增!important
來提高設定樣式的優先順序,但還是沒有生效。
後來查了W3C的關於table的設定說明,發現了上文提到的td自帶的display:table-cell
樣式。於是嘗試在樣式中新增display:block
替代原有table自帶樣式。果然當我設定之後,子td的寬高和margin都生效了。
查閱資料之後發現,一方面td標籤不允許設定margin
,另一方面,在table整體的寬度設定後,樣式不會按照td標籤中設定的寬度執行,會按照整體的table寬度均分給每一個子td。如果希望一些特殊的效果,對寬度設定百分比是可以生效的。這其實能夠理解,如果在table-cell
的模式下允許某個子模組設定寬度和margin
,會導致子模組的寬度和高度不可預期,對同一行的其他子塊的寬高造成影響。總結下,為了保證table的樣式整體聯動性,table寬高和子td的寬高設定不能同時使用絕對數值來設定,只能設定其中一個絕對值,另外一個用相對值來計算劃分。
如果我們通過display:block
完成格式,整體的表格結構就會被打破,產生更多不符合表格邏輯預期的樣式問題。於是我們通過每個子單元格均分的特性,設定總的行寬和行高來控制單元格自身的大小和之間的距離,從而達到實現整體表格佈局的效果。
新增日期範圍和選擇樣式
-
盒子寬度問題
那當我們hover態的盒子和背景顏色的盒子大小不一樣的時候,我們就需要在td的內部內建一個盒子。這樣通過設定顏色我們就可以實現背景。按照上述,只要我們設定好整體的table寬度和背景顏色,就可以得到日期選中範圍的設計背景效果,對應的背景顏色得到如下結果。
設定整體寬度之後,我們發現部分子td之間存在一條深色的邊界線。這是由於他們之間出現了互相壓蓋,整體的七個td的總寬度設計稿給出是242px,按照預期是應該七個子模組均分寬度。但我檢視具體每個子td的寬度發現,有的子td寬度是34、有的是35。這也就是說,在寬度不能夠被子模組整除均分的情況下,table自動為我們做了取整,並且為了保持總寬度的不便,有些被向下取整,有些被向上取整。
目前想到的解決辦法是,通過計算固定寬度的總寬度使得每一個td能夠被整除。
-
選中態背景問題
接下來,我們需要解決在選中態下起終點日期的樣式問題。按照原有的選中樣式無論是否新增背景都不能滿足需求。見下圖,會出現10號日期右側空白或26號日期多餘背景的情況。
對於起始日期,要完成上述要求,我們需要將起始框以及它的右側作為塊內容並且仍能保證水平居中。解決辦法是,對於10號日期的選擇起點,將左側設定margin
,右側設定相應寬度的padding
。
做到這裡基本可以認為完成了一個日期範圍選擇功能。
但實戰發現,還沒完......
當用戶只選擇了起點我們會發現選中態導致右側的邊界還會有藍色背景色。於是,我們還要利用scss的語法特性為樣式設定生效條件來區分兩種不同的顯示策略。
-
border-radius問題
設計稿要求,每一行的選擇框的起始和末尾需要有圓角。這樣一個常見的需求,table果然沒讓我失望,對tr標籤設定無效。原因是因為在border-collapse
設定為separate
下,對於所有table標籤設定圓角都無法生效。
查閱資料,找到了兩種思路的解決方法。
第一種就是對tr的子td, first-child/last-child
設定圓角。講到這裡就不得不提table的一個屬性:border-collapse
。這個屬性用來決定表格的邊框是分開的還是合併的。在分隔模式下,相鄰的單元格都擁有獨立的邊框。在合併模式下,相鄰單元格共享邊框。這裡有三個常用值:inherit
, separate
,collapse
。separate
表示每個單元格擁有獨立的邊框,inherit表示相鄰的單元格共用同一條邊框。
當在separate模式下,我們還可以通過設定border-spacing設定邊框的寬度。
w3c border-spacing配圖
第二種當設定border-collapse:inherit
,便可以設定td和tr的圓角了。
總結
在table佈局下,有許多自己樣式佈局,在我們熟練掌握了之後會發現有很多方便的特性。我也把這次遇到的問題沉澱成了表格,希望能對大家以後的開發有點幫助,少走彎路。
產品推廣
地圖元件是專為移動端定製的輕應用產品,支援各手機端主流瀏覽器,可以實現位置展示、路線規劃、地圖選點、前端定位等多種場景的下的呼叫。相比於JS API, 可以通過高度引數化的URL直接呼叫,極大簡化開發的複雜度,降低維護成本。歡迎大家體驗!