<div class="canvas"></div> .canvas { width: 80vmin; height: 80vmin; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); border: 1px solid #ddd; background-image: repeating-linear-gradient(transparent 0 9.85%, #ddd 0 10%), repeating-linear-gradient(to right, transparent 0 9.85%, #ddd 0 10%); }注意:为了能够精确地放置不同的元素,画布必须设置为相对或绝对定位。
<div class="canvas"> <div class="head"> <div class="cheek"></div> <div class="cheek"></div> <div class="eye"></div> <div class="eye"></div> </div> </div> .canvas { --skin: #fca; /* 肤色 */ --eyes: #630a; /* 眼睛颜色 */ --cheeks: #f001; /* 脸颊红晕颜色 */ /* ... 堆代码 duidaima.com */ /* ... 其他样式 */ } /* ... 其他样式 */ .head { --positionX: 28%; /* 水平定位 */ --positionY: 63%; /* 垂直定位 */ position: absolute; top: 10%; left: 50%; border-radius: 50%; width: 25%; height: 25%; transform: translate(-50%, 0); background: var(--skin); } .eye { position: absolute; top: var(--positionY); left: var(--positionX); width: 12%; height: 12%; background: var(--eyes); border-radius: 50%; } .eye + .eye { left: auto; right: var(--positionX); } .cheek { position: absolute; top: calc(var(--positionY) + 7%); left: calc(var(--positionX) - 12%); width: 20%; height: 12%; background: var(--cheeks); border-radius: 50%; } .cheek + .cheek { left: auto; right: calc(var(--positionX) - 12%); }
<div class="canvas"> <div class="beard"></div> <div class="head"> <div class="cheek"></div> <div class="cheek"></div> <div class="eye"></div> <div class="eye"></div> <div class="mustache"></div> <div class="mustache"></div> <div class="hat"></div> </div> </div> .canvas { --beard: #eee; /* 胡须颜色 */ --mustache: #fff; /* 小胡子颜色 */ /* ... 其他样式 */ } /* ... 其他样式 */ .beard { position: absolute; top: 10%; left: 50%; width: 30%; height: 40%; background: var(--beard); transform: translate(-50%, 0); border-radius: 100% / 120% 120% 80% 80%; /* 椭圆形胡须的边框半径 */ } .mustache { position: absolute; top: 88%; left: 52%; width: 40%; height: 40%; background: var(--mustache); border-radius: 100% 10% 100% 0; /* 小胡子的边框半径 */ transform-origin: top right; transform: translate(-100%, 0) rotate(25deg); } .mustache + .mustache { left: 48%; border-radius: 10% 100% 0 100%; /* 相邻小胡子的边框半径 */ transform-origin: top left; transform: rotate(-25deg); }以上就是如何用CSS创建圣诞老人的胡须和小胡子的详细步骤。通过简单的形状和位置调整,我们就能够创造出有趣的效果。这种技术不仅能用来创造节日图像,同样也可以应用到其他各种各样的图形设计中。
<div class="canvas"> <div class="beard"></div> <div class="head"> <div class="cheek"></div> <div class="cheek"></div> <div class="eye"></div> <div class="eye"></div> <div class="mustache"></div> <div class="mustache"></div> <div class="hat"></div> </div> </div> html { background: #bcd; /* 背景色 */ } .canvas { --suit: #d00; /* 帽子颜色 */ /* ... 其他样式 */ } /* ... 其他样式 */ .hat { position: absolute; width: 98%; height: 80%; background: var(--suit); border-radius: 100% 20% 0 0; /* 帽子主体的边框半径 */ top: -40%; left: 50%; transform: translate(-50%, 0) rotate(1deg); } .hat::before { content: ""; /* 重要:即使没有内容,也必须设置content属性 */ display: block; position: absolute; bottom: -17%; left: -5%; width: 110%; height: 40%; border-radius: 100% / 50%; /* 帽子底部的边框半径 */ transform: rotate(-2deg); background: radial-gradient(200% 100% at 50% 100%, #0000 30%, var(--mustache) 31%); /* 底部渐变 */ } .hat::after { content: ""; /* 球状饰品 */ display: block; position: absolute; right: -25%; top: -15%; width: 40%; aspect-ratio: 1; /* 保持宽高比 */ border-radius: 50%; /* 圆形 */ background: var(--beard); /* 球状饰品的颜色 */ }通过上面的步骤,我们可以完成一个有帽檐和球状饰品的圣诞帽。整个过程不仅锻炼了我们对CSS伪元素的运用,还让我们的圣诞老人看起来更加完整和可爱。
<div class="canvas"> <div class="body"></div> <div class="beard"></div> <div class="head"> <div class="cheek"></div> <div class="cheek"></div> <div class="eye"></div> <div class="eye"></div> <div class="mustache"></div> <div class="mustache"></div> <div class="hat"></div> </div> </div> .canvas { --belt: #222; /* 腰带颜色 */ /* ... 其他样式 */ } /* ... 其他样式 */ .body { position: absolute; top: 35%; left: 50%; width: 50%; height: 50%; background: var(--suit); /* 身体颜色 */ border-radius: 100% / 150% 150% 25% 25%; /* 身体形状的边框半径 */ transform: translate(-50%, 0); background-image: radial-gradient(circle at 50% -50%, transparent 75%, var(--belt) 75.1% 83%, transparent 83.1%), linear-gradient(to right, transparent 42%, white 42.2% 57%, transparent 57.2%); }注意,在身体的渐变中,后一个渐变不是恰好从前一个渐变结束的地方开始,而是添加了一个小数点。这是因为浏览器对CSS渐变的边缘处理过于锐利(SVG则不会),这个小数点有助于平滑边缘。
<div class="canvas"> <div class="body"> <div class="belt"></div> </div> <div class="beard"></div> <div class="head"> <div class="cheek"></div> <div class="cheek"></div> <div class="eye"></div> <div class="eye"></div> <div class="mustache"></div> <div class="mustache"></div> <div class="hat"></div> </div> </div> .canvas { --belt-buckle: gold; /* 腰带扣颜色 */ /* ... 其他样式 */ } /* ... 其他样式 */ .body { /* ... */ background-image: /* 按钮 */ radial-gradient(circle at 50% 36%, var(--belt) 2.75%, #0000 3%), radial-gradient(circle at 50% 48%, var(--belt) 3%, #0000 3.25%), radial-gradient(circle at 50% 60%, var(--belt) 2.75%, #0000 3%), radial-gradient(circle at 50% 90%, var(--belt) 2.25%, #0000 2.5%), /* 腰带 */ radial-gradient(circle at 50% -50%, transparent 75%, var(--belt) 75.1% 83%, transparent 83.1%), /* 底部翻边 */ linear-gradient(to right, transparent 42%, white 42.2% 57%, transparent 57.2%); clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 51% 100%, 50% 96%, 49% 100%, 0% 100%); } .belt { /* ... */ background: linear-gradient(var(--belt-buckle) 0 0) 75% 50% / 25% 12% no-repeat, linear-gradient(var(--belt) 0 0) 50% 50% / 85% 80% no-repeat, var(--belt-buckle); }
<div class="canvas"> <div class="hand"></div> <div class="hand"></div> <div class="arms"></div> <div class="body"> <div class="belt"></div> </div> <div class="beard"></div> <div class="head"> <div class="cheek"></div> <div class="cheek"></div> <div class="eye"></div> <div class="eye"></div> <div class="mustache"></div> <div class="mustache"></div> <div class="hat"></div> </div> </div> .arms { position: absolute; top: 37%; left: 50%; transform: translate(-50%, 0); width: 65%; height: 40%; background: #a00; /* 手臂的颜色 */ border-radius: 100% / 170% 170% 25% 25%; /* 手臂的形状 */ background-image: linear-gradient(transparent 20%, #0003); /* 手臂的渐变阴影 */ } .hand { --positionX: 18%; /* 手的水平定位 */ position: absolute; top: 70%; left: var(--positionX); width: 13%; height: 13%; background: var(--belt); /* 手的颜色 */ border-radius: 50%; /* 手的圆形 */ } .hand + .hand { left: auto; right: var(--positionX); }现在,我们的圣诞老人的上半部分已经完成了。这甚至可以作为网站的一个可爱元素(例如,从页面底部动画弹出)。通过这些步骤,我们的圣诞老人变得越来越可爱,为网站添加了节日的气息和趣味性。
<div class="canvas"> <div class="hand"></div> <div class="hand"></div> <div class="arms"></div> <div class="leg"></div> <div class="leg"></div> <div class="body"> <div class="belt"></div> </div> <div class="beard"></div> <div class="head"> <div class="cheek"></div> <div class="cheek"></div> <div class="eye"></div> <div class="eye"></div> <div class="mustache"></div> <div class="mustache"></div> <div class="hat"></div> </div> </div> .leg { position: absolute; top: 75%; left: 29%; width: 19%; height: 25%; background: var(--suit); /* 腿部的颜色 */ transform: skew(2deg); /* 腿部的倾斜 */ background-image: linear-gradient(#0002, transparent 70%, var(--belt) 0); /* 裤子和靴子的分界线 */ } .leg + .leg { left: 52%; /* 第二条腿的位置 */ } .leg::after { content: ""; display: block; position: absolute; bottom: 0; left: -6%; width: 110%; height: 20%; background: black; /* 靴尖的颜色 */ border-radius: 50% / 100% 100% 0 0; /* 靴尖的圆角 */ } .leg + .leg::after { left: -4%; /* 第二个靴尖的位置 */ }
html { background: #abc; /* 背景色 */ overflow: hidden; background-image: radial-gradient(circle at 50% 50%, white 2.5%, transparent 0), radial-gradient(circle at 30% 90%, white 1.5%, transparent 0), radial-gradient(circle at 70% 10%, white 1%, transparent 0), radial-gradient(circle at 10% 40%, white 1%, transparent 0); background-size: 45vmin 35vmin, 50vmin 70vmin, 60vmin 50vmin, 65vmin 60vmin; background-position: 0 0; } .canvas::before { content: ""; display: block; position: absolute; top: 90%; left: 50%; width: 200vmax; height: 200vmax; background: white; /* 地面颜色 */ transform: translate(-50%, 0) rotate(1deg); border-radius: 100% / 20%; /* 地面的弯曲度 */ } /* ... */
@keyframes snow { 0% { background-position: 0 0, 0 0, 0 0, 0 0; } 40% { background-position: 10px 14vmin, -20px 28vmin, 20px 20vmin, 10px 24vmin; } 60% { background-position: -10px 21vmin, -30px 42vmin, 30px 30vmin, 15px 36vmin; } 100% { background-position: 0 35vmin, 0 70vmin, 0 50vmin, 0 60vmin; } } // 堆代码 duidaima.com @keyframes blink { 0%, 6%, 100% { height: 12%; } 3% { height: 0%; } } @keyframes moveMustache { 0%, 40%, 44%, 100% { transform: translate(-100%, 0) rotate(25deg); } 42% { transform: translate(-100%, 0) rotate(30deg); } } @keyframes moveMustache2 { 0%, 40%, 44%, 100% { transform: rotate(-25deg); } 42% { transform: rotate(-30deg); } } html { animation: snow infinite 7s linear; /* ... */ } .eye { animation: blink 5s infinite linear; /* ... */ } .mustache { animation: moveMustache 7s infinite linear; /* ... */ } .mustache + .mustache { animation: moveMustache2 7s infinite linear; /* ... */ } /* ... */重要的是要考虑用户的意愿,如果用户选择减少运动(特别是考虑到辅助功能),则应该禁用动画。我们可以使用prefers-reduced-motion媒体功能来实现这一点。
@media (prefers-reduced-motion) { * { animation: none !important; } }这个选择器过于泛化。如果你在网站上嵌入了这个圣诞老人的绘图,你可能需要调整它,以免影响你页面上的其他动画。
<div class="canvas" role="img" aria-label="一个站在雪地小山上的圣诞老人卡通形象。"> <!-- ... --> </div>通过这样做,我们就完成了使CSS艺术作品更易于辅助技术访问的过程。
此外,您可以随意添加更多细节:增加眉毛会很好,帽子下露出一些头发,圣诞老人周围放一些礼物,甚至在某个地方添加一个驯鹿!
.canvas { width: 80vmin; aspect-ratio: 1; /* 移除 height */ /* ... */ }通过移除高度并指定aspect-ratio为1,画布将始终保持正方形。由于我们在所有尺寸和背景中使用了百分比,我们可以将宽度改变为我们想要的任何值,绘图都会很好地缩放。例如,将宽度设置为200像素后,效果如下:
<div class="canvas" role="img" aria-label="一个站在雪地小山上的圣诞老人卡通形象。"> <div class="hand"></div> <div class="hand"></div> <div class="arms"></div> <div class="leg"></div> <div class="leg"></div> <div class="body"> <div class="belt"></div> </div> <div class="beard"></div> <div class="head"> <div class="cheek"></div> <div class="cheek"></div> <div class="eye"></div> <div class="eye"></div> <div class="mustache"></div> <div class="mustache"></div> <div class="hat"></div> </div> </div> @keyframes snow { 0% { background-position: 0 0, 0 0, 0 0, 0 0; } 40% { background-position: 10px 14vmin, -20px 28vmin, 20px 20vmin, 10px 24vmin; } 60% { background-position: -10px 21vmin, -30px 42vmin, 30px 30vmin, 15px 36vmin; } 100% { background-position: 0 35vmin, 0 70vmin, 0 50vmin, 0 60vmin; } } @keyframes blink { 0%, 6%, 100% { height: 12%; } 3% { height: 0%; } } @keyframes moveMustache { 0%, 40%, 44%, 100% { transform: translate(-100%, 0) rotate(25deg); } 42% { transform: translate(-100%, 0) rotate(30deg); } } @keyframes moveMustache2 { 0%, 40%, 44%, 100% { transform: rotate(-25deg); } 42% { transform: rotate(-30deg); } } @media (prefers-reduced-motion) { * { animation: none !important; } } html { background: #abc; overflow: hidden; background-image: radial-gradient(circle at 50% 50%, white 2.5%, transparent 0), radial-gradient(circle at 30% 90%, white 1.5%, transparent 0), radial-gradient(circle at 70% 10%, white 1%, transparent 0), radial-gradient(circle at 10% 40%, white 1%, transparent 0); background-size: 45vmin 35vmin, 50vmin 70vmin, 60vmin 50vmin, 65vmin 60vmin; background-position: 0 0; animation: snow infinite 7s linear; } .canvas { --skin: #fca; --eyes: #630a; --cheeks: #f001; --beard: #eee; --mustache: #fff; --suit: #a00; --belt: #222; --belt-buckle: gold; width: 60vmin; aspect-ratio: 1; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .canvas::before { content: ""; display: block; position: absolute; top: 90%; left: 50%; width: 200vmax; height: 200vmax; background: white; transform: translate(-50%, 0) rotate(1deg); border-radius: 100% / 20%; } .head { --positionX: 27%; --positionY: 63%; position: absolute; top: 10%; left: 50%; border-radius: 50%; width: 25%; height: 25%; transform: translate(-50%, 0); background: var(--skin); } .eye { position: absolute; top: var(--positionY); left: var(--positionX); width: 12%; height: 12%; background: var(--eyes); border-radius: 50%; animation: blink 5s infinite linear; } .eye + .eye { left: auto; right: var(--positionX); } .cheek { position: absolute; top: calc(var(--positionY) + 7%); left: calc(var(--positionX) - 12%); width: 20%; height: 12%; background: var(--cheeks); border-radius: 50%; } .cheek + .cheek { left: auto; right: calc(var(--positionX) - 12%); } .beard { position: absolute; top: 10%; left: 50%; width: 30%; height: 40%; background: var(--beard); transform: translate(-50%, 0); border-radius: 100% / 120% 120% 80% 80%; } .mustache { position: absolute; top: 88%; left: 52%; width: 40%; height: 40%; background: var(--mustache); border-radius: 100% 10% 100% 0; transform-origin: top right; transform: translate(-100%, 0) rotate(25deg); animation: moveMustache 7s infinite linear; } .mustache + .mustache { left: 48%; border-radius: 10% 100% 0 100%; transform-origin: top left; transform: rotate(-25deg); animation: moveMustache2 7s infinite linear; } .hat { position: absolute; width: 98%; height: 80%; background: var(--suit); border-radius: 100% 20% 0 0; top: -40%; left: 50%; transform: translate(-50%, 0) rotate(1deg); } .hat::before { content: ""; display: block; position: absolute; bottom: -17%; left: -5%; width: 110%; height: 40%; border-radius: 100% / 50%; transform: rotate(-2deg); background: radial-gradient(200% 100% at 50% 100%, #0000 30%, var(--mustache) 31%); } .hat::after { content: ""; display: block; position: absolute; right: -25%; top: -15%; width: 40%; aspect-ratio: 1; border-radius: 50%; background: var(--beard); } .body { position: absolute; top: 35%; left: 50%; width: 50%; height: 50%; background: var(--suit); border-radius: 100% / 150% 150% 25% 25%; transform: translate(-50%, 0); background-image: /* buttons */ radial-gradient(circle at 50% 36%, var(--belt) 2.75%, #0000 3%), radial-gradient(circle at 50% 48%, var(--belt) 3%, #0000 3.25%), radial-gradient(circle at 50% 60%, var(--belt) 2.75%, #0000 3%), radial-gradient(circle at 50% 90%, var(--belt) 2.25%, #0000 2.5%), /* belt */ radial-gradient(circle at 50% -50%, transparent 75%, var(--belt) 75.1% 83%, transparent 83.1%), /* flap */ linear-gradient(to right, transparent 42%, white 42.2% 57%, transparent 57.2%); clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 51% 100%, 50% 96%, 49% 100%, 0% 100%); } .belt { position: absolute; top: 75%; left: 50%; transform: translate(-50%, -50%); width: 23%; height: 15%; background: linear-gradient(var(--belt-buckle) 0 0) 75% 50% / 25% 12% no-repeat, linear-gradient(var(--belt) 0 0) 50% 50% / 85% 80% no-repeat, var(--belt-buckle); } .arms { position: absolute; top: 37%; left: 50%; transform: translate(-50%, 0); width: 65%; height: 40%; background: #a00; border-radius: 100% / 170% 170% 25% 25%; background-image: linear-gradient(transparent 20%, #0003); } .hand { --positionX: 18%; position: absolute; top: 70%; left: var(--positionX); width: 13%; height: 13%; background: var(--belt); border-radius: 50%; } .hand + .hand { left: auto; right: var(--positionX); } .leg { position: absolute; top: 75%; left: 29%; width: 19%; height: 25%; background: var(--suit); transform: skew(2deg); background-image: linear-gradient(#0002, transparent 70%, var(--belt) 0); } .leg + .leg { left: 52%; } .leg::after { content: ""; display: block; position: absolute; bottom: 0; left: -6%; width: 110%; height: 20%; background: black; border-radius: 50% / 100% 100% 0 0; } .leg + .leg::after { left: -4%; }