ARTICLE DETAIL

资讯详情

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

HTML五角星输出指南:实体、CSS与SVG全方案解析

HTML五角星输出指南:实体、CSS与SVG全方案解析 1. 为什么键盘上找不到五角星特殊字符在HTML中的处境1.1 一个常见的误解很多人第一次需要在网页里放一个五角星时第一反应是去键盘上找或者打开输入法的特殊符号面板翻半天。做这个动作的不只是刚学HTML的新手我见过不少写了三五年业务代码的前端真要在页面上放一个星星图标时依然会下意识去搜“五角星符号怎么打”。这个现象背后有个很现实的原因五角星不属于键盘直接按键的字符集。键盘上每个键位对应用ASCII字符区的内容能直接敲出来的是数字、英文字母、加减乘除这些五角星在Unicode里属于“符号”区必须靠别的途径输入。理解了这一点你就明白为什么不管怎么按键盘都打不出这个符号了。1.2 HTML页面里的字符是从哪来的当浏览器拿到一个HTML文档后会按照文档声明的字符编码通常是UTF-8去解码字节流。HTML里出现的每一个可见字符本质上都是“字符集”中的一个码点。五角星对应的码点是U2605实心和U2606空心在HTML代码里你可以用实体引用或数字引用把它标注出来也可以直接把这个字符粘贴进代码里。这里的关键是直接粘贴字符虽然最直观但容易遇到编码问题。比如某个页面是GBK编码的你从其他地方复制了一个五角星贴进去很可能保存后变成乱码这就是字符集不匹配也是很多新手第一次“打”五角星失败的原因。1.3 输出五角星的三层思路我把在HTML里输出五角星的方法分成三层第一层是字符方案用HTML实体或Unicode码点适合在文本、按钮、标题里放一颗小星星代码量最少。第二层是CSS方案用伪元素、裁剪或几何变换生成图形优点是不依赖字体和系统内置符号样式可控性更强。第三层是SVG方案用多边形矢量路径绘制适合做图标、评分大星或多边形组合图形放大后依然清晰锐利。这三层方案我会逐一讲透。很多人只知道第一层做页面时遇到字体不支持、星星显示成方框、或者样式无法调整尺寸的情况就卡住了。读完后面这些内容你应该能从“怎么打一个符号”升级到“怎么在任何场景下稳定输出一个五角星”。2. 最简单的一招HTML实体与Unicode直接输出五角星2.1 实体引用表复制即可用如果你现在只是需要让页面上出现一个五角星最快的办法是复制下面这几行p实心五角星#9733; 或者 starf;/p p空心五角星#9734; 或者 star;/p★ 是U2605的十进制写法★ 是它在HTML里的命名实体☆ 是U2606的十进制写法☆ 是命名实体。两种写法在浏览器里的渲染结果一样区别只体现在代码可读性上。命名实体更直观但数量有限像一些更深僻的星星符号不一定有命名实体所以大多数人习惯直接用数字引用。我建议你在实际项目里优先用数字引用也就是★这种写法。理由有两个第一数字引用不依赖浏览器内置的实体对应关系表几乎所有环境都能解析第二团队的代码规范里一般不会把各种命名实体列全你换个偏门符号比如顶角向上的四角星或者带圈的星号就可能找不到对应的命名实体干脆统一用数字引用省得记。2.2 不只是五角星星星符号全集参考五角星只是星星家族的一员。我做页面设计评审时经常需要在一组星星变体里挑合适的符号这里整理一份比较全的列表符号十进制HTML实体说明★★实心五角星☆☆空心五角星✩✩细线五角星✮✮变形五角星✯✯带圆点装饰的五角星⭐⭐五角星Emoji发光星星其中有几个在字体支持上存在兼容性问题下面第6部分会专门展开讲。你现在只要记住复制就能稳定使用的是★和☆这两颗。2.3 JS和CSS里的Unicode写法很多人搞混一个概念在HTML正文里用★一旦到了CSS里写法就变了。CSS的content属性里要用反斜杠加十六进制码点.star::before { content: \2605; color: #f5a623; font-size: 24px; }而在JavaScript里生成五角星用的是另一种写法const star \u2605; document.getElementById(rating).textContent star;这里有个容易踩的坑HTML数字引用是十进制★CSS和JS里是十六进制Unicode码点\2605和\u2605。9703转成十六进制是2605你必须会这一个换算否则在CSS里对着★照搬是写不出内容的。我平时会直接用浏览器的开发者工具换算或者用Node环境跑一句(9733).toString(16)几秒钟搞定。2.4 关于直接粘贴字符的建议如果你只是本地写一个Demo直接从这篇文章复制★符号粘贴到HTML文件里也能正常显示。前提是文件的字符编码要声明为UTF-8!DOCTYPE html html langzh-CN head meta charsetUTF-8 title五角星测试页/title /head body p★ ☆/p /body /html如果没写这行meta charset浏览器在本地文件场景下可能按系统默认编码解析。中文内容在Windows上有时按GBK解析这时候你粘贴的★本来就是UTF-8字节串就可能被拆成两个乱码字符显示出来。所以我的建议是能复制就直接复制但一定要养成写全DOCTYPE和charset的习惯。这两行代码几乎是每个HTML页面的地基省了它们后面你迟早要吃亏。3. 重绘不重依赖纯CSS画五角星的两种思路3.1 三种方式叠加法利用CSS变换拼出五角星字符方案虽然方便但有一个绕不开的短板字符的样式受字体控制。同一颗★在Windows的宋体里是一种形态在苹果的苹方字体里又是另一种形态把字号调大后边缘还会模糊。遇到需要把五角星当图形用、并且精确定制颜色和大小的情况字符方案就力不从心了。这时候就该考虑纯CSS绘制方案。第一种思路叫“三个等腰三角形叠加法”。原理一句话就能说清楚五角星可以看作三个相同的等腰三角形围绕中心点旋转72度、144度、216度后组合在一起。利用CSS的border绘制三角形再用transform旋转就能拼出一颗星。.star-five { width: 0; height: 0; position: relative; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid #f5a623; } .star-five::before, .star-five::after { content: ; position: absolute; width: 0; height: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-top: 100px solid #f5a623; } .star-five::before { transform: rotate(72deg); left: -50px; top: -100px; } .star-five::after { transform: rotate(-72deg); left: -50px; top: -100px; }这段代码在结构上由三部分组成主体元素是一个底部带颜色的border三角两个伪元素各是一个顶部带颜色的border三角通过旋转拼接出五星轮廓。它的兼容性非常好IE10以上都能正常显示。但说实话这个方案用border画三角形的方式在今天看来有点hack。我讲它的主要价值在于帮你建立几何直觉理解了“三个等腰三角形围绕中心旋转72度”这个逻辑后面用SVG写坐标时你会更清楚每个顶点是怎么来的。3.2 clip-path多边形裁剪现代浏览器里的优雅做法如果是面向现代浏览器的项目我会优先用clip-path。这个属性直接按多边形坐标裁剪元素画五角星非常清爽.star { width: 100px; height: 100px; background: #f5a623; clip-path: polygon( 50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35% ); }这组多边形有10个顶点规律很清晰每隔一个点落在外圈其余的点落在内圈。外顶点比例大概是0%、35%、70%这三个高度内顶点大概在35%、57%、91%这几个高度。官方数值不需要完全背下来我给出一个通用规律外顶点到中心的距离与内顶点到中心的距离之比约为1.618也就是黄金分割比例。只要保证这个比例星星的形状就正。clip-path方案的好处是背景可以是纯色、渐变色、甚至一张图片鼠标悬浮时还能配合transition做形变动效。缺点是IE和旧版Edge不支持。如果页面只是内部系统使用浏览器版本可控这个方案没问题如果要发布面向全网的站点还是需要用SVG或者更保守的方案。3.3 用字符当底图::before 里的实体引用还有一个介于字符和图形之间的小技巧在CSS里直接让一个元素的内容是★再用font-size和color控制大小和颜色。典型场景是列表前的装饰星星li::before { content: \2605; margin-right: 8px; color: #f5c542; }这个写法代码量最少而且语义清晰谁看到:before里的五角星码点都知道这是装饰性星号。缺点是你能控制的范围仅限于字体样式。假如星星需要渐变、阴影或者描边这个方案做不到只能借助SVG。所以在实际项目里我通常把字符装饰用在“不追求像素级精致”的次要位置。4. SVG五角星图形放大不模糊的终极方案4.1 polygon多边形十个顶点画一颗星如果你的五角星要做成大尺寸展示比如页面顶部的主视觉、详情页的评分大图标字符方案和CSS方案都有各自的局限。字符在放大后边缘发虚CSS裁剪的图形虽然清晰但改内部结构比如给星星加一个圆角、调整角的尖锐度很麻烦。这种情况我会直接上SVG。SVG里最直接的方法是使用polygon多边形元素把五个外顶点和五个内顶点交替排列svg width100 height100 viewBox0 0 100 100 xmlnshttp://www.w3.org/2000/svg polygon points50,5 61,38 95,38 68,60 79,95 50,72 21,95 32,60 5,38 39,38 fill#f5a623 stroke#333 stroke-width2/ /svg这组坐标是怎么来的我提供一下推导过程以(50,50)为圆心外半径取45内半径按黄金分割比例取约27.8。然后分别计算18度、90度、162度、234度、306度外顶点以及54度、126度、198度、270度、342度内顶点的正弦余弦值乘以半径并平移到圆心坐标位置。第一次手算这组数确实麻烦所以我给你一个通用公式外顶点坐标(50 R * cos(18° i72°), 50 - R * sin(18° i72°))内顶点坐标(50 r * cos(54° i72°), 50 - r * sin(54° i72°))其中i从0到4R是外半径r ≈ R * 0.3820.382这个数也来自正五边形的几何关系不用过分纠结。你只要记住“内半径约等于外半径的0.382倍”在填坐标时就能算出合理的星形。4.2 path路径更精细的星星控制如果想让星星有更复杂的形状比如尾部拉长或者带弧线polygon就不够用了得用path路径指令。以viewBox 0 0 100 100为例画一颗标准五角星可以这样写svg viewBox0 0 100 100 xmlnshttp://www.w3.org/2000/svg path dM 50,0 L 61,35 L 98,35 L 70,57 L 80,91 L 50,73 L 20,91 L 30,57 L 2,35 L 39,35 Z fill#f5a623/ /svg从M移动到50,0开始然后依次用L画线到各个顶点最后Z闭合路径。这个path在视觉上与polygon渲染结果基本一样但path可以配合stroke做描边效果也可以在CSS动画里逐段绘制路径形成“画笔描边画出星星”的视觉效果。对了如果想做空心五角星只需要把fill改成none加上strokepath dM 50,0 L 61,35 L 98,35 L 70,57 L 80,91 L 50,73 L 20,91 L 30,57 L 2,35 L 39,35 Z fillnone stroke#f5a623 stroke-width4 stroke-linejoinround/stroke-linejoin设为round后星星的尖角衔接处会带一点圆滑视觉上更柔和。这个细节在图标设计里很实用尤其是中等尺寸32px到48px的图标太尖锐的角会显得有攻击性。4.3 内联SVG的三个实操注意事项第一SVG标签可以直接写进HTML文件的body里不需要单独引入文件。浏览器把它当普通DOM元素渲染CSS能控制它的宽高和颜色。宽度高度属性可以直接写在SVG标签上也可以先用CSS写width: 100%; height: auto;再控制父容器。第二如果希望星星的颜色跟随CSS变化比如hover时变色可以在SVG里不写fill属性而是在外部CSS里用path选择器控制.star-icon path { fill: #aaa; transition: fill 0.2s; } .star-icon:hover path { fill: #f5a623; }这里有个前提SVG里不能有内联的fill属性否则内联优先级高于外部CSShover变色不会生效。我见过很多同事踩这个坑把fill直接写在SVG标签上结果外面怎么写CSS都覆盖不掉。第三内联SVG文件体积虽然小但如果页面上有几十颗星星建议用symbol和use组合复用路径。先定义一个symbol然后在需要的地方用use引用svg styledisplay:none symbol idicon-star viewBox0 0 100 100 path dM 50,0 L 61,35 L 98,35 L 70,57 L 80,91 L 50,73 L 20,91 L 30,57 L 2,35 L 39,35 Z/ /symbol /svg svg classstar-icon width24 height24 use href#icon-star/ /svg这样写的好处是路径只维护一份页面里所有星星的样式统一改路径就等于全局更新。这个方案在实际项目中几乎是必须的不然光是复制粘贴几十遍坐标点就让人头大。5. 五角星的实战改造评分组件与装修装饰5.1 商品评分字符星星的典型场景五角星在Web页面里最常见的场景就是评分系统。一个标准的五星评分组件通常包含三颗满星、两颗空星或者支持用户点击打分。用HTML实体可以快速搭建静态效果div classrating>.rating { display: inline-flex; gap: 4px; font-size: 20px; line-height: 1; } .rating .star { width: 1em; text-align: center; }把每颗星的宽度固定为1em再配合居中就能消除字符宽度差异。这个细节如果你不做一般情况下看不出大问题但一旦跟设计稿的像素级标注做比对就会被人一眼看出来星星没有对齐。5.2 半星评分字符方案做不到的事业务里经常碰到小数评分比如4.5分。这时候一半星实心、一半星空心纯字符方案做不了。标准做法是双层叠加底层放一组灰色星星上层放一组金色星星用上层容器的宽度裁剪出半星效果。div classrating div classrating-bg span★★★★★/span /div div classrating-fg stylewidth: 90%; span★★★★★/span /div /div.rating { position: relative; display: inline-block; font-size: 20px; line-height: 1; color: #ddd; } .rating-fg { position: absolute; top: 0; left: 0; overflow: hidden; white-space: nowrap; color: #f5a623; }上层宽度按百分比调整90%就是4.5颗星。要注意底层和上层的两行星星必须使用同样字号和行高否则两层错位。这个方案在大型电商平台的PC端页面里很常见属于经典中的经典值得背下来。5.3 列表装饰与分隔线小星星的多样性除了评分五角星在页面里也经常被用作列表前缀、分隔线花纹和卡片装饰。最常用的写法是给标题两侧各加一颗星h2 span classdeco★/span 精选推荐 span classdeco★/span /h2配合CSS旋转或缩放能让装饰星星不那么死板。比如给左侧星星加一个rotate(-15deg)右侧星星加rotate(15deg)视觉上两边对称但有变化感。另一个用法是做“已评价”的成功提示用一颗大号SVG星星加对勾组合比单纯文字更生动。5.4 动态效果星星动画的轻量实现想让页面里的星星动起来最简单的是CSS旋转。给SVG星星加一个class然后定义animation.spin-star { animation: rotateStar 2s linear infinite; transform-origin: center; } keyframes rotateStar { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }这里有一个容易忽略的点transform-origin一定要设置为center否则旋转中心会在SVG的左上角。如果用字符星星做旋转动画同样要给元素加display: inline-block否则某些浏览器的transform不生效。如果想让星星“点亮”比如从灰色变成金色可以在JavaScript里切换class或者配合CSS的transition实现颜色渐变。这里的性能建议是能用transform和opacity做动画就不要用top/left避免引起整页重排。6. 兼容性雷区与编码陷阱我踩过的真实坑6.1 字体决定字符渲染编码决定页面解析很多人在HTML里输出★后在电脑的Chrome上看得好好的换到手机或者某些国产浏览器上星星却变成了一个方框或者完全消失。这个问题的根因只有一个字体不支持这个字符。系统自带字体里苹果系统的苹方、Windows的微软雅黑都内置了常见的星星字符但某些安卓定制系统的默认字体对U2605的支持不完整导致显示成方框也就是通常说的豆腐块。解决办法有两个给容器设置一个明确包含星星字符的字体族比如font-family: PingFang SC, Microsoft YaHei, Segoe UI Symbol, Arial;如果是重点依赖的图标不要用字符方案改用SVG。第二种方案更稳妥因为没有任何办法能保证用户设备上的字体一定收录了U2605。字符方案只适合“锦上添花”的装饰位置。6.2 meta charset声明粘贴字符乱码的真正原因我接过不少求助代码长这样页面却显示成乱码html head title测试五角星/title /head body p★/p /body /html问题不在★本身而在缺了meta charsetUTF-8。浏览器在解析本地HTML时如果响应头里没有Content-Type声明就会按操作系统的默认区域设置来猜编码。Windows中文系统经常会按GBK猜测而你把文件保存成了UTF-8于是★被拆成两个字节连同中文字符一起全乱了。这个坑特别隐蔽因为你在本地看源代码感觉没问题一旦刷新或者换机器访问就会暴露。所以我的习惯是新建HTML文件时第一行先写DOCTYPE第二行写meta charset哪怕页面里一个中文都没有也要写。代码规范里的每一条习惯背后基本都对应着一个真实的线上故障。6.3 微信内置浏览器的星星渲染一个值得记住的案例还有一个我实际测试时发现的案例同样是★在微信内置浏览器里不同安卓机型表现差异很大。某些机型会把U2605解析成一个位置偏高的符号视觉上跟周围的文本基线对不齐。解决办法是给星星加一个微调定位.star { display: inline-block; transform: translateY(-2px); }不同系统差多少不一样没法一个值通吃但inline-block加transform至少给了你微调的能力。如果你做的是跨端H5页面建议还是用SVG替代星星字符一次性规避这类问题。我在一个活动页里因为这个星星对不齐的问题改了三版最后换SVG才彻底消停。6.4 数字引用还是命名实体协作开发里的选择前面提到过★和★实际上指向同一个字符。多人协作时建议团队统一一个规范。如果严格按照代码规范推荐数字引用原因在第2部分已经说过了。但如果你跟SEO工程师合作对方可能要求页面里出现可读的文本这时候直接放★字符反而比实体更友好因为实体在源码层面是转义后的某些简单的爬虫不一定能正确解析。我在公司内部通常定这样的规矩模板引擎里用命名实体纯静态HTML用数字引用CSS和JS里用Unicode码点。这样既保证可读性又方便代码压缩和转义处理。7. 五角星家族图鉴实心空心与各种风格变体7.1 从五角星到六角星、八角星做页面装饰时不是所有地方都适合正五角星。比如做“质量认证”类元素时六角星和八角星更常见它们的HTML实体代表有符号十进制HTML实体说明✢✢四角星✶✶六角星✷✷八角星✹✹十二角星这些符号的字体支持情况比五角星更差使用前一定要在目标设备上测试。我做官网时用过一次六角星做背景装饰结果在老旧浏览器里直接显示成豆腐块最后全部换成了SVG。这里没什么技巧就是测试、测试、再测试。7.2 Emoji风格的星空颜色自带但样式难控还有一种思路是直接使用Emoji字符⭐U2B50、U1F31F、✨U2728。这些字符在支持彩色Emoji的设备上会显示成彩色省去了写CSS处理颜色的事。但在老旧设备或者某些桌面浏览器上它们会退化成黑白色或者显示成带轮廓的版本。最麻烦的是颜色不能通过CSS的color属性随意修改变成品牌金色更是不可能所以只适合娱乐性场景不适合正式的UI。7.3 自定义锐利度用SVG实现不同“胖瘦”的五角星如果你想要一颗“胖一点”或者“瘦一点”的五角星可以调整内半径和外半径的比值。默认的0.382是几何正五角星比例视觉上比较标准。想更圆润把比值调到0.45想更尖锐调到0.30。修改之后多边形坐标会整体变化如果每次手算太麻烦可以用JavaScript动态生成function generateStarPoints(cx, cy, outerR, innerR, points 5, offset 0) { const step Math.PI / points; let result ; for (let i 0; i points * 2; i) { const r i % 2 0 ? outerR : innerR; const angle offset i * step; const x cx r * Math.sin(angle); const y cy - r * Math.cos(angle); result ${x.toFixed(2)},${y.toFixed(2)} ; } return result.trim(); } console.log(generateStarPoints(50, 50, 45, 27.8));这段代码输出一组polygon可以直接用的坐标点。我把这个函数封装成了工具函数传入圆心坐标、半径和角数就能生成任意角星——不止五角星八角星、十二角星都能做。如果你需要在页面上批量生成多个不同尺寸和颜色的星星配合React或Vue的循环渲染非常方便。就我个人的使用排序来说普通文本装饰我直接用★字符省事需要做评分、绝对可控颜色时用SVG纯CSS的clip-path方案虽然优雅但它的真正价值在于可以跟动画结合做出字符和SVG都不方便实现的效果。不同方案之间不是替代关系而是适用场景不同。你在实际项目里如果拿不准先在小页面上把三种方案各写一遍看目标浏览器上的实际渲染效果用结果做决定。比对着文档瞎猜靠谱得多。
返回列表