轉眼間,2019年還有不到12個小時就要完全過去,回顧本身這一年來,收穫與失落並存。在這最後時刻,發一篇文章送給社區,也送給本身。css
本文摘自這一年來本身在工做中經歷的幾個比較好的CSS問題(不必定複雜,但我的以爲都挺值得一說),這些CSS問題平時不多遇到,即便遇到後也不必定知道解決方案,即便知道解決方案也不必定知道產生的原理,同時也準備了2個JS問題(以前有整理過一篇較長的JS問題文章,在此不作推新)。本文會更新下去,但願幫到各位朋友。期待您的點贊,謝謝。html
input
標籤元素(如button
、text
、areatext
)的一些事件(如click
、focus
等),在不少瀏覽器下默認會有藍色邊框出現,如把一個普通button
的background
和border
都設置爲none
後,觸發點擊後樣式以下:前端
這是由元素默認的輪廓線產生的,這是瀏覽器的一種防禦機制,起到突出元素的做用,把它幹掉就好了,方法以下:web
// 方法1:
outline: none / medium;
// 方法2:
outline-width: 0
複製代碼
咱們一般是使用 opacity
來作背景的透明化處理,該屬性被全部瀏覽器支持,能夠大膽使用,透明度從0.0(徹底透明)到1.0(徹底不透明),但該方法會使其全部子元素都透明,此時若只想讓背景透明,其餘不透明,則可使用rgba
處理背景:chrome
background-color: rgba( red , green , blue , alpha )
複製代碼
其中這個alpha
即設置透明度,取值在0~1之間。該方法除IE9如下不可用外,其餘瀏覽器都可用,看一下效果: 瀏覽器
同理,咱們也能夠用這個方法把整個背景作透明瞭,即多寫一個div
做爲modal層作透明處理,能夠明顯看到上面文字並未透明:安全
上述種效果代碼以下:bash
// html
<section>
<div class="item-pic">
<header class="header1">
<h4>你會微笑放手,說好不哭讓我出新專輯</h4>
</header>
</div>
<div class="item-pic">
<header class="header2">
<h4>你會微笑放手,說好不哭讓我出新專輯</h4>
</header>
</div>
<div class="item-pic">
<div class="handle-opacity"> <!-- 透明罩 -->
<header>
<h4>你會微笑放手,說好不哭讓我出新專輯</h4>
</header>
</div>
</div>
</section>
<style lang="less">
.header1 {
opacity: .6;
}
.header2 {
background-color: rgba(0, 0, 0, 0.45);
}
.handle-opacity {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.45);
header {
background-color: rgba(0, 0, 0, 0.45);
}
}
</style>
複製代碼
用一個div
包裹一個img
,會出現img
不能徹底覆蓋div
空間,總會在底邊留下一點空隙。less
這種現象產生的緣由是img
是行內元素,瀏覽器爲下行字符(如:g、y、j、p、q)留下的一些空間,這些字符是會比其餘字符多佔據底部一些空間(具體以當前字體大小有關),這種規則會影響行內元素img
標籤(其默認垂直對齊方式是依照基線來的,即vertical-align: baseline
),一樣行內元素都會和外部元素留這麼一丟丟安全距離。上圖右側就是加了文字的效果,這樣就更說明一切了。iphone
如今咱們知道這種現象主要是因爲下行字符串保護機制和img
是行內元素這兩個因素致使的,那解決方案就從這兩處入手,整理以下:
div
設置font-size: 0
或line-height: 0
,進而行高爲0;img
設置 vertical-align: top 或者 middle/
,使其再也不以默認基線爲對齊方式;img
設置 display:block
,使其變成塊級元素。綜上,我的認爲方法3是最好用的,方法1不推薦使用。
該現場多在表單輸入等場景上會出現,初次看到確實很怪異,效果如圖:
即當瀏覽器(chrome)給輸入框自動填充內容後,也會自動給輸入框帶上背景(黃或灰藍),該問題是因爲chrome會默認給自動填充的input
、select
、textarea
等加上:-webkit-autofill
私有僞屬性形成的,比較好的解決方案就是作樣式覆蓋,代碼以下:
input:-webkit-autofill{
box-shadow: 0 0 0px 1000px white inset !important;
}
select:-webkit-autofill{
box-shadow: 0 0 0px 1000px white inset !important;
}
textarea:-webkit-autofill{
box-shadow: 0 0 0px 1000px white inset !important;
}
複製代碼
比較渣的辦法是設置禁止自動填充,但仍是別那樣作了...
transform做爲CSS3最爲自豪的屬性,已經成爲了當前前端開發中不可或缺的方法,但它有個渲染的問題,即當元素設置有transform,且其值爲基數或小數,同事其總體高度也有基數時,其內部文字會變模糊,如圖:
上圖上模糊狀態下的,下圖是修正過的,具體緣由經查多是由於transform
變換會在瀏覽器上單首創建一個繪畫層並從新進行渲染,在此渲染過程當中也處理了周圍的文字,若是高度爲奇數的文字可能會存在半個像素的計算量,瀏覽器對這半個像素會進行優化渲染,因此邊緣會出現模糊的狀況。解決方案即:
做爲CSS經常使用僞類選擇器,:last-child
常常會被用到,但有時遇到極端狀況,它會意外失效,讓人摸不着頭腦,例子以下: 3個img
標籤包裹在card
中,當前需求是使最後一張圖的邊框呈粉色,代碼以下:
// html
<div class="card">
<img
v-for="(item,i) in pics"
:key="i"
:src="item"
/>
</div>
// css
<style lang="less">
.card {
> img {
width: 150px;
margin-right: 10px;
&:last-child {
border: 5px solid pink;
}
}
}
</style>
複製代碼
同理用:last-of-type
也能實現:
.card {
> img {
width: 150px;
margin-right: 10px;
&:last-of-type {
border: 5px solid pink;
}
}
}
複製代碼
效果以下:
如今要往img
後加一個span
,發現:last-child
已失效:
// html
<div class="card">
<img
v-for="(item,i) in pics"
:key="i"
:src="item"
/>
<span>next is ...</span>
</div>
// css
<style lang="less">
.card {
> img {
width: 150px;
margin-right: 10px;
&:last-child {
border: 5px solid pink;
}
}
}
</style>
複製代碼
而此時:last-of-type
依然沒問題:
如今得出結論:
:last-child
選取一羣兄弟元素中的最後一個元素,且最後的這個元素必須是所聲明的指定元素(注意2個條件);:last-of-type
選取一羣兄弟元素中的最後一個指定類型的元素。可知,:last-of-type
更嚴謹一些,不容易產生意外bug,我更推薦使用它。同理適用於:nth-last-child(n)
和:nth-last-of-type(n)
這部分我會敘述一些DOM操做遇到的一些容易被忽視的問題。
常常作H5移動端開發的朋友我想對這個問題確定不陌生,那就是在部門IOS版本(IOS5及如下)中,對以「-」間隔的字符串時間格式的解析是不成功的,好比咱們寫了這麼一個雞肋時間格式適配器:
function DateFormat(date) {
if(!date) return null;
date = new Date(date);
let Y = date.getFullYear();
let M = (date.getMonth() >= 0 && date.getMonth() <= 8) ? `0${date.getMonth() + 1}` : `${date.getMonth() + 1}`;
let D = (date.getDate() >= 0 && date.getDate() <= 9) ? `0${date.getDate()}`: `${date.getDate()}`;
return `Y-M-D`
}
複製代碼
此時若是在IOS5及如下版本的iphone下,傳入 "2019-12-31"就會呈現出 NaN-NaN-NaN
,而其餘IOS版本及安卓系統都是沒問題的。
針對上述問題,要作兼容適配,即把以"-"間隔的事件字符串替換成以"/"便可,一樣是這個適配器,添加一段代碼:
function DateFormat(date) {
if(!date) return null;
if(typeof date === 'string' && date.indexOf('T')!=-1 && date.indexOf('+')!=-1) {
date = date.replace(/-/g, '/').replace('T',' ').substring(0,date.indexOf('.'))
}
date = new Date(date);
let Y = date.getFullYear();
let M = (date.getMonth() >= 0 && date.getMonth() <= 8) ? `0${date.getMonth() + 1}` : `${date.getMonth() + 1}`;
let D = (date.getDate() >= 0 && date.getDate() <= 9) ? `0${date.getDate()}`: `${date.getDate()}`;
return `Y-M-D`
}
複製代碼
這個真的很詭異的問題,當在一個表單中執行了ENTER鍵提交後,若是是打開新頁面顯示提交結果,則會發現當前表單頁面也跟着刷新了,這種體驗固然是很糟糕的。經查證,該問題的產生條件爲:Form
中只有一個input
時,此時執行ENTER鍵會自動提交表單並刷新頁面。解決方案也很粗暴,直接在input輸入框附近寫一個隱藏標籤,這樣就有2個input了,即避免了產生默認刷新的bug,實例以下:
<form>
<input
type="text"
v-model.trim="searchText"
placeholder="搜索您感興趣的內容"
@keyup.enter="goSearch"
/>
<input
id="hidden"
type="text"
style="display:none"
@keyup.enter="goSearch"
/>
</form>
複製代碼
終於在2020年到來前夕發了一篇比較趕的文章,結束個人2019之旅。本文會一直更新下去,若有不一樣看法和問題,請留言指出,期待您的點贊。最後祝您2020好運連連。