flex#3 flex-wrap

flex-wrap: nowrap (預設)

不拆行(所有flex item擠在一排裡面)
即便指定了寬度,flex container也會以擠在一起為原則,盡量達成指定的寬度

.container
  display: flex
  border: 10px solid goldenrod
  flex-wrap: nowrap
 
.box
  color: white
  font-size: 100px
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 300px
1
2
3
4
5
6
7
8
9
10

flex-wrap: wrap

拆行(flex item超過寬度的話會掉下來)
會遵守width

.container
  display: flex
  border: 10px solid goldenrod
  flex-wrap: wrap
 
.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 300px
1
2
3
4
5
6
7
8
9
10

flex-wrap: wrap-reverse

反轉cross-axis
本來是由上到下↓↓↓
現變成由下到上↑↑↑

.container
  display: flex
  border: 10px solid goldenrod
  flex-wrap: wrap-reverse
 
.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 300px
1
2
3
4
5
6
7
8
9
10

讓flex-item可以無縫填滿外層

  • 寬度算好
  • 使用box-sizing: border-box
.container
  display: flex
  border: 10px solid goldenrod
  flex-wrap: wrap
 
.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  box-sizing: border-box
  width: 33.33%
1
2
3
4
5
6
7
8
9
10

flex-item之間留個空隙

  • 空隙用margin指定
  • 寬度用calc算好
.container
  display: flex
  border: 10px solid goldenrod
  flex-wrap: wrap
 
.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  margin: 10px
  box-sizing: border-box
  width: calc(33.33% - 20px)
1
2
3
4
5
6
7
8
9
10

flex#2 flex-direction

flex-direction: row (預設)

main axis: 由左至右 →→→
cross axis: 由上至下 ↓↓↓

.container
  display: flex
  border: 10px solid goldenrod
 flex-direction: row
1
2
3
4
5
6
7
8
9
10

flex-direction: column

main axis: 由上至下 ↓↓↓
cross axis: 由左至右 →→→

.container
  display: flex
  border: 10px solid goldenrod
 flex-direction: column
1
2
3
4
5
6
7
8
9
10

flex-direction: row-reverse

main axis: 由右至左 ←←←

.container
  display: flex
  border: 10px solid goldenrod
 flex-direction: row-reverse
1
2
3
4
5
6
7
8
9
10

flex-direction: column-reverse

main axis: 由下至上 ↑↑↑

.container
  display: flex
  border: 10px solid goldenrod
 flex-direction: column-reverse
1
2
3
4
5
6
7
8
9
10

flex#1 CSS flexbox

無使用flex時

.container
 .box.box1 1
 .box.box2 2
 .box.box3 3
 .box.box4 4
 .box.box5 5
 .box.box6 6
 .box.box7 7
 .box.box8 8
 .box.box9 9
 .box.box10 10
.box
  color: white
  font-size: 100px
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px

.box1
  background: #1abc9c
.box2
  background: #3498db
.box3
  background: #9b59b6
.box4
  background: #34495e
.box5
  background: #f1c40f
.box6
  background: #e67e22
.box7
  background: #e74c3c
.box8
  background: #bdc3c7
.box9
  background: #2ecc71
.box10
  background: #16a085

Display

1
2
3
4
5
6
7
8
9
10

使用display: flex

外層元素會拉成一列
內層元素會變成flex-item

.container
  display: flex
  border: 10px solid goldenrod
1
2
3
4
5
6
7
8
9
10

使用display: inline-flex

外層元素會拉成一列,但不會全部填滿一列
內層元素會變成flex-item

.container
  display: inline-flex
  border: 10px solid goldenrod
1
2
3
4
5
6
7
8
9
10

JavaScript easing

說明

  1. 設定好自訂動畫函數,input固定間隔值的數字,動畫函數的output會是一個動畫曲線
  2. 用setInterval寫動畫執行函數。參數意義如下
    ele:element
    b:before(初期值)
    c:change(終點值)
    t:timing(目前的時間戳)
    d:duration(這個動畫總共要有幾秒)
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
button(onclick="move()") click me
.box
 background: teal
 width: 200px
 height: 100px
 margin: 40px
//easing函數
function easeOut(t, d){
  return 1 - Math.pow(1-(t/d), 5);
}

function smoothScroll(ele, b){
  var c=-ele.scrollTop;
  var start = Date.now();
  var total = 1400; //毫秒
  var d = 1;

  timer = window.setInterval(function() {
    var t = (Date.now() - start) / total;
    var result = easeOut(t, d);
    var y = b + result * c;
    ele.scrollTop = y;
    if (t >= d) { 
      clearInterval(timer);
    }
  }, 16);
}

function move(){
 if(document.body.scrollTop!==0){
  //Safari
  smoothScroll(document.body, pageYOffset)
 }else{
  //Chrome, FF, IE
  smoothScroll(document.documentElement, pageYOffset)
 }
}

easing 函數介紹

easing out類(開始快,結束慢)

easing out by pow (指數)

function easeOutPow(t, d){
  return 1 - Math.pow(1-(t/d), 5);
}

easing  out by quad (2倍)

function easeOutQuad(t) { 
  return t*(2-t)
}

easing  out by cubic (3倍)

function easeOutCubic(t) { 
  return (--t)*t*t+1 
}

easing  out by quart (4倍)

function easeOutQuart(t) {
  return t*t*t*t
}

easing  out by quint (5倍)

function easeOutQuint(t) {
 return 1+(--t)*t*t*t*t
}

easing in類(開始慢,結束快)

easing in by pow (指數)

function easeInPow(t, d){
  return Math.pow((t/d), 5);
}

easing in by quad (2倍)

function easeInQuad(t) { 
  return t*t 
}

easing in by cubic (3倍)

function easeInCubic(t){ 
  return t*t*t 
}

easing in by quart (4倍)

function easeInQuart(t) { 
  return t*t*t*t 
}

easing in by quint (5倍)

function easeInQuint(t) { 
  return t*t*t*t*t 
}

ease in and out類(開始慢,中間快,結束慢)

easing in by pow (指數)

function easeInOutPow(t, d){
  return t<.5 ? Math.pow((t/d)*1.8, 6.5) : 1 - Math.pow((1-(t/d))*1.8, 6.5);
}

easing in by quad (2倍)

function easeInOutQuad(t) { 
  return t<.5 ? 2*t*t : -1+(4-2*t)*t 
}

easing in by cubic (3倍)

function easeInOutCubic(t) { 
  return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1
}

easing in by quart (4倍)

function easeInOutQuart(t) { 
  return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t 
}

easing in by quint (5倍)

function easeInOutQuint(t) { 
  return t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t
}

參考資料

SMIL 動態控制

SVG <animate>的動態控制屬性

結束後保持變化後的狀態 fill=”freeze”

效果類似animation-fill-mode: forwards;

svg(viewbox="-50 -50 100 100")
 circle(cx=0,cy=0,r=10)
  animate(attributeName="r" dur="5s" values="10;40" fill="freeze")
svg
 width: 240px
 border: solid 2px

JS控制動畫開始

  1. 用參數控制SVG動畫一開始先停止
  2. 用JS method喚醒動畫
svg(viewbox="-50 -50 100 100")
 circle(cx=0,cy=0,r=10)
  animate#myAni(attributeName="r" dur="2s" values="10;30;10" begin="infinite" repeatCount="indefinite")
button(onclick="myAni.beginElement()") click me
svg
 width: 240px
 border: solid 2px

Safari bug:transform-origin不會生效

若使用CSS Animation Keyframes設定動畫的話,則transform-origin可以在safari正常使用的,
但在SMIL設定<animate>,則safari的transform-origin屬性不知為何沒有作用,會造成動畫扭曲

IIFEs

function statements

function statements在執行前會先透過Hoisting儲存在記憶體,
所以可以提前執行不會有問題。

greeting(); //可以被提前執行

function greeting(){
  console.log('Good');
}

function expressions

function expressions執行前不會進記憶體,
所以提前執行會出問題。

greeting(); //→不會理你

var greeting=function(){
 console.log('GOOD');
}

IIFEs

透過function expressions建立函式,並且立刻執行它。

沒用IIFEs時

var greeting=function(){
 console.log('GOOD'); 
}

//Console Panel
//Nothing

使用IIFEs時

var greeting=function(){
console.log('GOOD'); 
}();
//會立刻執行

//Console Panel
//GOOD

Form相關事件

簡介

埋在form裡面的<input type=”submit” />以及<button>,只要按下就會觸發form執行

reportvalidity()

手動觸發「檢核」提示

form#myForm
 input(type="text" required)
 input(type="submit")
 
button(onclick="myForm.reportValidity()") click me

checkValidity()

檢查表單檢核有沒有過,有通過的話回傳true,沒通過的話回傳false

form#myForm
 input(type="text" required)
 input(type="submit")
//Console Panel
myForm.checkValidity()

reset()

清空表單的input內容

form#myForm
 input(type="text" required)
 input(type="submit")
//Console Panel
myForm.reset() //清空內容

PHP陣列取值

name如果命名成xxx[]的話,傳到PHP會直接變成陣列
適合用在很多checkbox時

<form action="ttt.php" method="post">
    <input type="checkbox" name="user[]" value="草莓" id="strawberry" />
    <label for="strawberry">草莓</label>
    <input type="checkbox" name="user[]" value="橘子" id="orange" />
    <label for="orange">橘子</label>
    <input type="checkbox" name="user[]" value="香蕉" id="banana" />
    <label for="banana">香蕉</label>
    <br>
    <br>
    <input type="submit" name="your_submit" />
</form>

<?php 

if(!empty($_POST['your_submit'])){
  for ($i=0; $i < count($_POST['user']); $i++) { 
    echo $_POST['user'][$i].'<br>';
  }
}

?>

Ian's Blog