ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CSS基础属性详解:从盒模型到居中,一次搞懂页面布局核心

CSS基础属性详解:从盒模型到居中,一次搞懂页面布局核心 前几天带一个刚转行的朋友调样式他对着教程敲了一下午最后问我为什么同样的属性别人写出来是那个效果我写出来就乱套我让他把代码发过来一看问题全出在基础属性上——盒模型没搞清、优先级没算明白、居中方案选错。说实话这种问题我见过太多。CSS 这玩意很多人把它当“背单词”今天记一个 text-align明天记一个 display可真到写页面的时候属性之间怎么配合、为什么这么写不生效脑子里一团浆糊。这篇图文详解版我不打算给你列一份“CSS 常用属性速查表”就完事而是把 CSS 里最常用、最容易踩坑的属性从原理到实战给你捋一遍样式怎么引、选择器怎么选、盒模型怎么算、文本怎么排、动画怎么写、常见问题怎么排查。不管你是零基础刚入门还是写了一两年还觉得基础不牢靠读完后你会发现CSS 没那么玄乎它就是一套“描述页面怎么画”的规则你看懂了规则剩下的就是熟练度的问题。1. 样式引入方式与选择器先搞清楚 CSS 怎么“接”到页面上很多人写 CSS 第一步就错了——不是属性记不住而是样式根本就没被正确加载进来。CSS 定义与引用这事儿看着简单里面门道不少。1.1 三种引入方式怎么选CSS 要生效前提是浏览器能拿到你的样式规则。常见的引入方式有三种外链式、内嵌式、行内式。外链式是把样式写在一个独立的.css文件里然后在 HTML 的head中用link引入!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleCSS 外链式/title link relstylesheet hrefstyle.css /head body p classintro这是一段测试文字/p /body /html我个人的建议是正经项目一律用外链式。原因有三个第一浏览器可以缓存 CSS 文件页面二次加载时样式秒开第二HTML 结构文件和样式文件分离谁维护都不打架第三多页面共用一套样式特别方便改一处全站生效。内嵌式就是把style标签直接写在 HTML 文件里适合单页演示或首屏关键样式比如官网落地页的首页样式为了减少一次请求可以内嵌一部分。行内式是把 style 属性直接写在标签上比如p stylecolor: red它虽然能生效但会带来两个麻烦样式没法复用、优先级还特别高后期想覆盖它得用!important属于自己给自己埋坑。还有一个细节容易被忽略——引入顺序。同样优先级的规则后加载的会覆盖先加载的。所以如果你引用了多个 CSS 文件谁写在后面谁的样式就“说了算”。很多新手问“为什么我写的样式不生效”一半以上问题出在这个顺序上。1.2 基础选择器与优先级计算选择器的作用就是告诉浏览器“这条规则管哪些元素”。基础选择器就那么几类通配选择器*、标签选择器div、类选择器.class、id 选择器#id。/* 通配选择器选中页面所有元素 */ * { margin: 0; padding: 0; } /* 标签选择器选中所有 p 标签 */ p { font-size: 16px; } /* 类选择器选中所有 classintro 的元素 */ .intro { color: blueviolet; } /* id 选择器选中 idmain 的独一无二元素 */ #main { width: 1200px; }id 选择器在 HTML 里要求全局唯一所以它的定位是“找那个唯一的大块头”比如页面主体容器、顶部导航。类选择器可以无限复用是日常开发的主力。选择器的优先级说白了就是“谁更具体谁说了算”。我习惯用一个权重记法行内样式是 (1,0,0,0)id 选择器是 (0,1,0,0)类选择器/伪类是 (0,0,1,0)标签选择器是 (0,0,0,1)通配符是 (0,0,0,0)。当两条规则冲突时从左到右比较数字大的赢。比如#main .intro p的权重是 (0,1,1,1)肯定压过.intro p的 (0,0,1,1)。!important是最后的“王牌”但别乱用。它会把优先级直接拉到最高后续想覆盖只能再用一个!important。我见过有人为了省事十几个属性全加上!important结果后面改需求时根本无法维护。记住一个原则能用优先级规则解决的问题永远别上!important。1.3 通配符*的优缺点热搜词里专门有一条“css 样式表中使用*的优缺点”看来踩过这个坑的人不少。通配选择器最常见的用法就是初始化样式* { margin: 0; padding: 0; }这么写的优点是省事、直观——所有元素的内外边距全部清零浏览器默认样式带来的干扰马上消失。但它有两个问题是你必须清楚的。第一是性能。*会匹配页面上所有元素包括 html、body、div、p、span、a……一个稍微复杂点的页面有几百上千个节点每条规则都要往所有元素上跑一遍虽然现代浏览器优化得不错但大项目里这种写法确实会影响渲染效率。第二是误伤。有些元素是有默认外边距的比如p标签自带上下边距h1~h6自带加粗和边距ul/ol自带缩进。你无差别清零之后语义化的默认样式全没了还得一个个手动加回来反而多写代码。我的做法是小项目、demo、学习练习用* { margin:0; padding:0; }没问题够简单够快。正经点的大项目用 CSS Reset 工具比如normalize.css或者主流的 reset 方案。这类工具不是粗暴清零而是把不同浏览器默认样式拉齐到一个合理的基准线上比如保留p的上下边距、保留标题的字号层级。2. 盒模型与布局属性页面长得不一样根源都在这里页面上每个元素在浏览器眼里都是一个“盒子”你调间距、调宽高、调边框本质上都是在调盒子。盒模型没搞懂后面全是糊涂账。2.1 两种盒模型的标准之争盒模型说的是一个元素由几部分构成内容区 content、内边距 padding、边框 border、外边距 margin。这里有个经典大坑——width到底包不包括 padding 和 border标准盒模型content-box下你写width: 200px这个 200px 只算内容区padding 和 border 是额外加上去的。实际占的宽度是 200 padding左右 border左右。而border-box盒模型下你写width: 200px浏览器保证这个元素整体宽度就是 200pxpadding 和 border 是从里面挤出来的。.box { width: 200px; padding: 20px; border: 2px solid #333; box-sizing: border-box; /* 整体宽度就锁死在 200px */ }刚学的时候经常听到一句话width 设了 200px为什么实际占了 244px就是因为默认用的是content-box。现在的工程实践里主流做法是在全局统一换成border-box*, *::before, *::after { box-sizing: border-box; }这样设计有个特别大的好处——你写布局时算宽度不用再“心算加 padding”尤其在做响应式布局、栅格系统的时候给一个百分比宽度再加上 padding不会把布局撑爆。我接手过的项目里凡是盒模型不统一导致对不齐的页面十有八九都是因为这个。2.2 常用盒属性margin 的合并与 auto 居中margin 是外边距padding 是内边距这俩一个向外推一个向内挤看着简单但有几个反直觉的规则。第一是 margin 合并。上下相邻两个兄弟元素各自设了 margin-bottom 和 margin-top它们的间距不是相加而是取最大值。比如上面元素 margin-bottom: 30px下面元素 margin-top: 20px实际间距是 30px 而不是 50px。父元素和第一个子元素的 margin-top 也会“穿透”出去导致父元素被整体往下顶这个新手遇见的频率特别高。第二是margin: 0 auto可以让块级元素水平居中但前提是这个元素得有一个确定宽度否则它默认占满整行没有“剩余空间”可分配居中也就无从谈起。还有垂直方向margin: auto默认是不起作用的除非父容器用 flex 布局。padding 和 border 的复合写法要熟练padding: 10px是四边都是 10pxpadding: 10px 20px是上下 10px、左右 20pxpadding: 10px 20px 30px是上 10px、左右 20px、下 30pxpadding: 10px 20px 30px 40px按上右下左顺时针。border 常用写法是border: 1px solid #ccc一次定义宽度、样式、颜色还有border-radius做圆角设 50% 能切出圆形这个在头像、按钮上太常见了。2.3 定位与布局position 五个值的正确打开方式position 属性是 CSS 里最核心的布局属性之一五个值各有各的性格。static是默认值元素按文档流正常排列。relative是相对定位元素先按文档流放好然后再用top/right/bottom/left做偏移。注意它原来的物理位置还占着不会让后面的元素顶上来。这个特性在做“微调”时很好用比如图标距离文字太近position: relative; left: 4px;就完事了。absolute是绝对定位元素脱离文档流不占位置它相对谁定位取决于祖先里有没有position非 static 的元素没有就一路找到浏览器视口。很多新手设了 absolute 发现元素乱跑就是忘给父元素加position: relative。fixed也是脱离文档流但它相对的是浏览器视口页面滚动它不动吸顶导航、右下角回到顶部按钮这些场景就是它。sticky是这几年特别好用的新值它像 relative 和 fixed 的合体元素在滚动范围内像普通元素一样一旦滚动到设定的阈值比如top: 0就“粘”住不动。.nav { position: sticky; top: 0; z-index: 100; }z-index只对定位元素生效值越大越靠前。脱离文档流的元素多了之后层级混乱是常见问题我的排查思路是先看谁没设 position再看 z-index 谁大谁小基本能定位。2.4 居中方案大全别再每次都百度了居中问题绝对是 CSS 高频问题热搜词里有一串相关的“css中怎么把input居中”“文本垂直水平居中css代码”“让table水平居中css代码”。我把常见场景一次性给你说清楚。水平居中分两种情况。行内元素文字、链接、span、input用text-align: center作用于父容器块级元素用margin: 0 auto前提是自身有宽度。垂直居中单行文本有个经典技巧让line-height等于容器高度。多行文本或任意元素现代方案是 flex父容器设display: flex; align-items: center; justify-content: center;水平垂直一起解决这是目前最推荐的方案。Grid 方案更简洁display: grid; place-items: center;两行搞定兼容性在现代浏览器都没问题。还有一种用绝对定位加 transform 的方法元素设position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);它不依赖父容器是 flex 还是 grid缺点是 transform 会开启新的层叠上下文某些情况下有影响。回到具体场景input 怎么居中如果是指 input 元素在页面里水平居中用一个包裹 div 设 flex 或者 text-align或者给 input 设display: block; margin: 0 auto;和宽度。如果是指 input 里的占位文字或输入文字居中那用text-align: center作用在 input 上。table 怎么居中table 默认是块级但宽度由内容撑开给它margin: 0 auto就行或者父容器text-align: center也能让 table 居中因为 table 在显示规则上比较特殊它在父容器里表现为类似 inline-block 的行为。3. 文本与字体属性文字是页面里占比最大的内容一个页面去掉图片和留白剩下的大部分都是文字。文本属性看起来零碎但组合起来能实现非常多的视觉效果包括热搜词里提到的删除线、字体渐变、外描边、段落分割线等。3.1 字体族与单位选择先聊font-family。它设置字体族可以写多个备选浏览器从左到右依次找找到哪个用哪个body { font-family: PingFang SC, Microsoft YaHei, Helvetica Neue, Arial, sans-serif; }中文网站推荐把中文字体放前面英文字体放后面最后一定加一个通用族名 sans-serif 兜底。字体名如果有空格或中文建议加引号。font-size的单位选择是很多新手纠结的点。px绝对大小最好理解em是相对父元素的父级 16px子元素1.5em就是 24px但嵌套层级多了会连环放大不好控制rem是相对根元素html的默认 16px所以1rem就是 16px2rem就是 32px它不受父级影响是目前团队协作里的主流单位。vw/vh是相对视口宽高的100vw就是满屏宽适合做全屏大图或者跟屏幕走的字号。font-weight是字重normal 对应 400bold 对应 700也可以写数字 100~900。要注意的是很多电脑没有对应粗细的字体文件时浏览器会自己模拟加粗效果可能失真。font-style设置斜体italic是字体自带的斜体oblique是强制倾斜正常用 italic 就行。有个综合写法font: italic bold 16px/1.5 PingFang SC, sans-serif;一眼能看出字号行高字体但顺序要求严格不熟练的时候我建议还是分开写可读性更好。3.2 删除线、外描边和字体渐变这几个热搜词都挺实用我一次说清楚。删除线就是text-decoration: line-through常见于商品原价、任务已完成的样式.old-price { text-decoration: line-through; color: #999; }text-decoration还可以组合比如text-decoration: underline dotted red下划线样式、颜色都能调比古早的u标签灵活多了。字体外描边常用的是-webkit-text-stroke.text-outline { font-size: 48px; font-weight: bold; -webkit-text-stroke: 2px #333; color: transparent; }注意-webkit-text-stroke的兼容性在现代浏览器都还行它描的是文字笔画的中线描边偏粗时字形看起来会变细。这个属性做标题艺术字效果特别好但别用在小字号正文上太粗会糊太细又看不出效果。字体渐变是个特别实用的小技巧核心是把背景渐变“裁剪”到文字里.gradient-text { font-size: 40px; font-weight: bold; background: linear-gradient(90deg, #f7971e, #ffd200); -webkit-background-clip: text; background-clip: text; color: transparent; }原理很简单先给元素设置渐变背景然后用background-clip: text把背景裁切成文字形状再把文字颜色设为transparent让文字透出背景渐变。这样实现渐变文字比用图片轻量得多而且文字还能选中、能被屏幕阅读器读到。3.3 行高、字间距与文本对齐line-height可能是文本属性里最容易被误解的一个。它控制的是行与行之间的基线距离更准确说是每行文本占据的高度。单行文本垂直居中的经典技巧就是让line-height等于容器高度因为行高会把文本在行框内撑到一个视觉居中的位置。给 body 设置一个合适的行高如1.5文本可读性会提升一大截。注意line-height不写单位时是相对 font-size 的倍数推荐这种方式它能随字号等比缩放。letter-spacing是字间距word-spacing是词间距。中文排版想做出标题的“高级感”给标题加一点letter-spacing: 2px或4px马上就不一样了但别加太多稀疏过头很难看。text-align是水平对齐方式left默认左对齐center居中right右对齐justify两端对齐。中文正文推荐左对齐或两端对齐两端对齐有时会在大段中文里产生奇怪的字间距需要自己权衡。还有一组很少人专门讲但特别常用的white-space控制空白符的处理nowrap可以禁止换行word-break控制断词方式break-all可以在字符间断开text-overflow配合 overflow 和 white-space 做溢出省略号。这三个组合起来就是后面 5.1 节要讲的单行/多行省略号的实现基础。3.4 段落分割线的几种做法“css 实现段落分割线”这个热搜词对应的场景最常见的就是文章正文里两个段落之间想加一条分割线。最简单的做法是给段落加下边框.separate { padding-bottom: 16px; margin-bottom: 16px; border-bottom: 1px solid #e5e5e5; }第二种是直接用hr标签它默认就是一条横线hr { border: none; border-top: 1px solid #333; margin: 24px 0; }第三种也特别常用就是那种“中间一行字、左右两边各有一条线”的标题比如“——— 热门推荐 ———”。用伪元素实现.section-title { display: flex; align-items: center; text-align: center; } .section-title::before, .section-title::after { content: ; flex: 1; height: 1px; background: #ddd; } .section-title::before { margin-right: 16px; } .section-title::after { margin-left: 16px; }这个方案的巧妙之处在 flex 布局下伪元素会被拉伸flex: 1让两条线自动占满剩余空间不管标题多长都能自适应。4. 动效与交互常用属性让页面“活”起来CSS 不只是静态样式它还能做动效。很多人以为动画必须上 JS其实纯 CSS 能搞定相当多的交互效果而且性能往往更好。4.1 transition 过渡让状态切换不再“干巴巴”transition的作用是让属性变化从“瞬间跳变”变成“平滑过渡”。它最常见的使用场景是配合:hover比如按钮悬停变色.btn { background: #409eff; color: #fff; padding: 8px 20px; border-radius: 4px; transition: background 0.3s ease; } .btn:hover { background: #337ecc; }鼠标悬停上去背景色不是瞬间变而是 0.3 秒内渐变整个交互柔和很多。transition的四个要素要过渡的属性、时长、缓动函数、延迟时间。ease是默认linear是匀速ease-in是先慢后快ease-out是先快后慢ease-in-out是两头慢中间快。缓动函数直接决定手势感想做得“软”一点多用 ease-out。这里必须提醒一个优化点尽量对transform和opacity做过渡而不是width、height、top、left。因为前者不会触发布局重排动画由 GPU 合成非常流畅而后者的过渡会让浏览器不停地重新计算布局页面元素一多就掉帧卡顿。4.2 transform 变换与关键帧动画涟漪扩散案例transform是 CSS 动效的核心它有四个常用函数translate平移、scale缩放、rotate旋转、skew倾斜。“css 平移”这个热搜词指的就是translate.box { transform: translate(50px, 20px); /* 水平向右移 50px垂直向下移 20px */ }它的优势是用 transform 做位移不会触发布局重排比改top/left高效得多。配合前面 2.4 节的居中技巧translate(-50%, -50%)是按元素自身尺寸的百分比位移这种居中方式不依赖父容器布局模式非常好用。再说keyframes关键帧动画。它是真正意义上的“动画”能定义多个阶段的状态而不只是两个状态间过渡keyframes ripple { 0% { transform: scale(1); opacity: 0.6; } 100% { transform: scale(2.5); opacity: 0; } } .ripple-circle { width: 100px; height: 100px; border-radius: 50%; background: rgba(64, 158, 255, 0.4); animation: ripple 1.5s ease-out infinite; }这就是“涟漪光圈扩散”效果的实现一个圆形元素通过 scale 从 1 放大到 2.5同时 opacity 从 0.6 降到 0再配上infinite无限循环视觉上就是水面涟漪不断扩散。如果你想做一圈一圈往外扩散的多层涟漪用::before和::after各做一个带延迟的动画就行animation-delay: 0.5s错开时间效果直接翻倍。4.3 伪类与交互状态CSS 里的“鼠标移入事件”严格来说CSS 没有事件这个概念。热搜词“css 鼠标移入事件”本质上是伪类:hover在起作用。CSS 有很多状态相关的伪类最常用的三个是:hover、:focus、:active。:hover是鼠标悬停:focus是元素获得焦点比如 input 被点击进入输入状态:active是元素被按下还没松开的那一瞬间。组合使用可以让交互更细腻比如按钮按下时的微反馈.btn { transform: scale(1); transition: transform 0.15s ease; } .btn:hover { transform: scale(1.05); } .btn:active { transform: scale(0.95); }这个效果虽然只有一点点缩放但用户点击体验完全不同按钮“按下去”的手感就出来了。类似地输入框聚焦时给个边框高亮也是:focusbox-shadow实现的。4.4 CSS Tab 控件实现思路热搜词里有条“最酷的 css tab 控件”Tab 切换过去总觉得一定要 JS其实纯 CSS 就能做而且思路还挺巧妙。核心是利用input typeradio的单选特性 label标签的for属性 兄弟选择器~/* 隐藏 radio 输入 */ .tab input { display: none; } .tab label { cursor: pointer; padding: 6px 16px; border-bottom: 2px solid transparent; } .tab-content { display: none; } /* 选中某个 radio 时让它后面的标签高亮 */ #tab1:checked ~ .tab-labels label[fortab1] { border-bottom-color: #409eff; color: #409eff; } /* 选中某个 radio 时展示对应的内容面板 */ #tab1:checked ~ .tab-panels .panel1 { display: block; }原理就是把 radio 的隐藏状态当作“开关”:checked伪类选中后通过兄弟选择器影响后面的元素。纯 CSS 实现的好处是零 JS 依赖、逻辑直观、切换速度快配合 transition 还能做淡入淡出。缺点是状态没法跨页面保存但对于纯展示型 Tab 完全够用。5. 常见问题与排查技巧踩过的坑最值钱写 CSS 不是一路顺畅的大部分时间都在和“样式不对”作斗争。我把这些年最常见的几个场景一次性讲透每个都是能直接抄作业的解决方案。5.1 文本溢出省略号单行与多行实现“css 两行超出……”这个热搜词已经很明确了就是文本超出容器后显示省略号。单行省略号方案.single-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }三个属性缺一不可white-space: nowrap禁止换行overflow: hidden隐藏溢出内容text-overflow: ellipsis用省略号代表被隐藏的部分。多行省略号目前主流方案还是-webkit-line-clamp虽然带-webkit-前缀但现代浏览器基本全支持.multi-line { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }这里的原理是display: -webkit-box启用老式弹性盒模型-webkit-line-clamp: 2限制显示两行超出部分隐藏。注意这几条必须写在同一个元素上容器高度不要写死让内容自己撑到两行高度再截断。5.2 样式不生效的排查思路遇到样式不生效先别慌按这几步排查能解决九成问题。第一检查选择器拼写和权重。看看目标元素有没有被更具体的选择器命中。比如你写.block .title但目标元素根本不在.block里面那就选中不了。第二检查样式引入顺序和位置。后加载的样式会覆盖前面的有时候你在文件末尾加的样式反而不生效是因为前面有个!important。第三检查浏览器默认样式。比如 button 在浏览器里自带背景色和边框你写background: none才能去掉。第四检查元素是否被其他元素遮挡。有时候样式生效了但被别的元素盖住了看不见调整 z-index 或检查定位就行。接这个思路我给个搜“css 样式表中使用*的优缺点”对应场景的建议——通配选择器初始化确实会把一些默认样式干掉比如p的上下间距、列表的缩进如果你重置后发现排版“太挤”就要知道不是浏览器坏了而是默认样式被你清了。5.3 CSS 常用属性分类速查学 CSS不用把每个属性都背下来但脑子里要建立一个分类体系。我平时记属性是分五类记的分类高频属性直观作用布局类display、position、float、flex、grid决定元素在页面上的位置和排布方式盒模型类width、height、margin、padding、border、box-sizing、border-radius决定元素盒子内部和外部的尺寸间距文本类font-size、font-weight、line-height、text-align、text-decoration、color决定文字的字形、大小、颜色、排版背景与视觉效果background、box-shadow、text-shadow、opacity决定元素的颜色、阴影、透明度等观感动效与交互transition、transform、animation、hover、focus决定元素的动态变化和交互反馈这套思维框架帮我省了大量查文档的时间。遇到任何样式需求先想“这个问题属于哪一类”再想这一类的常用属性有哪些组合基本都能解决。5.4 排查工具浏览器开发者工具是最好老师排查 CSS 问题最高效的手段不是问别人而是打开浏览器开发者工具。按 F12 打开后点左上角的箭头图标再点页面上出问题的元素右侧就会出现它的全部样式。这里重点看两个面板Styles 面板会列出命中的所有 CSS 规则哪条生效、哪条被划掉了一眼就能看出来。被划掉的通常就是优先级不够往上看有没有权重更大的选择器即可。Computed 面板会显示该元素最终计算后的所有属性值以及盒模型的实时图示边框、内边距、外边距各占多少像素鼠标一放上去就知道。我调试时有个习惯遇到布局对不齐的问题随手给有嫌疑的元素加个 1px 的红色边框或者醒目的背景色看它实际占的区域在哪里。这个“临时加边框定位法”用到熟练比任何调试工具都直觉化。再透露一个日常习惯写样式时先把基础的 reset 和全局变量放最前面组件样式放中间页面独占的覆盖样式放最后。这样规则从上到下、从全局到局部同优先级时后者覆盖前者基本不会出现“拼命用 !important 改”的尴尬局面。后期维护你自己都会感谢这个配色和结构。这个内容后续往深了走可以再聊响应式布局的媒体查询、Grid 布局的十二栅格设计、CSS 变量与主题切换、容器查询等新特性。但基础打得牢上层这些新东西上手都很快。
返回列表