CSS:display控制元素布局

display 是什么

display 是 CSS 中一个非常核心的属性,用于控制元素的显示类型(布局行为)。它决定了:

  • 元素在页面中如何排列(是独占一行还是和其他元素并排);
  • 元素是否生成盒子(box);
  • 是否参与文档流;
  • 子元素如何布局(比如是否开启 Flex 或 Grid 上下文)等。

简单说:display 决定了“这个元素怎么显示、怎么占位置”。

常见的 display 值及其含义

block(块级元素)

  • 独占一行(前后自动换行);
  • 可以设置 widthheightpaddingmargin
  • 默认宽度为父容器的 100%;
  • 在 HTML/uni-app 中,<view><div><p><h1> 等默认就是 display: block
  • block 元素会自动换行,并且可以设置宽高、内外边距,非常适合做容器或独立区块。
<template>
  <view class="page">
    <text class="title">display: block 的效果演示</text>

    <!-- 三个设置了 display: block 的 view -->
    <view class="block-item red">第一个块</view> 我在后面写字了
    <view class="block-item blue">第二个块</view>前后会自动换行
    <view class="block-item green">第三个块</view>

    <text class="tip">👉 每个“块”都独占一行,即使内容很短。</text>
  </view>
</template>

<script setup>
// 无逻辑,纯展示
</script>

<style scoped>
.page {
  padding: 40rpx;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
  margin-bottom: 40rpx;
  display: block;
}

/* 关键:display: block */
.block-item {
  display: block;           /* 默认就是 block,但显式写出更清晰 */
  width: 200rpx;            /* 设置固定宽度 */
  height: 80rpx;            /* 设置固定高度 */
  line-height: 80rpx;       /* 垂直居中文本 */
  text-align: center;
  color: white;
  font-weight: bold;
  margin-bottom: 20rpx;     /* 块之间加点间距 */
}

.red { background-color: #ff6b6b; }
.blue { background-color: #4ecdc4; }
.green { background-color: #45b7d1; }

.tip {
  margin-top: 40rpx;
  font-size: 28rpx;
  color: #888;
}
</style>

inline(行内元素)

  • 不会独占一行,多个元素会在同一行显示
  • 无法设置宽高(设置无效);
  • 内容多长就占多宽(由内容撑开)。
  • ⚠️ 重要提示:在 uni-app 中,<view> 默认是块级元素(block),即使你设置 display: inline,在某些平台(如微信小程序)中可能仍表现异常。
  • 最可靠的方式是用 <text> 标签来演示 inline 行为,因为 <text> 在所有平台都天然支持行内布局。
  • 水平方向的 padding/margin 有效,但垂直方向可能不影响布局;
  • 例子:<span><a><strong><em>
特性 display: inline
是否换行 ❌ 不换行,与其他 inline 元素同行
能否设宽高 ❌ 不能(设置无效)
能否设水平 margin/padding ✅ 可以
能否设垂直 margin/padding ⚠️ 可设置但不撑开布局(可能重叠)
推荐标签 <text><span>(在 H5 中)
<template>
  <view class="page">
    <text class="title">display: inline 的效果演示</text>

    <!-- 使用 <text> 模拟 inline 元素(最准确) -->
    <view class="demo-line">
      <text class="inline-item red">苹果</text>
      <text class="inline-item blue">香蕉</text>
      <text class="inline-item green">橙子</text>
    </view>

    <text class="tip">👉 三个文字在同一行,且不能设置固定宽高。</text>

    <!-- 对比:如果用 view + display: inline(可能无效) -->
    <view class="demo-line" style="margin-top: 40rpx;">
      <view class="inline-view red">View1</view>
      <view class="inline-view blue">View2</view>
    </view>
    <text class="tip" style="color: #e74c3c;">⚠️ 注意:上面两个 View 可能仍换行(因平台限制)</text>
  </view>
</template>

<script setup>
// 无逻辑,纯展示
</script>

<style scoped>
.page {
  padding: 40rpx;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
  margin-bottom: 40rpx;
  display: block;
}

.demo-line {
  margin-bottom: 30rpx;
}

/* ✅ 正确方式:用 text 演示 inline */
.inline-item {
  display: inline;          /* 实际上 text 默认就是 inline */
  padding: 10rpx 20rpx;     /* 只有水平 padding 有效 */
  margin: 0 10rpx;          /* 水平 margin 有效 */
  color: white;
  font-size: 28rpx;
  /* ❌ 下面这些对 inline 元素无效! */
  /* width: 200rpx; */      /* 不生效 */
  /* height: 100rpx; */     /* 不生效 */
}

.red { background-color: #e74c3c; }
.blue { background-color: #3498db; }
.green { background-color: #2ecc71; }

/* ⚠️ 不推荐:用 view + inline(在 uni-app 中可能失效) */
.inline-view {
  display: inline;
  width: 150rpx;   /* 在 H5 可能有效,但在小程序通常无效 */
  height: 80rpx;   /* 同上 */
  padding: 10rpx 20rpx;
  color: white;
  font-size: 28rpx;
}
</style>

inline-block(行内块元素)

  • 多个元素在同一行显示(像 inline);
  • 可以设置宽高、内外边距(像 block);
  • 是实现“水平排列 + 精确控制尺寸”的经典方案。
  • 常用于需要并排显示又需要控制尺寸的场景(如导航菜单项、图标按钮)。
需求 inline block inline-block
同一行显示
设置宽高
设置 margin/padding ⚠️(垂直无效)
适合做按钮/图标
<template>
  <view class="page">
    <text class="title">display: inline-block 的效果演示</text>

    <!-- 三个 inline-block 元素 -->
    <view class="demo-container">
      <view class="item red">首页</view>
      <view class="item blue">分类</view>
      <view class="item green">我的</view>
    </view>

    <text class="tip">👉 三个按钮在同一行,且每个都有固定宽高和间距。</text>

    <!-- 对比:如果用 display: block(会换行) -->
    <text class="subtitle">对比:display: block(换行)</text>
    <view class="demo-container">
      <view class="item-block red">首页</view>
      <view class="item-block blue">分类</view>
      <view class="item-block green">我的</view>
    </view>
  </view>
</template>

<script setup>
// 无逻辑,纯展示
</script>

<style scoped>
.page {
  padding: 40rpx;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
  margin-bottom: 30rpx;
  display: block;
}

.subtitle {
  font-size: 32rpx;
  margin: 50rpx 0 20rpx;
  color: #e74c3c;
}

/* ✅ 关键:inline-block 容器 */
.demo-container {
  /* 容器本身是 block,但子元素 inline-block */
  margin-bottom: 30rpx;
}

/* 🔑 核心样式:inline-block */
.item {
  display: inline-block;     /* 行内块:同行 + 可设宽高 */
  width: 180rpx;             /* ✅ 宽度生效 */
  height: 80rpx;             /* ✅ 高度生效 */
  line-height: 80rpx;        /* 垂直居中文本 */
  text-align: center;
  color: white;
  font-size: 28rpx;
  font-weight: bold;
  border-radius: 16rpx;
  margin-right: 20rpx;       /* ✅ 水平间距有效 */
  /* 注意:最后一个元素的 margin-right 不影响布局 */
}

/* 对比:block(会换行) */
.item-block {
  display: block;
  width: 180rpx;
  height: 80rpx;
  line-height: 80rpx;
  text-align: center;
  color: white;
  font-size: 28rpx;
  font-weight: bold;
  border-radius: 16rpx;
  margin-bottom: 20rpx;      /* 垂直间距 */
}

.red { background-color: #ff6b6b; }
.blue { background-color: #4ecdc4; }
.green { background-color: #45b7d1; }

.tip {
  margin-top: 20rpx;
  font-size: 28rpx;
  color: #888;
}
</style>

none(隐藏元素)

  • display: none 会让元素 完全从页面中消失
  • 不占据任何空间(后面的元素会“顶上来”);
  • visibility: hidden(隐藏但占位)有本质区别。
<template>
  <view class="page">
    <text class="title">display: none 的效果演示</text>

    <!-- 控制按钮 -->
    <button class="toggle-btn" @click="toggleHidden">
      {{ isHidden ? '显示中间块' : '隐藏中间块' }}
    </button>

    <!-- 三个色块:红、蓝(可隐藏)、绿 -->
    <view class="box red">红色块(始终显示)</view>
    
    <!-- 👇 这个蓝色块会根据 isHidden 切换 display: none -->
    <view 
      class="box blue" 
      :style="{ display: isHidden ? 'none' : 'block' }"
    >
      蓝色块(可隐藏)
    </view>

    <view class="box green">绿色块(始终显示)</view>

    <text class="tip">💡 点击按钮切换蓝色块的显示/隐藏。</text>
    <text class="tip">👉 注意:蓝色块隐藏时,绿色块会立即上移,不留空白!</text>
  </view>
</template>

<script setup>
import { ref } from 'vue';

// 响应式状态:控制是否隐藏
const isHidden = ref(false);

// 切换函数
const toggleHidden = () => {
  isHidden.value = !isHidden.value;
};
</script>

<style scoped>
.page {
  padding: 40rpx;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
  margin-bottom: 40rpx;
  display: block;
}

.toggle-btn {
  margin-bottom: 40rpx;
  background-color: #4ecdc4;
  color: white;
  border-radius: 12rpx;
}

.box {
  width: 100%;
  height: 120rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  margin-bottom: 20rpx;
  border-radius: 16rpx;
}

.red { background-color: #ff6b6b; }
.blue { background-color: #45b7d1; }
.green { background-color: #2ecc71; }

.tip {
  margin-top: 30rpx;
  font-size: 28rpx;
  color: #888;
}
</style>

如果换成 visibility: hidden:(非本例,但供你理解)

  • 蓝色块看不见了;
  • 但绿色块不会上移,蓝色块的位置仍然“空着”;
  • 因为它只是“透明”,仍占据文档流中的空间

彻底移除元素并释放空间 → 用 display: none

暂时隐藏但保留位置 → 用 visibility: hidden

flex(弹性盒子)

  • 将元素变为弹性容器(Flex Container),它的直接子元素就自动成为 “弹性项目”(Flex Items)

  • “弹性” = 能伸能缩,自动适应空间,也就是子元素能根据容器空间自动调整大小和位置

  • 容器属性(作用于父元素)

    属性 作用
    display: flex 启用弹性布局
    flex-direction 主轴方向(row / column
    justify-content 主轴对齐(center, space-between 等)
    align-items 交叉轴对齐(center, flex-start 等)
    flex-wrap 是否换行(nowrap / wrap
  • 子项属性(作用于子元素)

    属性 作用
    flex: 1 简写,表示“可伸缩,占满剩余空间”
    align-self 单独控制某个子项的交叉轴对齐
  • 具体可以查看笔记:HTML、CSS和JS的入门:Flex 布局(弹性盒子布局)

<template>
  <view class="page">
    <text class="title">display: flex 弹性布局演示</text>

    <!-- 控制按钮:切换布局方向 -->
    <button class="btn" @click="toggleDirection">
      当前方向:{{ isColumn ? '垂直 (column)' : '水平 (row)' }}
    </button>

    <!-- 控制按钮:切换对齐方式 -->
    <button class="btn" @click="cycleAlign">
      对齐方式:{{ currentAlign }}
    </button>

    <!-- Flex 容器 -->
    <view 
      class="flex-container" 
      :class="{ column: isColumn }"
      :style="{
        justifyContent: isColumn ? 'center' : alignMap[currentAlign].justify,
        alignItems: isColumn ? alignMap[currentAlign].align : 'center'
      }"
    >
      <view class="item red">A</view>
      <view class="item blue">B</view>
      <view class="item green">C</view>
    </view>

    <text class="tip">💡 点击按钮切换布局方向和对齐方式。</text>
    <text class="tip">👉 观察三个色块如何自动排列和对齐!</text>
  </view>
</template>

<script setup>
import { ref } from 'vue';

// 响应式状态
const isColumn = ref(false); // false = row(水平),true = column(垂直)

// 对齐方式选项
const alignOptions = ['居中', '左上', '右下', '两端对齐'];
const currentAlign = ref('居中');

// 对齐映射(根据方向动态调整 justify 和 align)
const alignMap = {
  '居中': { justify: 'center', align: 'center' },
  '左上': { justify: 'flex-start', align: 'flex-start' },
  '右下': { justify: 'flex-end', align: 'flex-end' },
  '两端对齐': { justify: 'space-between', align: 'center' }
};

// 切换主轴方向
const toggleDirection = () => {
  isColumn.value = !isColumn.value;
};

// 循环切换对齐方式
const cycleAlign = () => {
  const index = alignOptions.indexOf(currentAlign.value);
  currentAlign.value = alignOptions[(index + 1) % alignOptions.length];
};
</script>

<style scoped>
.page {
  padding: 40rpx;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
  margin-bottom: 30rpx;
}

.btn {
  margin-bottom: 30rpx;
  background-color: #4ecdc4;
  color: white;
  border-radius: 12rpx;
}

/* 🔑 核心:Flex 容器 */
.flex-container {
  display: flex;               /* 启用弹性布局 */
  width: 100%;
  height: 300rpx;              /* 固定高度,便于观察垂直对齐 */
  background-color: #f8f9fa;
  border: 2rpx dashed #ccc;
  border-radius: 16rpx;
  padding: 20rpx;
  box-sizing: border-box;
}

/* 垂直布局时 */
.flex-container.column {
  flex-direction: column;      /* 主轴变为垂直 */
}

/* Flex 子项 */
.item {
  width: 120rpx;
  height: 120rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  font-size: 36rpx;
  border-radius: 16rpx;
}

.red { background-color: #ff6b6b; }
.blue { background-color: #45b7d1; }
.green { background-color: #2ecc71; }

.tip {
  margin-top: 30rpx;
  font-size: 28rpx;
  color: #888;
}
</style>

grid(网格布局)

  • 创建网格容器(Grid Container)
  • 子元素按二维网格(行 + 列)排列;
  • 适合复杂布局(如卡片墙、仪表盘)。
<template>
  <view class="page">
    <text class="title">display: grid 网格布局演示</text>

    <!-- 控制按钮:切换列数 -->
    <button class="btn" @click="cycleColumns">
      当前列数:{{ columns }} 列
    </button>

    <!-- Grid 容器 -->
    <view 
      class="grid-container"
      :style="{
        gridTemplateColumns: `repeat(${columns}, 1fr)`
      }"
    >
      <!-- 动态生成 8 个网格项 -->
      <view 
        v-for="index in 8" 
        :key="index" 
        class="grid-item"
        :class="getColorClass(index)"
      >
        {{ index }}
      </view>
    </view>

    <text class="tip">💡 点击按钮切换列数(2/3/4列)。</text>
    <text class="tip">👉 观察数字如何自动换行并填满网格!</text>
  </view>
</template>

<script setup>
import { ref } from 'vue';

// 响应式状态:当前列数
const columns = ref(2);

// 循环切换列数:2 → 3 → 4 → 2 ...
const cycleColumns = () => {
  columns.value = columns.value === 4 ? 2 : columns.value + 1;
};

// 根据索引返回不同颜色(让网格更美观)
const getColorClass = (index) => {
  const colors = ['red', 'blue', 'green', 'yellow', 'purple', 'orange', 'pink', 'cyan'];
  return colors[(index - 1) % colors.length];
};
</script>

<style scoped>
.page {
  padding: 40rpx;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
  margin-bottom: 30rpx;
}

.btn {
  margin-bottom: 40rpx;
  background-color: #45b7d1;
  color: white;
  border-radius: 12rpx;
}

/* 🔑 核心:Grid 容器 */
.grid-container {
  display: grid;                /* 启用网格布局 */
  gap: 20rpx;                   /* 网格项之间的间距(行+列) */
  padding: 20rpx;
  background-color: #f8f9fa;
  border-radius: 16rpx;
  /* grid-template-columns 由 JS 动态设置 */
}

/* 网格项 */
.grid-item {
  height: 160rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  font-size: 36rpx;
  border-radius: 16rpx;
}

/* 颜色类 */
.red { background-color: #ff6b6b; }
.blue { background-color: #4ecdc4; }
.green { background-color: #2ecc71; }
.yellow { background-color: #f9ca24; }
.purple { background-color: #a55eea; }
.orange { background-color: #f0932b; }
.pink { background-color: #eb4d4b; }
.cyan { background-color: #6c5ce7; }

.tip {
  margin-top: 30rpx;
  font-size: 28rpx;
  color: #888;
}
</style>

table / table-row / table-cell

  • 模拟 HTML 表格的显示行为;
  • 虽然现在少用,但在某些兼容性场景仍有价值。
display: table;
display: table-cell;

contents(不常用但强大)

  • 元素自身不生成任何盒子,但其子元素仍正常渲染;
  • 好比“透明外壳”,常用于无障碍或布局穿透。
display: contents;

flow-root(较新)

  • 创建一个新的块格式化上下文(BFC),常用于清除浮动;
  • 类似于 overflow: hidden 的效果,但语义更清晰。
display: flow-root;

Grid 常见属性

容器属性

属性 作用 常见示例
display: grid 开启 Grid 布局 display: grid;
grid-template-columns 定义列宽 grid-template-columns: 1fr 1fr;
grid-template-rows 定义行高 grid-template-rows: 100px auto;
gap 行列间距(简写) gap: 10px;
row-gap 行间距 row-gap: 20px;
column-gap 列间距 column-gap: 20px;
justify-items 子元素水平对齐 justify-items: center;
align-items 子元素垂直对齐 align-items: center;
place-items align + justify 简写 place-items: center;
justify-content 整个 Grid 水平对齐 justify-content: space-between;
align-content 整个 Grid 垂直对齐 align-content: center;
place-content content 对齐简写 place-content: center;
grid-auto-columns 隐式列尺寸 grid-auto-columns: 100px;
grid-auto-rows 隐式行尺寸 grid-auto-rows: minmax(100px, auto);
grid-auto-flow 自动排列方向 grid-auto-flow: row;

子项(item)常见位置控制属性

属性 作用 示例
grid-column-start 列起始线 grid-column-start: 1;
grid-column-end 列结束线 grid-column-end: 3;
grid-row-start 行起始线 grid-row-start: 1;
grid-row-end 行结束线 grid-row-end: 2;
grid-column 列简写 grid-column: 1 / 3;
grid-row 行简写 grid-row: 1 / 2;
grid-area 指定区域 grid-area: header;
align-self 垂直对齐自己 align-self: end;
place-self self 对齐简写 place-self: center;

子项(item)常见单个元素对齐属性

属性 作用 示例
justify-self 水平对齐自己 justify-self: center;
align-self 垂直对齐自己 align-self: end;
place-self self 对齐简写 place-self: center;

grid-template-columns

grid-template-columnsW3C 官方定义的 CSS Grid Module Level 1 规范中的核心属性,作用是:定义网格容器中的列数、每列的宽度。

/* 固定列宽 */
grid-template-columns: 100px 200px 100px;

/* 等分三列 */
grid-template-columns: 1fr 1fr 1fr;
/* 简写 */
grid-template-columns: repeat(3, 1fr);

/* 混合:固定 + 弹性 */
grid-template-columns: 100px 1fr 2fr;

/* 响应式:最小 150rpx,最大等分 */
grid-template-columns: repeat(auto-fill, minmax(150rpx, 1fr));

Grid vs Flex 核心对比

Flex = 排一排,Grid = 画格子

Grid 负责布局(layout),Flex 负责对齐(alignment)

对比项 CSS Grid Flexbox
设计方向 二维布局(行 + 列) 一维布局(单方向)
控制范围 同时控制行和列 只控制一条轴
适合场景 页面整体布局 单行 / 单列排列
布局方式 网格思维 流式排列
对齐能力 非常强(区域定位) 简单直接
响应式 强(auto-fit / minmax) 中等
复杂布局 非常适合 会变复杂
学习难度 略高 较简单
/* Flex 的思维(线性排列)*/
.container {
  display: flex;
}
/* 效果像:
[ item ][ item ][ item ]*/


/* Grid 的思维(网格布局))*/
.container {
  display: grid;
}
/*
[ 1 ][ 2 ][ 3 ]
[ 4 ][ 5 ][ 6 ]
*/

Tips

fr 单位

fr 单位:表示按比例分配空间。

grid-template-columns: 1fr 2fr;

repeat() 函数

grid-template-columns: repeat(4, 1fr); = 写 4 次 1fr

repeat(auto-fit, ...)

  • 意思是:能放多少列就放多少列。

  • 浏览器会根据容器宽度自动计算:

    • 屏幕宽 → 多放几列

    • 屏幕窄 → 自动减少列数

minmax(最小值, 最大值)

给 Grid 的行或列设置「最小值 + 最大值」的弹性范围。

参数 含义
min 最小尺寸(不能再小)
max 最大尺寸(最多扩展到这里)

JavaScript的驼峰命名

<!-- ✅ 在 <style> 中 -->
<style>
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 连字符 */
}
</style>

<!-- ✅ 在 :style 动态绑定中 -->
<template>
  <view :style="{ gridTemplateColumns: 'repeat(3, 1fr)' }"></view>
</template>

这里用的是 gridTemplateColumns(驼峰式),原因如下:

场景 属性命名规则 示例
CSS 文件 / <style> 标签 使用连字符(kebab-case) grid-template-columns
JavaScript / Vue :style 对象 使用驼峰命名(camelCase) gridTemplateColumns

📌 这是 Vue 和所有前端框架(React、Svelte 等)的通用规则,因为:

  • grid-template-columns 不是合法的 JavaScript 变量名(包含 -);

  • 所以浏览器和框架约定:将 CSS 属性中的 -x 转为大写 X

例如:

  • background-colorbackgroundColor
  • font-sizefontSize
  • grid-template-columnsgridTemplateColumns
  • justify-contentjustifyContent

×

喜欢就点赞,疼爱就打赏