此文章所做的筆記,僅為提醒自己要多加注意的地方。
本文引用之圖片均來自Alpha Camp
作業筆記
起手式 Rest default CSS 還原瀏覽器預設設定
每家瀏覽器都有預設不同的 CSS 樣式,造成前端工程師網頁開發上一個頭痛的問題:
開發時用 CSS 設計好整齊美麗的排版,在 Google Chrome 上看起沒問題,用 IE 打開卻全變了樣,且市面上還有 Firefox、Safari、Opera 等其他家瀏覽器,
所以實務開發中,CSS起手式通常會是 Reset CSS,先將各大瀏覽器的預設樣式還原,有個乾淨的開始,再來制訂專案的樣式。
可以直接使用開源的 CSS Reset 工具如:
- Reset CSS ,這是 CSS 大師 Eric Meyer 整理出的版本
- Normalize.css 這是 Bootstrap 目前已經內建使用的版本
- 或是自行制訂
header 固定置頂
常常看到很多網頁,可以將header固定在最上方,不會因為頁面下滑消失。
我們可以使用 position: fixed 來固定元素位置。
再通過 z-index 可以定義元素的層級,愈大的數字會放在愈上層,愈小的數字會放在愈下層,而視窗位於 0 的位置。
將數值設定為 999 ,基本 header 元素就很難被其他元素覆蓋掉,導覽列就會固定在最上層。
em vs. rem
rem 和 em 同樣是相對單位,只是參照的對象不同。 em 參照的對象是父元素, rem 是 root em 的意思, 參照的是根元素,就是 html 層級的字體大小,一般瀏覽器的預設值是 16 px。
使用 rem 的好處是,專案一複雜,很容易忘記父元素是多少大小,用 rem 不用特別去記。或當父元素字體大小突然被改動時,用 rem 也不會受到連帶影響。
絕對定位 position:absolute
絕對定位 position: absolute 指的是子元素根據父元素做定位,但父元素CSS要設定position: relative,否則會根據html body標籤來設定位置。
在這個案例中,父元素是 header(跟body位置一樣寬且置頂),子元素是 nav。
假設 top 是 0,子元素會貼齊父元素的最頂端。
看手機設計稿,此案導覽列是貼齊在 header 的下面,所以要設定 top:100%。子元素移動到父元素正下方。
本案導覽列原本是沒有特別設定寬度的,瀏覽器預設為 auto。
一般情況下,導覽列因為是 block element,因此會想辦法佔滿父元素的寬度和高度空間。
然而,在設定為絕對定位後,元素已經完全脫離文字流了,本身寬度和高度大小會透過內容決定,
所以目前 .nav 的寬度只有 4 個字元寬。手動將寬度設為 100% 和父元素同寬,文字就會置中。
使用line-height 來設定文字的垂直置中
要做文字的垂直置中的效果,可能會直覺想到 position 或是 flexbox,
這邊因為只有文字,所以可以使用 line-height 這方法來讓 logo 文字垂直置中。
將文字的 line-height 設定和父元素同高即可。
使用input-checkbox來製作漢堡排使導覽列收合
1.先加入html標籤
1 | <header> |
2.原先的nav先設定不顯示
1 | nav { |
3.使用 pseudo-class 控制「被勾選」時樣式,及使用 ~ 選定同一層後方元素
1 | .nav-toggle:checked ~ .nva { |
這樣就可以製作出一個陽春版的漢堡排。
4.使用 transition 和 transform 優化收合的轉場效果
- transition 屬性是一個縮寫,冒號後面可以放四個屬性值:
transition: property duration timing-function delay;依序代表:- transition-property:載明哪個屬性要使用這個效果,例如我們的目標是和顯示有關的 display 屬性。
- transition-duration:這個效果持續發生的時間,單位是秒,如果是 0 點幾,0 可以不寫。例如我們希望持續 0.2 秒的話可寫 .2s 。
- transition-timing-function:效果的變化速度,可以寫屬性名稱,例如 ease-in 是緩慢的開始,也可以自由定義 cubic-bezier 函數,easing.net 提供一張好用的速查表,可前往試用後複製想要的函數。
- transition-delay:先延遲多久之後再開始這個效果,單位和寫法同transition-duration。
- 再nav加入 transition
1
2
3
4
5
6
7
8
9
10
11nav {
/*依據 Header 定位*/
position: absolute;
top: 100%;
background: #ffffff;
width: 100%;
/*原本先不顯示*/
display: none;
/*設定display的過渡動畫變化效果*/
transition: display .2s ease-out;
}
最後發現沒有變化
畫面沒有變化是因為 display 只有 100% 完全顯示和 0% 完全不顯示兩個狀態,無法做到漸變的效果。
- transform
為了解決這個問題,我們再來多認識一個 CSS 屬性:transform。
transform 的 MDN 文件,裡面有屬性變化效果的範例。
使用 transform: scale(1,0); 來取代 display: none;
及 transform: scale(1,1); 來取代 display: block;
1 | nav { |
此時能夠發現有轉場效果了,但是卻從中間開闔。
- 使用 transform-origin 設定 transform 變化起點在上方
讓導覽列從上方開始做上下收放,可使用 transform-origin 這個屬性來達成。
預設的屬性值是 center,代表 transform 效果的起始點是在元素的中心。
可以看 MDN還有哪些屬性 transform-origin
增加transform-origin屬性
1 | nav { |
- 最後使用 opacity 讓使用者不會看到開關時文字壓縮
在.nav-item上加上opacity: 0 以及 .nav-toggle:checked時.nav-item的樣式1
2
3
4
5
6
7
8
9.nav-item {
margin: 1.4rem 0;
opacity: 0; /*完全透明*/
}
.nav-toggle:checked ~ .nav .nav-item {
transition: opacity 0.2s ease-out 0.15s; /*透明過場設定,最後一個參數為當checked被執行時,緩150毫秒進行過場動畫*/
opacity: 1; /*不透明*/
}
製作 hamburger 樣式及位置
利用label 的for 屬性會和input 的 id綁定,就可以點label的時候去觸及input
先在html上加入 label,再加上span打上三,暫時製作一個陽春的漢堡排
1 | <header> |
設定漢堡排位置
先選定 navbar-toggle-label ,使用絕對定位,讓漢堡排從文字流離開
然後設定top和bottom都為0,代表這個元素高度跟父元素 header 相等是 60px
最後使用display: flex 和 align-items 來設定垂直置中。
1 | .navbar-toggle-label { |
進階版漢堡排:使用span畫線
先把國字三刪除,接著改寫 .hamburger的樣式,畫出第一條具備美感的漢堡排中央橫線。
選定漢堡.hamburger,寬度設定 30px,高度是 3px,背景顏色則是 #267b98。
.hamburger {
width: 30px;
height: 3px;
background: #267b98;
}
使用偽元素增加漢堡另外兩條線
其他兩條都跟中間這一條外觀相同,所以我們在選擇器 .hamburger後加兩個偽元素選擇 hamburger::before 和 .hamburger::after。
但我們還沒有給它任何的 content,還沒有任何的內容,所以基本上是看不到它。
我們需要給hamburger::before 和 .hamburger::after一個 content,屬性值設定為一個空值,因為我們只需要利用這個元素的空間來做樣式,不需要內容。
1 | .hamburger, |
設定偽元素的位置
如果想給 .hamburger:before 和 .hamburger::after 設定在 .hamburger 的上下方,
應該給 .hamburger設定 position: relative
.hamburger:before 和 .hamburger::after 設定position: absolute
absolute是相對於自己最近的父元素來定位的,
如果不給.hamburger相對定位,那麼.hamburger:before 和 .hamburger::after的絕對定位absolute就是相對於body來定位的。
relative是相對於自己來定位的,例如:.hamburger{position:relative;top:-50px;},這時.hamburger會以他原本的位置上移50px。
1 | .hamburger, |
接著移動before和after兩個元素的上下位置
1 | .hamburger::before { |
會看到兩個元素已經各上下移動8px,但是偏了一邊,只要在設定absolute的時候給兩個元素left 0即可
完整css
1 | .hamburger, |
隱藏input-checkbox
給input-checkbox設定上CSS樣式屬性 visibility: hidden;
就會隱藏,但是會看到brand歪一邊,這時候再給input-checkbox設定position: absolute,讓他抽離文字流即可。
1 | .navbar-toggle { |
display: none 與 visibility: hidden 的差異 display: none 與 visibility: hidden 都是隱藏元素的方法,差別在於 display: none 會一口氣使操作對象從文字流中拔除,而 visibility: hidden 則像是用一塊白布蓋起來的感覺,畫面上不顯示,但還是會佔一個空間:
在我們剛剛實作的案例中,將 visibility: hidden 搭配上 position: absolute; ,故元素會從文字流中移除,完全和 display: none 是一樣的效果。
在我們的情境中這兩種做法都可以,一併介紹給大家知道。
未來你可以根據需求判斷要用哪一個方法比較合適。
grid-auto-flow 與 grid-auto-rows
grid-auto-flow 是控制當沒有宣告子元素要被擺在網格的特定位置時,子元素將根據特定的流向被自動擺放到網格當中。
grid-auto-flow 的預設值為 row,意思是子元素將逐列被擺放到網格中。
假設第一行有兩列,放滿後會被推向下一行,若是有設定grid-auto-rows高,那麼會自動生成下一行高,並把元素推下一行的第一列。
1 | .container{ |
換個方向可以手動更改grid-auto-flow 為 column,意思是子元素將逐行被放到網格中。
假設第一行只有一列,第二行也只有一列,子元素會由上而下,放滿後會被推向下一列第一行,若是有設定grid-auto-columns寬,那麼自動生成的下一列寬,並把元素推下一列的第一行。
1 | .container{ |
grid-template-areas
可以透過父層先劃分好格子,然後再選擇各個子元素,將各個子元素使用grid-area各自命名,最後回到父層使用grid-template-areas來安排子元素
1 | .banner-wrapper { |