點燈坊

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

如何同時並存水平置中與水平靠右 ?

Sam Xiao's Avatar 2021-03-22

實務上常遇到一些不規則水平置中需求,如一個為水平置中,另一個卻水平靠右。

Version

CSS 3

父層控制水平靠右

center000

1 水平置中,但 2 則水平靠右。

<template>
  <div class="box">
    <div class="item1">1</div>
    <div>2</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
  justify-content: flex-end;
}

.item1 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}
</style>

第 9 行

.box {
  display: flex;
  justify-content: flex-end;
}

由父層控制水平靠右:

  • display: flex:子層 item 使用 Flexbox
  • justify-content: flex-end:直接將子層 item 水平靠右

14 行

.item1 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}

子層獨立新 layer 控制水平置中:

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin: auto 有操作空間
  • position: absolute:使用 absolute position,因為其父層皆沒設定定位,相當於定位在 window,亦可使用 position: fixed
  • left: 0right: 0:要使用 margin: auto 水平置中,前提必須要有空間使其調整 margin,left: 0於左側邊緣緊貼 browser,right: 0 於右側邊緣緊貼 browser,因此相當於架構出無形的矩形空間,只是受限於 width: fit-content 只顯示與 content 同寬部分,剩下空間可由 margin: auto 自由發揮而水平置中
  • margin: auto:自動調整左右 margin 而水平置中

父層控制水平置中

center001

1 水平置中,但 2 則水平靠右。

<template>
  <div class="box">
    <div>1</div>
    <div class="item2">2</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
  justify-content: center;
}

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}
</style>

第 9 行

.box {
  display: flex;
  justify-content: center;
}

由父層控制水平置中:

  • display: flex:子層 item 使用 Flexbox
  • justify-content: center:直接將子層 item 水平置中

14 行

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}

子層獨立新 layer 控制水平靠右:

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin-left: auto 有操作空間
  • position: absolute:使用 absolute position,因為其父層皆沒設定定位,相當於定位在 window,亦可使用 position: fixed
  • left: 0right: 0:要使用 margin-left: auto 水平靠右,前提必須要有空間使其調整 margin,left: 0於左側邊緣緊貼 browser,right: 0 於右側邊緣緊貼 browser,因此相當於架構出無形的矩形空間,只是受限於 width: fit-content 只顯示與 content 同寬部分,剩下空間可由 margin-left:auto 自由發揮而水平靠右
  • margin-left: auto:自動調整 left margin 而水平靠右

center002

1 水平置中,但 2 則水平靠右。

<template>
  <div class="box">
    <div>1</div>
    <div class="item2">2</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
  justify-content: space-around;
}

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}
</style>

第 9 行

.box {
  display: flex;
  justify-content: space-around;
}

由父層控制水平置中:

  • display: flex:子層 item 使用 Flexbox
  • justify-content: space-around:原本與 space-between 一樣將剩餘寬度自動平分給 item 間剩餘空間,但不同的是 space-around 會考慮 item 的前後空間,因此平分後看起來像水平置中

14 行

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}

子層獨立新 layer 控制水平靠右:

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin-left: auto 有操作空間
  • position: absolute:使用 absolute position,因為其父層皆沒設定定位,相當於定位在 window,亦可使用 position: fixed
  • left: 0right: 0:要使用 margin-left: auto 水平靠右,前提必須要有空間使其調整 margin,left: 0於左側邊緣緊貼 browser,right: 0 於右側邊緣緊貼 browser,因此相當於架構出無形的矩形空間,只是受限於 width: fit-content 只顯示與 content 同寬部分,剩下空間可由 margin-left: auto 自由發揮而水平靠右
  • margin-left: auto:自動調整 left margin 而水平靠右

center003

1 水平置中,但 2 則水平靠右。

<template>
  <div class="box">
    <div>1</div>
    <div class="item2">2</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
  justify-content: space-evenly;
}

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}
</style>

第 9 行

.box {
  display: flex;
  justify-content: space-evenly;
}

由父層控制水平置中:

  • display: flex:子層 item 使用 Flexbox
  • justify-content: space-evenly:原本與 space-between 一樣將剩餘寬度自動平分給 item 間剩餘空間,但不同的是 space-evenly 會考慮 item 的前後空間,因此平分後看起來像水平置中

space-aroundspace-evenly 差異是儘管包含 item 前後空間,但 space-evenly 是真正 evenly 等寬,但 space-around item 間空間會是前後寬度的兩倍,但目前因為只有一個子層 item,因此 space-aroundspace-evenly 結果相同都是水平置中

14 行

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}

子層獨立新 layer 控制水平靠右:

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin-left: auto 有操作空間
  • position: absolute:使用 absolute position,因為其父層皆沒設定定位,相當於定位在 window,亦可使用 position: fixed
  • left: 0right: 0:要使用 margin-left: auto 水平靠右,前提必須要有空間使其調整 margin,left: 0於左側邊緣緊貼 browser,right: 0 於右側邊緣緊貼 browser,因此相當於架構出無形的矩形空間,只是受限於 width: fit-content 只顯示與 content 同寬部分,剩下空間可由 margin-left: auto 自由發揮而水平靠右
  • margin-left: auto:自動調整 left margin 而水平靠右

子層控制水平靠右

center004

1 水平置中,但 2 則水平靠右。

<template>
  <div class="box">
    <div class="item1">1</div>
    <div class="item2">2</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
}

.item1 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}

.item2 {
  margin-left: auto;
}
</style>

第 9 行

.box {
  display: flex;
}
  • display: flex:為了要使子層 item 能與 conent 同寬有 margin 可操作水平靠右

21 行

.item2 {
  margin-left: auto;
}

由子層控制水平靠右:

  • margin-left: auto:自動調整 left margin 而水平靠右

13 行

.item1 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}

子層獨立新 layer 控制水平置中:

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin: auto 有操作空間
  • position: absolute:使用 absolute position,因為其父層皆沒設定定位,相當於定位在 window,亦可使用 position: fixed
  • left: 0right: 0:要使用 margin: auto 水平置中,前提必須要有空間使其調整 margin,left-0於左側邊緣緊貼 browser,right-0 於右側邊緣緊貼 browser,因此相當於架構出無形的矩形空間,只是受限於 width: fit-content 只顯示與 content 同寬部分,剩下空間可由 margin: auto 自由發揮而水平置中
  • margin: auto:自動調整左右 margin 而水平置中

center005

1 水平置中,但 2 則水平靠右。

<template>
  <div class="box">
    <div class="item1">1</div>
    <div class="empty"/>
    <div>2</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
}

.item1 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}

.empty {
  flex-grow: 1;
}

</style>

10 行

.box {
  display: flex;
}
  • display: flex:子層 item 使用 Flexbox

22 行

.empty {
  flex-grow: 1;
}

設定子層 empty style:

  • flex-grow:表示空白部分剩餘 width 將由此子層 item 平分,因此看起來為水平靠右

14 行

.item1 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}

子層獨立新 layer 控制水平置中:

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin: auto 有操作空間
  • position: absolute:使用 absolute position,因為其父層皆沒設定定位,相當於定位在 window,亦可使用 position: fixed
  • left: 0right: 0:要使用 margin: auto 水平置中,前提必須要有空間使其調整 margin,left: 0 於左側邊緣緊貼 browser,right: 0 於右側邊緣緊貼 browser,因此相當於架構出無形的矩形空間,只是受限於 width: fit-content 只顯示與 content 同寬部分,剩下空間可由 margin: auto 自由發揮而水平置中
  • margin: auto:自動調整左右 margin 而水平置中

子層控制水平置中

center006

1 水平置中,但 2 則水平靠右。

<template>
  <div class="box">
    <div class="item1">1</div>
    <div class="item2">2</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
}

.item1 {
  margin: auto;
}

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}
</style>

第 9 行

.box {
  display: flex;
}
  • display: flex:為了要使子層 item 能與 conent 同寬有 margin 可操作水平靠右

13 行

.item1 {
  margin: auto;
}

由子層控制水平置中:

  • margin: auto:自動調整左右 margin 而水平置中

17 行

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}

子層獨立新 layer 控制水平靠右:

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin-left: auto 有操作空間
  • position: absolute:使用 absolute position,因為其父層皆沒設定定位,相當於定位在 window,亦可使用 position: fixed
  • left: 0right: 0:要使用 margin-left: auto 水平靠右,前提必須要有空間使其調整 margin,left: 0 於左側邊緣緊貼 browser,right: 0 於右側邊緣緊貼 browser,因此相當於架構出無形的矩形空間,只是受限於 width: fit-content 只顯示與 content 同寬部分,剩下空間可由 margin-left: auto 自由發揮而水平靠右
  • margin-left: auto:自動調整 left margin 而水平靠右

center007

1 水平置中,但 2 則水平靠右。

<template>
  <div class="box">
    <div class="empty"/>
    <div>1</div>
    <div class="empty"/>
    <div class="item2">2</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
}

.empty {
  flex-grow: 1;
}

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}
</style>

11 行

.box {
  display: flex;
}
  • display: flex:子層 item 使用 Flexbox

15 行

.empty {
  flex-grow: 1;
}

設定子層 empty style:

  • flex-grow: 1:表示空白部分剩餘 width 將由子層 item 平分,因此看起來為水平置中

19 行

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}

子層獨立新 layer 控制水平靠右:

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin-left: auto 有操作空間
  • position: absolute:使用 absolute position,因為其父層皆沒設定定位,相當於定位在 window,亦可使用 position: fixed
  • left: 0right: 0:要使用 margin-left: auto 水平靠右,前提必須要有空間使其調整 margin,left: 0 於左側邊緣緊貼 browser,right: 0 於右側邊緣緊貼 browser,因此相當於架構出無形的矩形空間,只是受限於 width: fit-content 只顯示與 content 同寬部分,剩下空間可由 margin-left: auto 自由發揮而水平靠右
  • margin-left: auto:自動調整 left margin 而水平靠右

兩個子層

center008

1 水平置中,但 2 則水平靠右。

<template>
  <div class="item1">1</div>
  <div class="item2">2</div>
</template>

<style scoped>
.item1 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}

.item2 {
  width: fit-content;
  margin-left: auto;
}
</style>

第 7 行

.item1 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}

子層獨立新 layer 控制水平置中:

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin: auto 有操作空間
  • position: absolute:使用 absolute position,因為其父層皆沒設定定位,相當於定位在 window,亦可使用 position: fixed
  • left: 0right: 0:要使用 margin: auto 水平置中,前提必須要有空間使其調整 margin,left: 0 於左側邊緣緊貼 browser,right: 0 於右側邊緣緊貼 browser,因此相當於架構出無形的矩形空間,只是受限於 width: fit-content 只顯示與 content 同寬部分,剩下空間可由 margin: auto 自由發揮而水平置中
  • margin: auto:自動調整左右 margin 而水平置中

15 行

.item2 {
  width: fit-content;
  margin-left: auto;
}

子層控制水平靠右

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin-left: auto 有操作空間
  • margin-left: auto:自動調整 left margin 而水平靠右

center009

1 水平置中,但 2 則水平靠右。

<template>
  <div class="item1">1</div>
  <div class="item2">2</div>
</template>

<style scoped>
.item1 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}
</style>

第 7 行

.item1 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}

子層獨立新 layer 控制水平置中:

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin: auto 有操作空間
  • position: absolute:使用 absolute position,因為其父層皆沒設定定位,相當於定位在 window,亦可使用 position: fixed
  • left: 0right: 0:要使用 margin: auto 水平置中,前提必須要有空間使其調整 margin,left: 0 於左側邊緣緊貼 browser,right: 0 於右側邊緣緊貼 browser,因此相當於架構出無形的矩形空間,只是受限於 width: fit-content 只顯示與 content 同寬部分,剩下空間可由 margin: auto 自由發揮而水平置中
  • margin: auto:自動調整左右 margin 而水平置中

15 行

.item2 {
  width: fit-content;
  position: absolute;
  left: 0;
  right: 0;
  margin-left: auto;
}

子層獨立新 layer 控制水平靠右:

  • width: fit-content:width 與 content 同寬,但仍維持其 block 特性,讓 margin: auto 有操作空間
  • position: absolute:使用 absolute position,因為其父層皆沒設定定位,相當於定位在 window,亦可使用 position: fixed
  • left: 0right: 0:要使用 margin-left: auto 水平靠右,前提必須要有空間使其調整 margin,left: 0 於左側邊緣緊貼 browser,right: 0 於右側邊緣緊貼 browser,因此相當於架構出無形的矩形空間,只是受限於 width: fit-content 只顯示與 content 同寬部分,剩下空間可由 margin-left: auto 自由發揮而水平靠右
  • margin-left: auto:自動調整 left margin 而水平靠右

Conclusion

  • 若兩個 item 都在同一個 layer,因為會互相影響,很難做到絕對一個水平置中,另一個水平靠右,唯有將其中一個 item 獨立成新 layer,或者兩個都獨立成新 layer 才有可能