ARTICLE DETAIL

资讯详情

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

H5与CSS核心考点整理:从布局原理到微信生态实战

H5与CSS核心考点整理:从布局原理到微信生态实战 这些年面试和带人我最大的体会是很多人技术上能做页面但一问到原理就卡壳。原因不是不努力而是缺少一份足够系统的整理。H5和CSS的知识点看起来零散其实都是围绕几个核心问题转的。我花了不少时间把面试中反复出现、以及日常开发里容易踩坑的H5/CSS内容整理成了这份八股文。本文会从HTML5基础到移动端实战再到CSS高级特效把高频考点和常见问题一次性讲透。不管你是准备跳槽还是想系统过一遍基础都可以直接拿来当对照清单。1. 从HTML5基础到H5业务先把概念边界划清楚1.1 H5到底是HTML5还是泛指移动端页面这是面试开场最常见的一问也是很多人容易含糊的地方。严格来说H5是HTML5的简称指第五版HTML标准。但实际业务里大家说的“H5页面”通常泛指运行在移动端浏览器、微信、企业微信、App内WebView里的网页。这个歧义本身就会影响后续沟通所以面试时我会先讲清楚两者的关系HTML5是技术标准H5是业务形态。移动端H5页面不一定用到了所有HTML5特性但它大概率依赖了HTML5的能力比如本地存储、地理位置、canvas、音视频等。从热搜词“h5能调用微信小程序当前经纬度不”能看出很多人把H5的能力边界和小程序能力混在一起。H5本身有Geolocation API但移动端浏览器对它的支持差异很大所以微信生态里通常用JS-SDK来定位。这些细节我会在后面的微信实战章节展开。1.2 语义化标签的好处和常用标签HTML5最直接的变化是语义化标签。以前的页面用div堆结构现在有了header、nav、main、article、section、aside、footer。面试时问语义化好处至少要能说出三点对SEO更友好搜索引擎能正确识别页面结构和重要内容。对屏幕阅读器和辅助技术更友好方便无障碍访问。提高代码可读性和团队协作效率结构一目了然。其中section和article的区别是高频问题。article是独立的、可单独分发的内容比如一篇帖子、一条评论section更偏向对页面内容进行分区强调一组相关内容。举例来说一篇文章是article文章里的“摘要”“正文”“作者介绍”是section。一个简单的判断标准去掉当前标签内容放到RSS里是否还是完整的如果是就用article。1.3 本地存储方案怎么选H5存储相关的八股文几乎必问核心是localStorage、sessionStorage、cookie三者的对比。对比项cookielocalStoragesessionStorage容量约4KB约5MB约5MB有效期可设置默认关闭浏览器失效永久保留除非手动清除标签页关闭失效作用域同源所有页面共享同源所有页面共享同一标签页内共享请求携带自动携带在请求头中不会自动携带不会自动携带存储类型字符串字符串字符串cookie自动携带这件事经常被忽略。正是因为它在每个请求头里都会被发送所以不宜放大量数据否则会增加网络开销。localStorage和sessionStorage适合存一些业务里需要持久化或会话内共享的普通数据复杂结构用JSON序列化后存储。如果数据量更大、需要索引查询就要上IndexedDB了但它API偏底层实际项目中用封装库或者直接用Dexie会更顺手。1.4 路由模式与页面通信移动端H5的“路由”很多时候不在面试范围内但只要涉及单页应用必然绕不开hash和history。hash路由通过监听hashchange实现兼容性好刷新不会404history路由使用history.pushState和popstateURL更干净但刷新时需要服务器配合重定向到入口页面。很多部署问题比如uniapp打包后出现“连接服务器超时点击屏幕重试”本质上就是history路由刷新后服务端没做try_files回退导致的。H5和宿主App、小程序的通信也是近年来常见考点。常见方式有URL传递参数适合初始化数据。通过JSBridge调用原生能力比如定位、扫码、分享。通过window.postMessage与WebView宿主通信。小程序web-view里用wx.miniProgram.postMessage与小程序通信。2. CSS选择器、层叠和继承这些底牌必须摸清2.1 选择器的优先级计算与十个典型选择器CSS优先级我建议直接按权重得分来记!important最高其次是内联样式然后是ID选择器接着是class、属性、伪类再其次是元素选择器和伪元素。通配符、组合器不增加权重。一个常见权重计数是内联1000ID 100class/属性/伪类10元素/伪元素1。但要注意这个100/10/1不是十进制数只是用来比较大小的。比如class选择器再多也不会超过一个ID。真正面试时与其背权重不如能脱口而出几个高频选择器后代选择器div p子代选择器div p相邻兄弟选择器h2 p通用兄弟选择器h2 ~ p属性选择器[typetext]结构伪类li:nth-child(2)、li:first-child、li:last-child状态伪类:hover、:focus、:disabled否定伪类:not(.active)其中nth-child和nth-of-type的区别是经典坑nth-child计数所有兄弟元素nth-of-type只计算同类型元素。比如给p元素写p:nth-child(2)如果父元素第二个子节点是span那这个p不会选中但p:nth-of-type(2)选中的是父元素下第二个p元素。2.2 层叠上下文是什么为什么z-index会失效很多同学问“我明明设了z-index:9999为什么还是被盖住了”。答案多半是层叠上下文。z-index不是全局排序而是在同一层叠上下文内比较。以下属性都会创建层叠上下文position为relative/absolute/fixed且z-index不为auto。transform不为none。opacity小于1。filter不为none。will-change指定了以上相关属性。举例一个父元素设置了transform: translateZ(0)它的z-index可能很低那么无论子元素z-index多大也不会超过另一个z-index更大的兄弟层。解决思路不是继续加大z-index而是检查父级层叠上下文调整父级层级或者只让高层级元素创建独立上下文。2.3 CSS变量和伪元素变量控制的玩法CSS自定义属性是这些年CSS里很好用的能力。定义在:root上全局可用也可以定义在任意选择器里局部可用。用法:root { --primary-color: #4caf50; --radius: 8px; } .button { color: var(--primary-color); border-radius: var(--radius); }热搜词里有“css 控制伪元素变量”这个思路很实用。因为伪元素不能直接设置HTML属性但可以先在元素上用CSS变量定义然后在伪元素里使用.tag::before { content: attr(data-icon); color: var(--tag-color, #333); }注意CSS变量是继承的所以你在父元素上设置--tag-color伪元素里就能读到。这种方式经常用来做主题切换、组件定制。2.4 原子化CSS是趋势还是炒作原子化CSSUtility-First CSS这两年讨论很多代表是Tailwind CSS。它把常见样式拆成单一功能类比如flex、pt-4、text-center组合使用。好处是样式不容易失控、可复用性高、打包时能摇树坏处是HTML类名很长、设计系统需要约束、团队需要接受新的工作模式。面试被问到这个建议不要说“就是炒作”也不要无脑吹。比较稳妥的回答是原子化CSS适合组件化开发、设计规范明确的团队能显著减少维护成本和CSS体积但项目已经有成熟设计系统或需要大量微调样式时传统语义化CSS仍然有它的价值。3. Flex和Grid布局从会用到底层逻辑的补齐3.1 Flex布局的父项与子项属性一次说清Flex布局是CSS中最重要的布局方案之一。先看容器属性flex-direction决定主轴方向默认rowflex-wrap控制换行justify-content控制主轴对齐align-items控制交叉轴对齐gap控制项目间距。子项属性里flex-grow是放大比例flex-shrink是缩小比例flex-basis是初始主轴尺寸。flex: 1实际上是flex: 1 1 0%表示可以放大、可以缩小、初始尺寸为0。flex: auto是flex: 1 1 auto即按内容尺寸放大。面试里常让手写垂直居中标准答案是用flex.parent { display: flex; align-items: center; justify-content: center; }热搜词“css div适中在底部”这个“适中”我理解是“固定在底部”。用flex也可以父容器flex-direction: column子元素margin-top: auto就能把当前块推到底部。用Grid同样可以。这是布局题里常见的“底部固定”场景。3.2 Grid布局的核心属性与典型应用Grid是二维布局方案可以同时控制行和列。核心属性.grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: 100px auto 100px; gap: 16px; }repeat(3, 1fr)就是三等分。minmax(200px, 1fr)表示最小200px剩余空间等分。auto-fit和auto-fill的区别也常考auto-fill在空间充足时会继续创建空轨道auto-fit则会压缩空轨道让项目占满。Grid和Flex怎么选我的原则是如果只需要处理一个方向上的排列用Flex如果需要对行和列同时控制用Grid。比如整页布局、卡片网格、复杂dashboardGrid更顺手。但不能说Flex可以完全替代Grid二者能力边界不同。3.3 布局场景底部固定、圣杯、两栏自适应实际面试里除了问属性还要会做几个经典布局。两栏自适应是常见题左边宽度固定右边占满剩余空间。用Flex一行搞定.container { display: flex; } .left { width: 200px; } .right { flex: 1; }圣杯布局在传统方案里很复杂但用Grid可以很清爽.layout { display: grid; grid-template-columns: 200px 1fr 200px; grid-template-rows: 60px 1fr 60px; grid-template-areas: header header header left content right footer footer footer; }这个例子能同时考察grid-template-areas的掌握程度面试效果很好。3.4 盒子模型与border-box到底影响了什么热搜词“css 加边框盒子不变形”说的就是box-sizing。经典坑是元素设置了width: 100px和border: 10px后标准盒模型下实际占用宽度是120px因为content-box的宽不包含padding和border。要想盒子不变形设置box-sizing: border-box让width包含padding和border。全局通常这么写*, *::before, *::after { box-sizing: border-box; }但要清楚border-box不是让盒子“不变形”而是让咱们声明的内容尺寸更符合直觉。面试时如果能把content-box和border-box区别讲得头头是道同时再说一句“移动端适配时会利用这个特性控制实际占用宽度”会加分。4. 文本、字体和显示细节看起来简单做起来翻车4.1 文本溢出截断三件套单行、多行、自定义单行溢出省略是一个经典的CSS组合.ellipsis { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }多行溢出省略在WebKit内核下使用-webkit-line-clamp.multiline { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }但要注意display: -webkit-box不能和flex等布局同时用而且这个方案对非WebKit浏览器支持不完整。如果兼容性要求高可以用max-heightline-height计算近似高度或者用JavaScript截断。热搜词“css 单行显示,超出点点点”对应的就是单行方案我会在项目里直接封装成工具类。4.2 文本位置调整与竖排排版“怎么调整css容器里的文本位置”这个问题其实就是文本对齐。水平text-align: left/center/right/justify。垂直line-height单行、display: flex align-items: center多行容器、或者使用vertical-aligninline元素。注意line-height设置与容器高度相等时单行文字会垂直居中多行文字这种方法会溢出需要改用flex或padding。竖排文字是另一个冷门考点。用writing-mode就能实现.vertical-text { writing-mode: vertical-rl; }还有text-orientation: upright可以让英文字符竖排时保持正立多用于古籍、印章、海报等设计感场景。4.3 字体渐变、背景图和文字效果字体渐变是常被问到的CSS技巧。核心是利用background-clip:.gradient-text { background: linear-gradient(90deg, #ff6a00, #ee0979); -webkit-background-clip: text; background-clip: text; color: transparent; }背景图方面background-size: cover和contain含义要分清楚。cover是铺满容器但不保证图片完整contain是完整显示但可能留白。多背景用逗号分隔经常用来叠加半透明遮罩和渐变。如果给文字加内阴影、金属拉丝或描边效果可以组合text-shadow、text-stroke、background-clip:text面试时能现场写出字体渐变已经够用。4.4 hover延迟关闭和交互细节热搜词“css hover延迟关闭”通常出现在导航菜单场景。鼠标从菜单项移动到下拉菜单时如果hover状态立刻消失菜单会闪一下。解决方法是给离开状态添加transition-delay.menu-item .dropdown { opacity: 0; visibility: hidden; transition: opacity 0.2s, visibility 0.2s; transition-delay: 0.15s; } .menu-item:hover .dropdown { opacity: 1; visibility: visible; transition-delay: 0s; }这里还涉及一个细节visibility可以配合transition做延迟显隐避免opacity:0的元素仍然可以点击。也可以用JS定时器延迟但纯CSS实现更轻量面试时能主动提到这个方案会显得经验老道。5. 高级CSS特效实战mask、渐变、波浪、旋转与金光5.1 CSS mask遮罩的基本用法热搜词里的“css mask”在面试里不算高频但一旦用到就是亮点。mask-image允许你用图片或渐变来控制元素哪些区域透明。最典型的应用是渐隐遮罩让一张图片底部平滑消失.fade-mask { -webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent); mask-image: linear-gradient(to bottom, #000 70%, transparent); }mask还支持multiple可以叠加多张遮罩。某些场景下mask比clip-path更适合做非线性形状裁切性能也更可控。前端面试时如果让聊“近期研究的一个CSS特性”mask是个不错的切入点。5.2 动态波浪效果的两套实现思路波浪效果在宣传页、加载动画里很常见。热搜词“css波浪效果”我也整理过。最简单的实现是使用多个圆形沿Y轴做位移动画.loader { display: flex; align-items: center; gap: 6px; height: 40px; } .loader span { width: 8px; height: 100%; background: #4caf50; animation: wave 0.9s ease-in-out infinite; } .loader span:nth-child(2) { animation-delay: 0.1s; } .loader span:nth-child(3) { animation-delay: 0.2s; }另一种思路是用SVG path做曲线位移或者用border-radius从圆形到椭圆渐变模拟水波扩散。扩散光圈常用radial-gradient加scale和opacity动画keyframes ripple { 0% { transform: scale(0.8); opacity: 1; } 100% { transform: scale(2); opacity: 0; } }热搜词“css涟漪光圈扩散”对应的就是这种。做的时候注意动画时间曲线用ease-out扩散才自然。5.3 rotate3d、transform-style与3D翻转transform: rotate3d(x, y, z, angle)是CSS 3D变换的核心函数。x、y、z定义旋转轴angle是角度。比如rotate3d(1, 0, 0, 45deg)是绕X轴旋转45度能产生立体的上下翻转效果。要让子元素有3D空间感父级必须加perspective和transform-style: preserve-3d。卡片翻转效果是经典demo.card { perspective: 800px; } .card-inner { transition: transform 0.6s; transform-style: preserve-3d; } .card:hover .card-inner { transform: rotateY(180deg); }需要注意3D变换会创建层叠上下文和包含块有时会影响z-index和fixed定位页面里小心使用。5.4 金光闪闪效果的本质高光扫过、渐变与闪烁热搜词“css如何做出来金光闪闪的效果”我理解通常指金属高光扫过的动画。核心是用一个宽渐变背景通过background-position移动模拟光线扫过.shine { background: linear-gradient(110deg, #b8860b 30%, #ffe27a 50%, #b8860b 70%); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; animation: shine 2s linear infinite; } keyframes shine { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }注意background-size必须大于100%否则没有位移空间。同理按钮上的高光扫过也可以用伪元素加一个白色半透明斜条配合transform: translateX实现。关键点是“渐变背景位移文字透明色”三个条件缺一不可。5.5 动画性能的一个关键只动transform和opacityCSS动画性能是高级前端必备认知。浏览器渲染一个元素需要经过布局、绘制、合成三步。修改width、height、top、left会触发布局代价很大修改color、background会触发绘制而修改transform和opacity可以只走合成性能最好。这也是为什么推荐用transform: translateX(100px)代替left: 100px做位移动画。实际写作里我会加一句并不是所有属性都不能动而是优先用transform和opacity配合will-change提前告知浏览器。6. 微信生态H5实战雷区定位、昵称、支付、下载与跳转6.1 定位h5能调微信小程序当前经纬度吗这个问题几乎每周都会有人问。先说结论H5页面可以获取当前经纬度但在微信生态里不是你调用一下浏览器API就能拿到。首先H5端直接使用navigator.geolocation在微信浏览器里经常失败因为微信内置浏览器对权限管控严格。更靠谱的是使用微信JS-SDK里的wx.getLocation前提是公众号已认证。在公众号后台配置了JS接口安全域名。当前用户已通过网页授权获取openid部分接口需要。引入对应的JS文件并通过wx.config注入签名参数。如果你在小程序web-view里嵌H5同样可以使用JS-SDK但签名需要用小程序对应的AppID。如果小程序端已经授权过定位H5里通常还需要用户点击触发JS-SDK授权不能静默获取。热搜词里“uniapp h5使用腾讯地图获取定位报错:getlocation:fail translate coordinate syst”这个报错我遇到过。它通常是因为uniapp在小程序端返回的是gcj02坐标你的地图组件传入了wgs84坐标或者反过来。解决办法是在uni.getLocation的type参数里显式指定坐标系然后调用腾讯地图时保持一致。比如都用gcj02就不要再转wgs84。还有一种可能是腾讯地图JS SDK没有正确引入建议先确认类型传参再排查SDK加载。6.2 获取微信昵称的边界“h5页面获取微信昵称”在以前是可以通过wx.getUserInfo接口拿到的但微信隐私政策调整后这个能力已经被回收。现在的正确做法是在小程序端使用头像昵称填写能力也就是button open-typechooseAvatar和input typenickname。H5页面本身无法直接拿到用户微信昵称除非你是通过开放平台拿到用户信息授权或者由小程序web-view场景下通过小程序侧把昵称传进来。面试时如果被问直接说清楚H5获取微信昵称不是一个合法稳定的能力微信早已改为用户手动填写。6.3 微信公众号H5打开小程序、小程序跳转H5微信公众号的H5页面如果想打开小程序需要在小程序后台绑定关联然后在H5里使用微信开放标签wx-open-launch-weapp。这个标签是自定义组件需要引入JS-SDK并且wx.config成功后使用。示例结构wx-open-launch-weapp appid你的小程序AppID pathpages/index/index template button去小程序/button /template /wx-open-launch-weapp注意按钮样式需要写在template里且不能使用内联事件。同时要监听error事件处理未绑定等异常。反过来小程序跳转H5则是通过web-view组件src指向你的H5地址。要注意域名需要在小程序后台配置业务域名且校验文件需要放在站点根目录。如果H5和小程序都是你维护的可以通过postMessage实现双向通信。uniapp项目里“微信小程序跳转h5”本质就是把web-view包一层通过message监听H5传过来的数据。6.4 H5支付、企微文件下载和分享卡片H5支付在微信里特指jsapi支付/公众号支付。它需要商户号开通对应产品权限在公众号后台配置支付目录。同时页面必须在微信内打开再通过WeixinJSBridge或JS-SDK调用。京东h5支付这类电商场景重点往往在支付成功回调、订单状态同步、以及iOS和Android差异。要注意鸿蒙微信曾出现无法H5支付的情况主要是内核兼容问题临时方案是引导用户复制链接到浏览器打开或者使用小程序支付。企业微信里H5文件下载是另一个高频问题。企微内置浏览器对下载行为限制很严直接a标签download经常不生效。我的经验是先尝试使用企业微信JS-SDK的checkJsApi和downloadFile接口如果不行在页面上提供“在浏览器中打开”的二维码引导。分享卡片也是类似H5分享到微信好友需要配置JS-SDK的分享参数updateAppMessageShareData并且分享的标题、描述、缩略图都要经过域名校验。7. 稳定输出性能优化、Vue深度选择器和部署避坑7.1 CSS性能优化与渲染层H5页面首屏性能CSS也是重要因素。几个常见优化点减少重排避免频繁修改布局属性能用transform就不用top/left。避免过深选择器通配符、标签选择器配合过多后代选择器会拖慢匹配速度不过现代浏览器已经没有过去那么敏感但仍要控制复杂度。使用content-visibility: auto可以让屏幕外内容跳过渲染适合长列表页面。图片要配合样式一致性比如固定尺寸的容器设置aspect-ratio避免图片加载后产生布局抖动。面试被问到“首屏优化”除了代码分割、路由懒加载也要提到CSS层面的优化比如关键CSS内联、非关键CSS异步加载。7.2 CSS deep方法vue scoped样式穿透热搜词“css deep方法”对应的就是Vue scoped样式穿透。Vue单文件组件里加了scoped后会给元素添加data-v-xxxx属性样式选择器也会带上属性选择器。但是子组件根元素、第三方组件内部元素可能没有这个data属性于是样式失效。解决方法是深度选择器。Vue 2传统写法是/deep/或::v-deepVue 3推荐使用:deep().parent :deep(.child-class) { color: red; }注意在uniapp项目里小程序平台对::v-deep的兼容性不如:deep()建议统一用:deep()。另外要尽量避免把scoped样式穿透到第三方组件内部去改样式紧急解决没问题但长期维护会很痛苦。更好的做法是给第三方组件外层加class或使用CSS变量覆盖。7.3 uniapp打包H5常见问题热搜词“uniapp打包h5 出现连接服务器超时,点击屏幕重试的页面 不想让她出现出现就自动”这个看起来很具体。出现这个页面通常是因为uniapp的App.vue里onLaunch请求接口超时或者路由初始化失败。常见原因接口请求地址在浏览器环境不可达。路由模式为history刷新或直接访问二级页面时服务器没有配置回退。uniapp内置的请求超时时间太短服务器响应慢。解决办法一是把路由模式改为hash避免服务端配置问题二是在nginx上配置try_files $uri $uri/ /index.html;三是排查请求报错如果接口需要用户登录态登录态失效也要做统一处理。热搜词里说“不想让她出现出现就自动”其实就是要捕获异常后跳转而不是停留在错误页。可以在main.js里通过uni.addInterceptor或网络请求封装统一处理。7.4 移动端兼容性小程序苹果底部兼容苹果手机底部横条Home Indicator会挡住操作按钮这是移动端H5经典兼容问题。解决方案是使用viewport-fitcover再配合safe-area-inset-bottommeta nameviewport contentwidthdevice-width, initial-scale1, viewport-fitcover.safe-bottom { padding-bottom: constant(safe-area-inset-bottom); /* iOS 11.0-11.2 */ padding-bottom: env(safe-area-inset-bottom); /* iOS 11.2 */ }小程序里的苹果底部兼容也可以使用env(safe-area-inset-bottom)。热搜词“小程序苹果底部兼容css”对应的就是这段。注意不同平台对constant和env的支持有差异建议先写constant再写env让新浏览器覆盖旧写法。最后关于这份整理我想补一句整理这份东西的时候我把这些年踩过的坑又过了一遍。很多问题看起来是“背八股”但真正理解的标志是能用自己的话把原理讲清楚并且能举出实际项目里的例子。比如CSS选择器优先级不是背1000/100/10/1而是调试样式时能猜到可能被谁覆盖flex和grid不是背属性而是拿到设计稿能快速决定用什么方案微信生态的定位、支付、分享不是看文档就够更要在真机和不同端上多跑几遍。这篇整理不会让你一步登天但如果你能把每个知识点都结合自己的项目问一遍为什么面试和日常开发都会轻松很多。后续我还会整理JavaScript篇、工程化篇、性能优化篇持续把散落的知识拼图补齐。
返回列表