CSS:水平垂直居中

一、使用 Flexbox 布局

复制代码
<script setup lang="ts">
// 不需要额外逻辑,纯CSS实现
</script>

<template>
  <div class="flex-center">
    <div class="content">我是居中内容</div>
  </div>
</template>

<style scoped>
.flex-center {
  display: flex;
  justify-content: center; /* 水平居中 */
  align-items: center;     /* 垂直居中 */
  height: 100%;          /* 视口高度 */
  width: 100%;            /* 宽度 */
}

.content {
  /* 可选样式 */
  padding: 20px;
  background-color: #f0f0f0;
  border-radius: 8px;
}
</style>

二、使用 Grid 布局

复制代码
<script setup lang="ts">
// 不需要额外逻辑,纯CSS实现
</script>

<template>
  <div class="grid-center">
    <div class="content">我是居中内容</div>
  </div>
</template>

<style scoped>
.grid-center {
  display: grid;
  place-items: center; /* 同时设置水平和垂直居中 */
  height: 100%;
  width: 100%;
}

.content {
  /* 可选样式 */
  padding: 20px;
  background-color: #f0f0f0;
}
</style>

三、使用绝对定位 + transform

复制代码
<script setup lang="ts">
// 不需要额外逻辑,纯CSS实现
</script>

<template>
  <div class="absolute-center">
    <div class="content">我是居中内容</div>
  </div>
</template>

<style scoped>
.absolute-center {
  position: relative;
  height: 100%;
  width: 100%;
}

.content {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%); /* 反向偏移自身宽高的50% */
  
  /* 可选样式 */
  padding: 20px;
  background-color: #f0f0f0;
}
</style>

四、使用 margin: auto (需要固定尺寸)

复制代码
<script setup lang="ts">
// 不需要额外逻辑,纯CSS实现
</script>

<template>
  <div class="margin-auto-center">
    <div class="content">我是居中内容</div>
  </div>
</template>

<style scoped>
.margin-auto-center {
  display: flex;
  height: 100%;
  width: 100%;
}

.content {
  margin: auto; /* 需要在flex或grid容器中,且元素需要有尺寸 */
  width: 200px;  /* 需要固定宽度 */
  height: 100px; /* 需要固定高度 */
  
  /* 可选样式 */
  padding: 20px;
  background-color: #f0f0f0;
}
</style>

五、使用 CSS 表格布局

复制代码
<script setup lang="ts">
// 不需要额外逻辑,纯CSS实现
</script>

<template>
  <div class="table-center">
    <div class="content">我是居中内容</div>
  </div>
</template>

<style scoped>
.table-center {
  display: table;
  width: 100%;
  height: 100%;
}

.table-center > .content {
  display: table-cell;
  text-align: center; /* 水平居中 */
  vertical-align: middle; /* 垂直居中 */
}
</style>

六、使用 JavaScript 动态计算 (响应式)

复制代码
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'

const position = ref({ x: 0, y: 0 })
const contentRef = ref<HTMLElement>()

const updatePosition = () => {
  if (contentRef.value) {
    const parent = contentRef.value.parentElement
    if (parent) {
      position.value = {
        x: (parent.clientWidth - contentRef.value.offsetWidth) / 2,
        y: (parent.clientHeight - contentRef.value.offsetHeight) / 2
      }
    }
  }
}

onMounted(() => {
  updatePosition()
  window.addEventListener('resize', updatePosition)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', updatePosition)
})
</script>

<template>
  <div class="js-center">
    <div 
      ref="contentRef" 
      class="content" 
      :style="{ transform: `translate(${position.x}px, ${position.y}px)` }"
    >
      我是JS计算的居中内容
    </div>
  </div>
</template>

<style scoped>
.js-center {
  position: relative;
  height: 100%;
  width: 100%;
}

.content {
  position: absolute;
  /* 初始位置,会被JS覆盖 */
  top: 0;
  left: 0;
  
  /* 可选样式 */
  padding: 20px;
  background-color: #f0f0f0;
  transition: transform 0.3s ease; /* 平滑过渡 */
}
</style>

七、使用 CSS 变量和 calc()

复制代码
<script setup lang="ts">
// 不需要额外逻辑,纯CSS实现
</script>

<template>
  <div class="calc-center">
    <div class="content">我是使用calc居中的内容</div>
  </div>
</template>

<style scoped>
.calc-center {
  position: relative;
  height: 100%;
  width: 100%;
}

.content {
  position: absolute;
  width: 200px;
  height: 100px;
  left: calc(50% - 100px); /* 50% - 宽度的一半 */
  top: calc(50% - 50px);  /* 50% - 高度的一半 */
  
  /* 可选样式 */
  padding: 20px;
  background-color: #f0f0f0;
}
</style>

Flexbox - 最简单、最现代的方式,推荐使用

Grid - 代码最简洁,但兼容性略低于Flexbox

绝对定位 + transform - 兼容性好,适合复杂场景

margin: auto - 需要固定尺寸,适合简单场景

CSS表格 - 较老的方法,不推荐在新项目中使用

JavaScript计算 - 适合需要动态调整的复杂场景

CSS calc() - 需要知道元素尺寸,灵活性较低

在大多数现代项目中,FlexboxGrid 方法是首选,因为它们简洁、高效且易于维护。

以上方法均经过测试

八、欢迎交流指正