谁向云端着此亭,檐前树木映窗棂。
-- 释绍嵩《陪赵知府登桃岭山亭》

(image from 中国窗棂)

The traditional Chinese window lattice has a symmetrical beauty, as well as a very beautiful formal name -- 窗棂.

As a CSS lover, I've always wanted to draw them with CSS by hand. But that's never being easy. I thought using SVG might be much straightforward until I learned how to apply the -webkit-box-reflect property.

The property

Unfortunately, -webkit-box-reflect is non-standard. The standard way is to use element() function, which has been implemented in Firefox already.

Honestly the -webkit-box-reflect property seems much elegant to me because it has a better name and it doesn't rely on an extra id like element()does. I don't get why it wasn't accepted by the CSS WG.

There's also an article in detail about reflection in CSS along with several demos by Ana Tudor back from 2016.

Directions

The -webkit-box-reflect property provides four directions of reflection:abovebelowleft and right. This is how to use it:

.box {
-webkit-box-reflect: above|below|left|right;
}

Perhaps because it's just an experimental property from the very beginning, there's no way yet to add multiple reflections to an element at once.

I think it would be much cooler to have multiple reflections and reflections in various degrees other than only 4 of them.

It's still exciting

Let's start with a single div element and its reflection on the right side.

<div>△</div>

<style>
div {
-webkit-box-reflect: right;
}
</div>

How to add another reflection?

Not long ago Chris Coyier introduced a trick in this article, about how to add shadows to a clipped element by applying drop-shadow to its parent node.

Yes, we can do something similar by adding a parent node and setting reflection to it.

<div class="parent">
<div class="box">△</div>
</div> <style>
.box {
-webkit-box-reflect: right;
}
.parent {
-webkit-box-reflect: below;
}
</style>

It's like unfolding a sheet of paper, first in half from left to right and then top to bottom. However, the order doesn't really matter.

Although it's not the exact result we wanted, it's so exciting to find a way to add multiple reflections.

Going deep

The total number of elements grows exponentially in this way, which is dependent on the depth of the nested divs.

So given 2 nested divs like the above, there will be 2^2 = 4 elements (including all the reflections). Given 7 of them will be 2^7 = 128 elements.

Seed

The innermost div can be treated as a seed. Since the whole graph composed with reflections will change with it.

For example, rotate it with -45 degree:

...
<div>
<div>
<div class="seed">△</div>
</div>
</div>
... <style>
/* ... */
.seed {
/* ... */
transform: rotate(-45deg);
}
</style>

Or combine with any other properties and some old methods. It seems another different way to build Unicode Patterns as well.

Chinese Window Lattice

So with the -webkit-box-reflect property and the technique described above, we can finally draw those symmetrical window lattices in CSS with very few lines of code.

I want to take the picture at the beginning of the article as an example. Let's see how to draw them step by step.

1. The seed element

First, find out the smallest part that can't be divided any further. Here we start from the part in the upper left corner as the seed element.

And then draw these lines with background linear-gradient. Using :emptyselector to target the seed element for simplicity.

<div></div>

<style>
div:empty {
width: 72px; height: 72px;
--g: linear-gradient(#000, #000);
--gs: linear-gradient(-45deg,
transparent calc(50% - 1px), #000 calc(50% - 1px),
#000 calc(50% + 1px), transparent calc(50% + 1px)
);
background:
var(--g) 0 0 / 100% 2px, var(--g) 100% 0 / 2px 48px,
var(--g) 100% 48px / 24px 2px, var(--g) 48px 100% / 2px 24px,
var(--g) 0 100% / 48px 2px, var(--g) 0 0 / 2px 100%,
var(--g) 0 46px / 24px 2px, var(--g) 24px 100% / 2px 26px,
var(--g) 100% 24px / 26px 2px, var(--g) 46px 0 / 2px 24px,
var(--gs) 50% 50% / 24px 24px, var(--gs) 0 0 / 40px 40px;
background-repeat: no-repeat;
}
</style>

2. Add reflection

The reflection begins with the seed element itself. We pick "right" as an initial direction and use custom property to make it more intuitive.

<div style="--reflect: right -3px"></div>

<style>
div {
-webkit-box-reflect: var(--reflect);
}
div:empty {
/* ... */
}
</style>

3. Continue unfolding

So we're going to add parent nodes for more reflections. It really helps to understand if you think of it as unfolding a sheet of paper.

<div style="--reflect: below -2px"></div>
<div style="--reflect: right -3px"></div>
</div>

Add another one.

<div style="--reflect: below calc(200% - 6px)"></div>
<div style="--reflect: below -2px"></div>
<div style="--reflect: right -3px"></div>
</div>
</div>

Repeat the process until we get the desired result.

<div style="--reflect: right calc(600% - 14px)">
<div style="--reflect: right calc(200% - 6px)">
<div style="--reflect: below calc(400% - 10px)">
<div style="--reflect: below calc(200% - 6px)">
<div style="--reflect: below -2px">
<div style="--reflect: right -2px"></div>
</div>
</div>
</div>
</div>
</div>

That's it.

You can see the result and the complete source code on CodePen. But you know it works only in Chrome and Safari.

Conclusion

The solution using -webkit-box-reflect property is beautiful in some way. I really wish it had been accepted as a standard and can even do reflections in various directions. So that it may be possible to do JianZhi (Chinese Paper-cutting Art) in CSS.

from:https://yuanchuan.dev/2019/05/15/window-lattice-and-css.html

Chinese Window Lattice And CSS的更多相关文章

  1. 巧用 -webkit-box-reflect 倒影实现各类动效

    在很久之前的一篇文章,有讲到 -webkit-box-reflect 这个属性 -- 从倒影说起,谈谈 CSS 继承 inherit -webkit-box-reflect 是一个非常有意思的属性,它 ...

  2. 关于获取、设置css样式封装的函数入门版

    <html> <head> <meta charset="UTF-8"> <title>CSS样式的获取和设置:简单版</ti ...

  3. Css动画形式弹出遮罩层,内容区上下左右居中于不定宽高的容器中

    <!DOCTYPE html> <html> <head> </head> <body id="body"> <! ...

  4. css+js回到顶部

    .backToTop { display: none; width: 18px; line-height: 1.2; padding: 5px 0; background-color: #000; c ...

  5. 第四十二课:基于CSS的动画引擎

    由于低版本浏览器不支持css3 animation,因此我们需要根据浏览器来选择不同的动画引擎.如果浏览器支持css3 animation,那么就使用此动画引擎,如果不支持,就使用javascript ...

  6. 【翻译】CSS水平和垂直居中的12种方法

    英语原文链接 在CSS中有许多不同的方法能够做到水平和垂直居中,但很难去选择合适的那个.我会向你展示我所看到的所有的方法,帮助你在所面对的情境下选择最棒的那一个. 方法1 此方法将只能垂直居中单行文本 ...

  7. HTML/CSS实现的一个列表页

    又到休息日,白天没事跟朋友去逛逛街,侃大山,晚上了,上网无趣,于是就想起该练练了, 这次是做了一个页面,最上面是一个banner 用到了一个jQuery的逻辑判断当banner初始top值小于wind ...

  8. BOM 浏览器对象模型_window 对象的常见 window.属性_window.方法

    1. 常用属性 window.devicePixelRatio        像素比 = css / 物理像素 window.scrollX,window.scrollY    滚动条 卷曲距离 if ...

  9. 从CSS到houdini

    0. 前言 平时写CSS,感觉有很多多余的代码或者不好实现的方法,于是有了预处理器的解决方案,主旨是write less &do more.其实原生css中,用上css变量也不差,加上bem命 ...

随机推荐

  1. badge徽章、挂件模版

    markdown语法 Gitee卡片 Gitee挂件 Github挂件 Gitee卡片 [![gqzdev/ForFuture Group](https://gitee.com/zhong96/sho ...

  2. 2、gitlab使用及权限管理

    目录 1.创建用户组... 2 2.创建用户... 4 3.新建项目... 5 4.linux端访问项目... 6 4.1 通过ssh方式访问... 6 4.2 通过http访问... 9 5.win ...

  3. 巨杉数据库入选年度Gartner Peer Insights报告,获得市场高度评价

    Gartner Peer Insights 年度评选结果于近日出炉,在数据库管理系统市场报告中,巨杉数据库获得了总平均分4.7(满分5分)的成绩,在众多国际厂商中位居第三,是国内唯一一家入选的数据库厂 ...

  4. Django中content-type组件的使用

    content-type组件 ContentType是Django的内置的一个应用,可以追踪项目的所有APP和model的对应关系,并记录在ContentTpe表中,当我们的项目做数据迁移后,会有很多 ...

  5. 什么是kafka,怎么使用? (2) - 内含zookeeper等

    zookeeper依赖于java https://baike.baidu.com/item/yum/2835771?fr=aladdin http://yum.baseurl.org/ 去yum官网下 ...

  6. 解决jmeter 24h长时间压测-o生成报告文件达到几个g以及以上的问题

    问题描述:jmeter执行稳定性测试时,因时间过长,导致jtl文件过大,生成html报告过程报内存溢出错误(增加内存配置也不能解决) 使用 jmeter -n -t    test.jmx   -l  ...

  7. 【牛客小白月赛21】NC201604 Audio

    [牛客小白月赛21]NC201604 Audio 题目链接 题目大意: 给出三点 ,求到三点距离相等的点 的坐标. 解析 考点:计算几何基础. 初中蒟蒻表示不会什么法向量.高斯消元..qwq 方法一: ...

  8. pybind11简介

    python调用C/C++有不少的方法,如boost.python, swig, ctypes, pybind11等,这些方法有繁有简,而pybind11的优点是对C++ 11支持很好,API比较简单 ...

  9. iframe宽高自适应

    iframe子页面结尾添加本script iframe子页面结尾添加本script <script type="text/javascript">         fu ...

  10. 关于memset....我太难了

    众所周知memset是个清空数组的好东西 然而...它慢的要死 直接让我从30ms炸到1045ms 于是快乐tle .... 是我的错 所以以后还是手动清空 (我真快乐)