工做中遇到的特殊CSS佈局

平常開發中,設計師總會提出各類奇思妙想的需求,爲咱們的UI還原工做帶來不少挑戰。雖然有時確實會讓咱們花蠻多時間去實現,但從一方面想這也是個機會,讓咱們更深刻了解的瀏覽器佈局方式。本文主要記錄以前工做中遇到的特殊佈局,都是經過CSS方式去實現。瀏覽器

多條件留白布局

圖中有兩個內容塊A和B,他們寬度取決於內容寬度,左右側留白有max-width: 200px限制,中間留白有min-width: 150px限制。若是父級寬度縮小,中間留白一直保持着150px寬度,左右側留白寬度跟隨父級寬度縮小。以下圖所示:bash

從需求的描述來看,須要的是同時支持彈性(寬度隨父級寬度而改變)和限制條件(max-width、min-width)的屬性。一提起彈性,天然而然的就想到flex佈局,只要加入佔位的元素,可以使用beforeafter僞類或手動插入元素,而後加上flex: 1和限制條件便可。佈局

在線預覽:性能

codesandbox 地址字體

代碼:flex

<style>
.container {
    display: flex;    
}

// 左右側留白
.left,
.right {
    flex: 1;
    max-width: 200px;
}

// 中間留白
.center {
    flex: 1;
    min-width: 150px;
}
</style>
複製代碼
<div class="container">
    <div class="left"></div>
    <div>Content A</div>
    <div class="center"></div>
    <div>Content B</div>
    <div class="right"></div>
</div>
複製代碼

中間文本截斷

需求:對於文件名,在頁面中必定要顯示文件擴展名,非擴展名部分溢出時顯示省略號。spa

短文件名:設計

長文件名:code

首先須要使用JS對文件名進行裁剪,拆分出兩部分:非擴展名部分和擴展名部分,放置在兩個相鄰的元素中。當文件名寬度 <= 父級寬度時,左側元素和右側元素寬度爲各自內部文字寬度。當文件名寬度 > 父級寬度時,左側元素寬度取決於內容,達到最大值後文本截斷顯示縮略號,右側元素隨左側元素向右移,一直保持自身寬度不縮放。cdn

對於這樣的問題,很天然的就想到flex-shrinkflex-shrink用來設置當父元素的寬度小於全部子元素的寬度的和時(即子元素會超出父元素),子元素如何縮小本身的寬度。

在線預覽:

codesandbox 地址

代碼:

<style>
.container {
    display: flex;
}

.left {
    flex-shrink: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.right {
    white-space: nowrap;
}
</style>
複製代碼
<div class="row">
    <span class="left">超長的文件名超長的文件名超長的文件名超長的文件名</span>
    <span class="right">.jpeg</span>
</div>
複製代碼

這個方法有個瑕疵,就是縮略符與右側字符存在必定空隙,不過字體小的時候不太明顯。使用JS能解決這個問題,可是用JS實現須要計算字符所佔寬度。由於字符的寬度不一致,不能使用字體大小*字體長度的方式,須要將字符插入一個元素,而後獲取元素的寬度。對於一個長列表來講,這個方式太耗性能。權衡利弊之下,因此選擇flex去實現。

豎向排列

需求:實現相似於下圖中豎向排列的佈局,父元素高度限定,寬度取決於子元素,子元素寬高取決於內容,子元素從上到下,從左到右排序。

一開始想着使用flex-flow: column wrap能快速實現,但事宜願爲,順帶發現了flex佈局的缺點。我給父級元素加了border,從而能夠看出父元素的寬度。

設置了flex-flow: column wrap;align-content: flex-start;後,父元素寬度仍然是百分百,但需求是寬度取決於子元素寬度,這時須要再加個display: inline-block元素。

加了inline-block元素後,父元素的寬度只等於一列子元素的寬度,明顯不符合預期。若是不使用display: flex,而使用display: inline-flex呢?

同樣的效果,看來flex對於此類佈局仍是略遜一籌,這時就須要用到不少人平時不太注意的屬性wirte-mode了。wirte-mode屬性定義了文本水平或垂直排布以及在塊級元素中文本的行進方向。

MDN文檔:write-mode

效果:

在線預覽:

codesandbox 地址

代碼:

<style>
.list {
    display: inline-block;
    height: 200px;
    font-size: 0;
    writing-mode: vertical-lr;
}

.item {
    display: inline-block;
    margin: 5px 5px;
    width: 150px;
    height: 40px;
    line-height: 40px;
    border-radius: 4px;
    font-size: 14px;
    text-align: center;
    color: #fff;
    background: #00a0e9;
    list-style: none;
    writing-mode: horizontal-tb;
}

.item:nth-child(2),
.item:nth-child(10) {
    height: 90px;
    line-height: 90px;
}
</style>
複製代碼
<ul class="list">
    <li class="item">1</li>
    <li class="item">2</li>
    <li class="item">3</li>
    <li class="item">4</li>
    <li class="item">5</li>
    <li class="item">6</li>
    <li class="item">7</li>
    <li class="item">8</li>
    <li class="item">9</li>
    <li class="item">10</li>
    <li class="item">11</li>
    <li class="item">12</li>
</ul>
複製代碼
相關文章
相關標籤/搜索