Recently, a group of friends asked me, one of their assignments, try to use as few tags as possible to achieve such a chess layout:
He used more than 60 tags , while his classmates only used 6 , and asked me if there was a way to use as few tags as possible to complete this layout effect.
In fact, for the layout of a page, fewer tags are not necessarily a good thing . While considering the consumption of DOM, we also need to pay attention to the readability of the code and the ease of subsequent interaction based on this layout. Wait.
Of course, just how much can we compress the number of tabs from the standpoint of completing this layout with fewer tabs? (does not consider <body>
and <html>
)
The answer is 1 .
This article attempts to use a tag to achieve this effect. Of course, this is just to explore the limits of CSS, and it does not mean that I recommend writing this way in actual business.
We split the entire layout, which can be roughly divided into three parts: grid + dotted cross + special symbols:
And, with more than one dashed cross and special symbols, there are bound to be some tricks here.
Meshes with gradients
OK, first, we implement the simplest grid layout:
Without considering the outermost border, we can first implement a grid layout using multiple linear gradients :
<div class="g-grid"></div>
.g-grid {
width: 401px;
height: 451px;
background:
repeating-linear-gradient(#000, #000 1px, transparent 1px, transparent 50px),
repeating-linear-gradient(90deg, #000, #000 1px, transparent 1px, transparent 50px);
background-repeat: no-repeat;
background-size: 100% 100%, 100% 100%;
background-position: 0 0, 0 0;
}
The effect is as follows:
There are many ways to add a border to the outermost layer. Here we simply use outline
with outline-offset
:
.g-grid {
width: 401px;
height: 451px;
background:
repeating-linear-gradient(#000, #000 1px, transparent 1px, transparent 50px),
repeating-linear-gradient(90deg, #000, #000 1px, transparent 1px, transparent 50px);
background-repeat: no-repeat;
background-size: 100% 100%, 100% 100%;
background-position: 0 0, 0 0;
outline: 1px solid #000;
outline-offset: 5px;
}
In this way, a shelf is almost:
Of course, there is no grid in the middle row of the chessboard. To process the above gradient code, it can be divided into upper and lower parts, separated by background-size
and background-position
.
Of course, we can also layer a pure white gradient directly on the top layer:
.grid {
// ...
background:
// 最上层叠加一层白色渐变
linear-gradient(#fff, #fff),
// 下面两个重复线性渐变实现网格
repeating-linear-gradient(#000, #000 1px, transparent 1px, transparent 50px),
repeating-linear-gradient(90deg, #000, #000 1px, transparent 1px, transparent 50px);
background-repeat: no-repeat;
background-size: calc(100% - 2px) 49px, 100% 100%, 100% 100%;
background-position: 1px 201px, 0 0, 0 0;
}
At this point, in fact, the core is still gradient. At present, there are 3 layers of gradient, and this effect is obtained:
Cross-dotted cross using gradient
OK, let's move on, we need to get two dashed crosses based on the above foundation, like this:
It's actually really difficult here. Imagine if you were given a DIV to implement one of them, what would you do?
Dashed by the peculiar dashed line in the border? This may require two elements to set a single-sided dashed border, and then rotate to intersect. (It can be implemented in a DOM using two pseudo-elements of the element).
Of course, in this case, our labels would not be enough.
So, here we take a different approach and keep using gradients !
First of all, let's make a sample. If it is a 100px x 100px DIV, how can I use the gradient to draw a cross dotted cross ?
<div></div>
div {
position: relative;
margin: auto;
width: 100px;
height: 100px;
border: 1px solid #000;
background: linear-gradient(
45deg,
transparent 0, transparent calc(50% - 0.5px),
#000 calc(50% - 0.5px), #000 calc(50% + 0.5px),
transparent calc(50% + 0.5px), transparent 0);
}
We first use the gradient to achieve a 1px oblique line. Note that the gradient here is from transparent to black to transparent , achieving a 45° oblique line.
We reverse 45° and use multiple linear gradients to achieve a transparent to white gradient effect:
div {
position: relative;
margin: auto;
width: 100px;
height: 100px;
border: 1px solid #000;
background:
// 渐变 1
repeating-linear-gradient(-45deg, transparent 0, transparent 5px, #fff 5px, #fff 10px),
// 渐变 2
linear-gradient(45deg,
transparent 0, transparent calc(50% - 0.5px),
#000 calc(50% - 0.5px), #000 calc(50% + 0.5px),
transparent calc(50% + 0.5px), transparent 0);
}
This way, we get a dashed line:
Well, in this step, some students may have a little doubt, how to change it.
I changed the transparent color of gradient 1 above to black, and it is easy to understand:
Imagine that the black part of the picture above, if it is transparent, can reveal the place where the original slash is not blocked by white.
Here, it needs to be mentioned that in the gradient, the more the gradient is written first, the higher the level.
Well, with the above foreshadowing, based on the above code, we will continue to use the gradient to fill in the upper and lower cross dotted lines:
.g-grid {
width: 401px;
height: 451px;
outline: 1px solid #000;
outline-offset: 5px;
background:
// 最上层的白色块,挡住中间的网格
linear-gradient(#fff, #fff),
// 实现网格布局
repeating-linear-gradient(#000, #000 1px, transparent 1px, transparent 50px),
repeating-linear-gradient(90deg, #000, #000 1px, transparent 1px, transparent 50px),
// 棋盘上方的虚线1
repeating-linear-gradient(-45deg, transparent 0, transparent 5px, #fff 5px, #fff 10px),
linear-gradient(45deg, transparent,
transparent calc(50% - 0.5px),
#000 calc(50% - 0.5px),
#000 calc(50% + 0.5px),
transparent calc(50% + 0.5px),
transparent 0),
// 棋盘上方的虚线2
repeating-linear-gradient(45deg, transparent 0, transparent 5px, #fff 5px, #fff 10px),
linear-gradient(-45deg, transparent,
transparent calc(50% - 0.5px),
#000 calc(50% - 0.5px),
#000 calc(50% + 0.5px),
transparent calc(50% + 0.5px),
transparent 0),
// 棋盘下方的虚线1
repeating-linear-gradient(-45deg, transparent 0, transparent 5px, #fff 5px, #fff 10px),
linear-gradient(45deg, transparent,
transparent calc(50% - 0.5px),
#000 calc(50% - 0.5px),
#000 calc(50% + 0.5px),
transparent calc(50% + 0.5px),
transparent 0),
// 棋盘下方的虚线2
repeating-linear-gradient(45deg, transparent 0, transparent 5px, #fff 5px, #fff 10px),
linear-gradient(-45deg, transparent,
transparent calc(50% - 0.5px),
#000 calc(50% - 0.5px),
#000 calc(50% + 0.5px),
transparent calc(50% + 0.5px),
transparent 0);
background-repeat: no-repeat;
background-size:
calc(100% - 2px) 49px, 100% 100%, 100% 100%,
// 交叉虚线 1
100px 100px, 100px 100px, 100px 100px, 100px 100px,
// 交叉虚线 2
100px 100px, 100px 100px, 100px 100px, 100px 100px;
background-position:
1px 201px, 0 0, 0 0,
// 交叉虚线 1
151px 0, 151px 0, 151px 0, 151px 0,
// 交叉虚线 2
151px 350px, 151px 350px, 151px 350px, 151px 350px;
}
Oh, this gradient code is indeed a bit complicated, but in fact, the role of each block is very clear, so our chessboard becomes like this:
Remaining conformance with pseudo-elements and box-shadow
So far, we have only used the element itself, you know, we still have two pseudo-elements of the element that are not used. All that's left to implement is multiple of this conformance:
Since there are a total of 12 such symbols to be implemented, some matches are still incomplete, all of which are done in the two pseudo-elements of the remaining elements. The optional method has come and gone, and there is only box-shadow .
Using box-shadow
can replicate itself very well. This technique has actually been repeated many times.
We first use a pseudo-element of the element, and at this position, implement a dash:
The code is roughly as follows:
.g-grid {
// ...
&::before {
content: "";
position: absolute;
top: 95px;
left: 35px;
width: 10px;
height: 1px;
background: #000;
}
}
We use box-shadow
to copy itself to complete the half horizontal line effect. Of course, since it is a mirror layout, you can use the mirror image -webkit-box-reflect: below
to reduce the code by half:
.g-grid {
// ...
&::before {
content: "";
position: absolute;
top: 95px;
left: 35px;
width: 10px;
height: 1px;
background: #000;
box-shadow:
20px 0, 0 10px, 20px 10px,
300px 0, 320px 0, 300px 10px, 320px 10px,
-30px 50px, -30px 60px,
50px 50px, 50px 60px, 70px 50px, 70px 60px,
150px 50px, 150px 60px, 170px 50px, 170px 60px,
250px 50px, 250px 60px, 270px 50px, 270px 60px,
350px 50px, 350px 60px;
-webkit-box-reflect: below 259px;
}
}
The effect is as follows:
Finally, use another pseudo-element to complete the other half of the vertical and horizontal lines:
.g-grid {
// ...
&::before {
// ...
}
&::after {
// ...
box-shadow:
10px 0, 0 20px, 10px 20px,
300px 0px, 300px 20px, 310px 0, 310px 20px,
-40px 50px, -40px 70px,
50px 50px, 50px 70px, 60px 50px, 60px 70px,
150px 50px, 150px 70px, 160px 50px, 160px 70px,
250px 50px, 250px 70px, 260px 50px, 260px 70px,
350px 50px, 350px 70px;
-webkit-box-reflect: below 260px;
}
}
In this way, we are in a label and get this effect:
Of course, there are still four characters, Chuhe and Hanjie , which can be simply added to the div. With some simple CSS adjustments, the whole effect can be completed in one tag:
You can click here for the complete code: CodePen Demo -- CSS Chess board
Well, in fact, I really don't recommend writing this way, it is purely for implementation, and there are many less considerations for code readability. Therefore, this article is more to bring you some ideas, and when you encounter similar problems, you can have more inspiration.
at last
Well, this is the end of this article, I hope this article will help you :)
More wonderful CSS technical articles are summarized in my Github -- iCSS , which will be updated continuously. Welcome to click star to subscribe to the collection.
If you have any questions or suggestions, you can communicate more. Original articles are limited in writing and knowledge. If there are any inaccuracies in the article, please let me know.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。