使用Css的flex來製作動態收縮展開的畫面。
在畫面會有五張圖<div>
垂直排列著,在點可以做到收縮展開的效果。
畫面有五個<div class="panel>
使用flex:1
進行排版
flex: flex-grow flex-shrink flex-basis ;
flex
只有一個數值時,代表著是flex:flex-grow
,其代表意義是5個panel
會撐滿父元素。
原理是子元素有五個panel
,每一個panel
的flex:flex-grow
都為1,其加總為5,與原子元素未填滿的父元素panels
的空間相除的解,與每個flex:flex-grow
相乘就可以得到子元素panel
增加的空間。flex:flex-grow
的數值越大,佔父元素panels
的的比列就越大。
在panel
中也把其子元素轉換成flex:flex-grow
去撐滿父元素panel
。
panel
中的子元素排列方向為由上而下的排列方式,水平位置置中。
display: flex;
justify-content: center;
flex-direction: column;
接下來在panel
建立兩個事件,第一個為click
事件,當panel
被點選時會觸發css
this.classList.toggle('open');
.panel.open {
flex: 5;
font-size:40px;
}
click
事件是讓panel
被點選時,判斷是否有.open
的class,.toggle()
有的話就移除,沒有就加入。
加入.open
class會讓panel
變大,因為.open
的class含有flex: 5;
。
第二件是panel
轉場變大之後,觸發transitionend
的事件。
原本在panel
的子元素有三個,上下的子元素被transform: translateY
向上向下位移100%。
transform: translateY(-100%)
transform: translateY(100%)
當transitionend
被觸發之後就把子元素拉回原本的位置,因此觸發.toggle()
,加入或移除open-active
的class
this.classList.toggle('open-active');
但這邊剛好發生一個問題,就是panel
裡有兩個子元素同時間觸發,會連續.toggle()
兩次結果沒變。
因此加入判斷式讓toggle()
只觸發一次
if (e.propertyName.includes('flex')) {
this.classList.toggle('open-active');
}
這樣就可以讓transitionend
事件正常觸發。
<div class="panels">
<div class="panel panel1">
<p>Hey</p>
<p>Let's</p>
<p>Dance</p>
</div>
。
。
。
<div class="panel panel5">
<p>Life</p>
<p>In</p>
<p>Motion</p>
</div>
</div>
panels.forEach(panel => panel.addEventListener('click', toggleOpen));
panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));
在panels
加入兩個監聽動作,第一個是click
和transitionend
,一個是點擊會有收縮展開的動作,另一個是收縮展開之後後續的動作。
this.classList.toggle('open');
flex是display新的屬性,inline-flex
亦屬於。使用flex會讓元素變成flex容器,而容器裡的元素會變成flex-item,而item可以被CSS的FlexibleBox的排版模組定。
display:flex
的預設值為X軸。初始方向為平行從左至右。flex-direction: row;
flex-direction: row-reverse;
/* 將flex-direction設定為column,就可把主軸(X)轉為Y軸做為主軸,item的排版方向為從上至下的垂直方向。 */
flex-direction: column;
flex-direction: column-reverse;
justify-content: center;
justify-content: flex-start;
justify-content: flex-end;
justify-content: space-between;
justify-content: space-around;
align-items: center;
align-items: start;
align-items: end;
align-items: stretch;
align-items: baseline;
範例
div:nth-child(3) {
align-self: flex-end;
background: pink;
}
flex
The flex CSS property specifies how a flex item will grow or shrink so as to fit the space available in its flex container. This is a shorthand property that sets flex-grow, flex-shrink, and flex-basis.
/* Three values: flex-grow flex-shrink flex-basis */
flex: 2 2 10%;
flex-grow
flex-grow主要是指子元素會依照flex-grow數值的比列去撐滿父層空間。
The flex-grow CSS property specifies the flex grow factor of a flex item. It specifies what amount of space inside the flex container the item should take up. The flex grow factor of a flex item is relative to the size of the other children in the flex-container.
flex-shrink
flex-shrink主要是指子元素比父層大時會依照flex-shrink數值的比列去縮減去符合父層空間。
The flex-shrink CSS property specifies the flex shrink factor of a flex item. Flex items will shrink to fill the container according to the flex-shrink number, when the default width of flex items is wider than the flex container.
flex-basis
子元素的基本大小。
The flex-basis CSS property specifies the initial main size of a flex item. This property determines the size of the content-box unless specified otherwise using box-sizing.
[1]
flex