點燈坊

失くすものさえない今が強くなるチャンスよ

實作 Card

Sam Xiao's Avatar 2021-03-08

Card 為目前很流行 Layout,因為可針對不同 Device 寬度輕易 RWD 改變。

Version

CSS 3

flex-grow: 1

card000

Image 與 author 為固定部分,主要 title 內容長度可變,希望 author 部分能永遠垂直靠下。

<template>
  <div class="box">
    <div class="card">
      <div class="pic">
        <img src="https://picsum.photos/300/200/?random=10">
      </div>
      <h3 class="title">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit.
      </h3>
      <div class="author">
        Sam
      </div>
    </div>
    <div class="card">
      <div class="pic">
        <img src="https://picsum.photos/300/200/?random=11">
      </div>
      <h3 class="title">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum, quisquam, sapiente?
      </h3>
      <div class="author">
        Sam
      </div>
    </div>
    <div class="card">
      <div class="pic">
        <img src="https://picsum.photos/300/200/?random=12">
      </div>
      <h3 class="title">
        Lorem ipsum dolor sit amet.
      </h3>
      <div class="author">
        Sam
      </div>
    </div>
  </div>
</template>

<style scoped>
* {
  margin: 0;
  padding: 0;
  list-style: none;
}

.box {
  width: 96%;
  margin: auto;
  display: flex;
  flex-wrap: wrap;
}

.card {
  width: 300px;
  margin: 10px;
  border: 1px solid red;
  display: flex;
  flex-direction: column;
}

.card .pic img {
  width: 100%;
  vertical-align: top;
}

.card .title {
  flex-grow: 1;
}
</style>

40 行

* {
  margin: 0;
  padding: 0;
  list-style: none;
}

CSS reset。

46 行

.box {
  width: 96%;
  margin: auto;
  display: flex;
  flex-wrap: wrap;
}

設定父層 box style:

  • width: 960px:設定父層 box width
  • margin: auto:設定自動調整左右 margin 而水平置中
  • display: flex:為了讓 card 能橫排且等高,設定 card 使用 Flexbox 排列
  • flex-wrap: wrap:RWD 自動換列

53 行

.card {
  width: 300px;
  margin: 10px;
  border: 1px solid red;
  display: flex;
  flex-direction: column;
}

設定子層 card style:

  • width: 300px:設定 card width
  • margin: 10px:設定 card margin
  • border: 1px solid red:設定 card border
  • display: flex:因為 title 內容長度可變,這會造成 author 位置不是垂直置中,打算使用 flex-grow: 1 讓 title 獨佔剩餘高度,因此出現兩層 Flexbox
  • flex-direction: column:由於 card 內容是垂直方向,因此更改其 flex-directioncolumn

61 行

.card .pic img {
  width: 100%;
  vertical-align: top;
}

設定 card 底下 img style:

  • width: 100%:設定圖片與父層 card 同寬
  • vertical-align: top:當 <img> 放在 <div> 內時,vertical-align 預設為 baseline,這導致 <img><div> 之間有一間隔,設定任意值給 vertical-align 取消這一間隔

66 行

.card .title {
  flex-grow: 1;
}

設定 card 底下 title style:

  • flex-grow: 1:由於 title 內容不定,這導致 author 位置會隨 title 內容而變,因此將 title 設定為 flex-grow: 1 佔據 card 剩餘高度,這也是本文最關鍵之處

margin-bottom: auto

card001

Image 與 author 為固定部分,主要 title 內容長度可變,希望 author 部分能永遠垂直靠下。

<template>
  <div class="box">
    <div class="card">
      <div class="pic">
        <img src="https://picsum.photos/300/200/?random=10">
      </div>
      <h3 class="title">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit.
      </h3>
      <div class="author">
        Sam
      </div>
    </div>
    <div class="card">
      <div class="pic">
        <img src="https://picsum.photos/300/200/?random=11">
      </div>
      <h3 class="title">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum, quisquam, sapiente?
      </h3>
      <div class="author">
        Sam
      </div>
    </div>
    <div class="card">
      <div class="pic">
        <img src="https://picsum.photos/300/200/?random=12">
      </div>
      <h3 class="title">
        Lorem ipsum dolor sit amet.
      </h3>
      <div class="author">
        Sam
      </div>
    </div>
  </div>
</template>

<style scoped>
* {
  margin: 0;
  padding: 0;
  list-style: none;
}

.box {
  width: 96%;
  margin: auto;
  display: flex;
  flex-wrap: wrap;
}

.card {
  width: 300px;
  margin: 10px;
  border: 1px solid red;
  display: flex;
  flex-direction: column;
}

.card .pic img {
  width: 100%;
  vertical-align: top;
}

.card .title {
  margin-bottom: auto;
}
</style>

66 行

.card .title {
  margin-bottom: auto;
}

設定 card 底下 title style:

  • margin-bottom: auto:由於 card 高度因為 Flexbox 而等高,因此也可藉由自動調整 title 的 bottom margin 而達到相同效果

雖然 flex-grow: 1margin-bottom: auto 最後結果相同,但藉由 Pesticide 仍可發現兩者不同,flex-grow 是藉由自動調整 title 高度讓 author 垂置靠下;而 margin-bottom 是靠自動調整 title margin 讓 author 垂直靠下

margin-top: auto

card002

Image 與 author 為固定部分,主要 title 內容長度可變,希望 author 部分能永遠垂直靠下。

<template>
  <div class="box">
    <div class="card">
      <div class="pic">
        <img src="https://picsum.photos/300/200/?random=10">
      </div>
      <h3 class="title">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit.
      </h3>
      <div class="author">
        Sam
      </div>
    </div>
    <div class="card">
      <div class="pic">
        <img src="https://picsum.photos/300/200/?random=11">
      </div>
      <h3 class="title">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum, quisquam, sapiente?
      </h3>
      <div class="author">
        Sam
      </div>
    </div>
    <div class="card">
      <div class="pic">
        <img src="https://picsum.photos/300/200/?random=12">
      </div>
      <h3 class="title">
        Lorem ipsum dolor sit amet.
      </h3>
      <div class="author">
        Sam
      </div>
    </div>
  </div>
</template>

<style scoped>
* {
  margin: 0;
  padding: 0;
  list-style: none;
}

.box {
  width: 96%;
  margin: auto;
  display: flex;
  flex-wrap: wrap;
}

.card {
  width: 300px;
  margin: 10px;
  border: 1px solid red;
  display: flex;
  flex-direction: column;
}

.card .pic img {
  width: 100%;
  vertical-align: top;
}

.card .author {
  margin-top: auto;
}
</style>

66 行

.card .author {
  margin-top: auto;
}

設定 card 底下 author style:

  • margin-top: auto:由於 card 高度因為 Flexbox 而等高,因此也可藉由自動調整 author 的 top margin 而達到相同效果

Conclusion

  • flex-growmargin-bottommargin-top 皆可達到相同效果,但關鍵是 card 的子層也要使用 Flexbox,因此出現兩層 Flexbox