Flex Panel Gallery
講者:琪雅
時間:2019/12/4
OUTLINE
-
HTML
-
CSS
-
JavaScript
HTML
-
寫一個網頁,由一個大div包著五個小div,每個div都要設置class名稱。
-
大div的class名稱設為panels
-
小div的class名稱設為panel panel1,依序往下編碼
-
每個div裡面用p寫三段文字
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flex Panel Gallery</title>
</head>
<body>
<div class="panels">
<div class="panel panel1">
<p>Hey</p>
<p>Let's</p>
<p>Dance</p>
</div>
<div class="panel panel2">
<p>Give</p>
<p>Take</p>
<p>Receive</p>
</div>
<div class="panel panel3">
<p>Experience</p>
<p>It</p>
<p>Today</p>
</div>
<div class="panel panel4">
<p>Give</p>
<p>All</p>
<p>You can</p>
</div>
<div class="panel panel5">
<p>Life</p>
<p>In</p>
<p>Motion</p>
</div>
</div>
</body>
</html>
css
- 用style標籤寫進head裡面,以background-image: url(); 的方式在5個小div的地方分別插入五種不同的圖片
<style>
.panel1 {
background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500);
}
.panel2 {
background-image: url(https://source.unsplash.com/1CD3fd8kHnE/1500x1500);
}
.panel3 {
background-image: url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d);
}
.panel4 {
background-image: url(https://source.unsplash.com/ITjiVXcwVng/1500x1500);
}
.panel5 {
background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500);
}
</style>
css
<style>
html {
box-sizing: border-box;
}
body {
margin: 0; /*定義一個區域(例如DIV 或span)的外邊界距離,俗稱外距*/
}
.panel1 {
background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500);
}
.panel2 {
background-image: url(https://source.unsplash.com/1CD3fd8kHnE/1500x1500);
}
.panel3 {
background-image: url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d);
}
.panel4 {
background-image: url(https://source.unsplash.com/ITjiVXcwVng/1500x1500);
}
.panel5 {
background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500);
}
</style>
-
針對html、body做區塊調整
-
box-sizing: 用來調整區塊的內距與邊框
-
border-box包含內容寬度、內距與邊框寬度。
-
content-box設定的寬度僅為內容寬度,而內距與邊框額外加上去。
-
inherit繼承至父層的 broder-sizing 設定値。
-
-
利用margin (外距) 使div區塊的圖片充滿網頁頁面
css
<style>
html {
box-sizing: border-box;
}
body {
margin: 0; /*定義一個區域(例如DIV 或span)的外邊界距離,俗稱外距*/
}
.panels {
min-height: 100vh; /*最低高度值*/
overflow: hidden; /*元素超過某個範圍的時候該如何呈現 hidden自動隱藏超出的文字或圖片*/
display: flex; /*宣告*/
}
.panel {
color: white;
text-align: center;
align-items: center;
/* Safari transitionend event.propertyName === flex */
/* Chrome + FF transitionend event.propertyName === flex-grow */
transition: font-size 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11), flex 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11), background 0.2s;
/* transition: property duration timing-function delay;
property用來定義可以產生 transition 屬性效果的屬性名稱,例如寬度、背景顏色 ...。
duration用來定義 transition 屬性發生的時間,單位為秒。
timing-function用來定義 transition 效果的發生速度。
delay用來定義多久之後開始發生 transition 效果。*/
font-size: 20px; /*字的大小*/
background-size: cover;
background-position: center;
flex: 1;
justify-content: center; /* 確定項目位於容器中心(可用於留白的語法)*/
display: flex;
flex-direction: column; /*改變軸線方向 column垂直從上往下排列*/
}
.panel1 {
background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500);
}
.panel2 {
background-image: url(https://source.unsplash.com/1CD3fd8kHnE/1500x1500);
}
.panel3 {
background-image: url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d);
}
.panel4 {
background-image: url(https://source.unsplash.com/ITjiVXcwVng/1500x1500);
}
.panel5 {
background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500);
}
</style>
設定div區塊
css
<link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>
<style>
html {
box-sizing: border-box;
}
body {
margin: 0; /*定義一個區域(例如DIV 或span)的外邊界距離,俗稱外距*/
}
.panels {
min-height: 100vh; /*最低高度值*/
overflow: hidden; /*元素超過某個範圍的時候該如何呈現 hidden自動隱藏超出的文字或圖片*/
display: flex; /*宣告*/
}
.panel {
color: white;
text-align: center;
align-items: center;
/* Safari transitionend event.propertyName === flex */
/* Chrome + FF transitionend event.propertyName === flex-grow */
transition: font-size 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11), flex 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11), background 0.2s;
/* transition: property duration timing-function delay;
property用來定義可以產生 transition 屬性效果的屬性名稱,例如寬度、背景顏色 ...。
duration用來定義 transition 屬性發生的時間,單位為秒。
timing-function用來定義 transition 效果的發生速度。
delay用來定義多久之後開始發生 transition 效果。*/
font-size: 20px; /*字的大小*/
background-size: cover;
background-position: center;
flex: 1;
justify-content: center; /* 確定項目位於容器中心(可用於留白的語法)*/
display: flex;
flex-direction: column; /*改變軸線方向 column垂直從上往下排列*/
}
.panel1 {
background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500);
}
.panel2 {
background-image: url(https://source.unsplash.com/1CD3fd8kHnE/1500x1500);
}
.panel3 {
background-image: url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d);
}
.panel4 {
background-image: url(https://source.unsplash.com/ITjiVXcwVng/1500x1500);
}
.panel5 {
background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500);
}
/* Flex Items */
.panel>* {
margin: 0;
width: 100%;
transition: transform 0.5s; /*transition屬性實現簡單旋轉效果*/
flex: 1 0 auto;
/*flex-grow flex-shrink flex-basis
flex-grow: 元件的伸展性
flex-shrink: 元件的收縮性
flex-basis: 元件的基準值*/
display: flex;
justify-content: center; /* 確定項目位於容器中心(可用於留白的語法)*/
align-items: center; /*交錯軸的對齊設定*/
}
/* :first-child() & :last-child()
CSS的:偽類別,分別可以選取first(第一個)/last(最後一個)子元素*/
.panel>*:first-child {
transform: translateY(-100%); /*translateY(y) 定義 Y 軸方向的 2D 轉換*/
}
.panel.open-active>*:first-child {
transform: translateY(0);
}
.panel>*:last-child {
transform: translateY(100%);
}
.panel.open-active>*:last-child {
transform: translateY(0);
}
.panel p {
text-transform: uppercase; /*控制文章中的文字字母大小寫*/
font-family: 'Amatic SC', cursive;
text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45); /*X 軸方向的陰影 Y 軸方向的陰影 模糊範圍 陰影顏色*/
font-size: 2em;
}
.panel p:nth-child(2) {
font-size: 4em;
}
.panel.open {
flex: 5;
font-size: 40px;
}
</style>
設定動畫
JavaScript
-
宣告取得所有的div 區塊
-
宣告一個上次點擊的Panel,預設先給他panels
let panels = document.querySelectorAll('.panel');
let lastClickPanel = document.querySelector('.panels');
JavaScript
-
寫一個函式,使每次點擊都是一個聚焦效果(關閉其他已展開的)
-
用if 檢查進入的element與上次進入的element是不是相同
-
若不相同,則把上次點擊的element移除open效果
-
再把lastClickPanel指向為這次的elment
-
-
用.classList.toggle觸發這個動畫class
function toggleOpen() {
if (this !== lastClickPanel) {
lastClickPanel.classList.remove('open');
lastClickPanel = this;
}
this.classList.toggle('open');
}
JavaScript
-
寫一個函式,使點擊後會動畫展開的圖片展示效果
-
e.propertyName可以抓到觸發transitionend的屬性
-
利用.includes('flex')來判斷, 只要e.property`有包含到flex的字串就使其通過判斷,加入動畫效果。
-
用.classList.toggle觸發這個動畫class
-
function toggleActive(e) {
console.log(e.propertyName);
if (e.propertyName.includes('flex')) {
this.classList.toggle('open-active');
}
}
JavaScript
-
用panels.forEach設定所有的panel都能用click觸發addEventLinstner中的toggleOpen以及觸發了transitionend來作動toggleActive。
panels.forEach(panel => panel.addEventListener('click', toggleOpen));
panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));
參考來源
Flex Panel Gallery hackmd:https://hackmd.io/JZMu13B2Rp-roHcEfqjKrw?view
Thank you for listening.
Flex Panel Gallery
By q8745912
Flex Panel Gallery
- 133