四年一度的世界杯正在炽热进行中,有没有熬夜看你喜爱的队伍较量呢。在这欢庆的气氛中,我决定用代码参加一把世界杯,擦边参加,那就是用CSS画一个足球场,失常的用CSS布局必定是十分easy的,所以决定只用一个div实现,接下来开始注释。

足球场的尺寸

画之前首先要获取几个要害地位的尺寸,查问度娘的后果如下:

  • 场地:长105米,宽68米;
  • 球门:长7.32米,高2.44米;
  • 大禁区(罚球区):长40.32米,宽16.5米;
  • 小禁区(球门区):长18.32米,宽5.5米
  • 中圈区:半径9.15米;
  • 角球去:半径1米;
  • 罚球弧:半径9.15的半圆

基于这份数据定义一些根本的变量,本次实现基于下面的值乘以2作为像素值,局部小区域数值有所调整。整体变量定义如下:

:root {  --lineColor: #fff;  --fieldWidth: 210px;  --fieldHeight: 136px;  --centerCircle: 18px;  --cornerCircle: 4px;  --grandForbiddenAreaWidth: 32px;  --grandForbiddenAreaHeight: 80px;  --smallRestrictedAreaWidth: 11px;  --smallRestrictedAreaHeight: 36px;  --goalWidth: 4px;  --goalHeight: 14px;}

CSS倒影

这里用到了CSS倒影 box-reflect,因为只能用一个div,所以要尽可能利用现有的CSS能力,缩小额定的代码量。足球场实质是一个对称图形,在这里应用CSS倒影就很适合,如果不思考只用一个div,还能够屡次应用倒影。本次CSS逻辑只实现内容左侧局部,右侧内容由 box-reflect 倒影实现。

-webkit-box-reflect: right;

实现过程

首先减少边框局部,本文所有的线条都是按2px实现。

div {  width: calc(var(--fieldWidth) / 2);  height: var(--fieldHeight);  border: 2px solid var(--lineColor);}


接下来开始画核心局部的圆圈,因为只应用一个div,所以将大量应用CSS突变实现各种线条局部内容,这里须要留神的中央是有倒影的应用代码上只须要画出半圆,所以要减少 no-repeat 防止在左侧绘制出另一半圆。

radial-gradient(  circle,  #0000 var(--centerCircle) 0,  var(--lineColor) calc(var(--centerCircle)),  var(--lineColor) calc(var(--centerCircle) + 2px),  #0000 calc(var(--centerCircle) + 2px)) no-repeat calc(var(--fieldWidth) / 4) 50% / 100% 100%

而后绘制四个角落的角球区域圆圈,高低两个角球局部须要离开绘制,外围代码都是一样,只是 background-position 的地位不一样。

// 下面角球 1/4 圆radial-gradient(  circle,   #0000 var(--cornerCircle),  var(--lineColor) calc(var(--cornerCircle)),  var(--lineColor) calc(var(--cornerCircle) + 2px),  #0000 calc(var(--cornerCircle) + 2px)) no-repeat calc(var(--fieldWidth) / 4 * -1) calc(var(--fieldHeight) / 2 * -1) / 100%

而后绘制大禁区局部,这部分实质是一个矩形,然而右边线条和底部的线条是重合的,所以还须要绘制残余的三根线条,这里为了缩小一部分代码,其中两条线应用 conic-gradient 绘制,残余的一条线应用 linear-gradient 绘制。

conic-gradient(  from -90deg at right 2px bottom 2px,   rgba(31, 157, 161, 0) 0 90deg,#fff 0) 0 calc((var(--fieldHeight) - var(--grandForbiddenAreaHeight)) / 2)/var(--grandForbiddenAreaWidth) var(--grandForbiddenAreaHeight) no-repeat,linear-gradient(  0deg,  var(--lineColor) 2px,  #0000 2px) 0px calc((var(--fieldHeight) - var(--grandForbiddenAreaHeight)) / 2)/var(--grandForbiddenAreaWidth) 2px no-repeat

小禁区和大禁区实现形式是一样的,只是在于区域的大小尺寸不一样,减少两个禁区后的成果如下:

接下来绘制罚球弧,这个是一条圆弧,貌似突变不能单纯的只绘制一条弧线,如果有晓得的欢送交换,这里应用伪元素实现,基于伪元素的边框加圆角并暗藏其中的三边边框即可达到冀望的成果。

&::after {  ...  border: 2px solid #fff;  border-radius: 50%;  background: #0000;  border-top-color: #0000;  border-left-color: #0000;  border-bottom-color: #0000;}

此时的根本效果图曾经差不多了,再应用另外一个伪元素绘制一下球门的地位。

最初再减少一下球场内的草坪成果。这里应用了反复线性突变,代码如下:

repeating-linear-gradient(  90deg,  #56a224 0px,  #56a224 10px,   #a9da27 10px,   #a9da27 20px)

最初残缺的效果图如下:

在线代码:https://code.juejin.cn/pen/71...

最初

残缺的实现过程就完结了,这只是一种实现的思路,在理论的我的项目中不倡议应用,除此之外也还有很多其余的实现形式,欢送探讨你的实现形式。看完感觉有用记得点个赞再走,珍藏起来说不定哪天就用上啦~

专一前端开发,分享前端相干技术干货,公众号:南城大前端(ID: nanchengfe)