深扒那些艺术的CSS_weixin_30399055的博客-程序员秘密

概览

使用单个div做css绘图,会充分利用到:

  • before、after伪元素
  • 使用border-radiusborder来控制图形的形状。
  • 使用叠加的box-shadow来创建多个相同的形状(可以有不同的大小、位置、颜色、模糊)。
  • background-imageborder-image属性上叠加使用渐变(线性、径向、圆锥、重复),叠加的渐变可以有不同的位置、大小颜色。

这几个属性配合起来就可以绘制出许多物体了。

当我们充分利用好了单个div,再用多个div来绘图就更加容易了。

常用属性

1.border与伪元素

bofore、after伪元素会创建一些不在文档树中的元素,并为其添加样式。注意区分伪元素与伪类的区别,看本小节后面的代码示例。

border是分为top、left、right、bottom四个方向的,它们是怎么划分势力范围的呢?答案是平分,像这样:

div {
    position: absolute;
    height: 0em;
    width: 0em;
    background-color: aquamarine;
    border-right: 2em solid red;
    border-bottom: 2em solid blue;
    border-top: 2em solid green;
    border-left: 2em solid yellow;
    /* border-radius: 50%; */
}

1619141-20190709145310479-1608373229.png

给它加一个border-radius:

1619141-20190709145341802-1522834820.png

设置一下height、weight:

1619141-20190709145354128-707847460.png

把border-bottom改成透明色transparent吧:

1619141-20190709145402592-1554861455.png

所以使用四个方向的border结合透明色transparent、border-radius可以轻松画出矩形、三角形、梯形(直角、等腰、不等腰)、弧形、环形

好,改一改画个羽毛球吧

1619141-20190709145416288-1643330835.png

好吧,不怎么像,去掉border-radius再改一改就是喇叭了:

1619141-20190709145427885-101379939.png

再给喇叭加一点音浪,像上面那样利用after、before在喇叭右边画两个1/4圆环吧!

1619141-20190709145438689-1819514616.png

使用rotate旋转的话,元素和它的before、after伪元素是作为整体一起的

1619141-20190709145448942-1272572966.png

我们给喇叭的音浪加一点震动的动画吧

1619141-20190709145515130-619461113.gif

这里要把音波的box-sizing设置为border-box,以免动画中改变border-width而使元素不对齐。

音波小喇叭的完整css代码在下面,也可以在我的codepen里面找到。

        @keyframes shock {
            from{
                border-width: 0.1em;
            }
            to{
                border-width: 0.6em;
            }
        }
        div {
            position: relative;
            height: 2em;
            width: 2em;
            background-color: aquamarine;
            border-right: 2em solid transparent;
            border-bottom: 2em solid white;
            border-top: 2em solid white;
            border-left: 2em solid white;
            border-radius: 0;
        }
        div:after,div:before{
            position: absolute;
            content: '';
            box-sizing: border-box;
            border-radius: 50%;
            border-right: 0.5em solid aquamarine;
            border-bottom: 0.5em solid transparent;
            border-top: 0.5em solid transparent;
        }
        div::after{
            top: -0.5em;
            right:-3.5em;
            height:3em;
            width:3em;
            animation: shock 1s linear 0s infinite alternate;
        }
        div:before{
            top: -2em;
            right:-4.5em;
            height: 6em;
            width: 6em;
            animation: shock 1s linear 0s infinite alternate;

        }

2.border-radius

border-radius用于设置元素外边框圆角,本质上是设置4个圆角对应椭圆的长轴、短轴(共8个轴),轴长可以是百分数或者长度,负值无效。

你可以这样统一设置8个轴为一样的长度:

border-radius: 20px;

1619141-20190709145710950-825433945.png

当然长轴和短轴是可以分开设置的,形如长轴(水平轴) / 短轴(竖轴),后面的同理:

border-radius:20px / 50%;

1619141-20190709145727542-1697366263.png

也可以设置2个值(分别对应左上与右下、右上与左下,其其长轴=短轴=对应值):

border-radius: 20px 60px ;

1619141-20190709145750388-1462216030.png

也可以分别设置4个值(分别对应左上、右上、右下、左下的圆角,其长轴=短轴=对应值):

border-radius: 20px 40px 60px 80px ;

1619141-20190709145812899-508812533.png

综上所诉,你还可以这样写:

border-radius: 20px 80px / 50%;

border-radius: 20px 40px 60px 80px / 50%;

border-radius: 20px 40px 60px 80px / 50% 10% 20% 30%;

3.box-shadow

box-shadow以多个逗号分隔的列表来描述一个或多个阴影,阴影和原元素的形状相同,位置、大小、颜色、模糊可以不同。

box-shadow: h-shadow v-shadow blur spread color inset , ... ;

说明
h-shadow 必需的。水平阴影的相对位置。允许负值
v-shadow 必需的。垂直阴影的相对位置。允许负值
blur 可选。模糊距离
spread 可选。阴影的相对大小
color 可选。阴影的颜色,默认黑色
inset 可选。从外层的阴影(开始时)改变阴影内侧阴影

阴影们按列表顺序渲染,后面的阴影被前面的阴影遮挡覆盖

给出几个栗子?:

外侧阴影:

box-shadow: -10px -10px 10px 0px black;

1619141-20190709145850822-640179049.png

内侧阴影:

box-shadow: -10px -10px 10px 0px black inset;

1619141-20190709145902907-1235881537.png

具象的来区分外侧阴影和内侧阴影大概是这样子:
1619141-20190709145938004-760177626.png

​ 来自灵魂画手这幅画的意思就是:

inset是将元素视为凹进去的物体,没有inset的元素视为凸出来的物体。同一个方向的光线,会使inset的元素阴影打在元素内部,非inset的元素阴影打在元素外部。

我们利用box-shadow可以产生任意个形状相同的阴影,而且阴影可以重叠。

box-shadow: -10px -10px 10px 0px gold inset,
            -10px 10px 20px 0.5em greenyellow inset,
            -20px -20px 10px 1em lightblue inset,
            10em 0 0 0 lightblue,
            5em -10px 10px 0px black ,
            11em -10px 10px 0px black;

1619141-20190709150102373-1291933059.png

足够有耐心的话,你还可以用box-shadow来画像素画,不过没多大必要就是了,像下面这样:

1619141-20190709150113280-1111500015.png

要注意的是box-shadow是盒子模型的阴影,border-radius会改变盒子模型的形状,而border改变的不是盒子模型的形状,所以即使你用border画了个三角形,你的盒子并不是三角形,自然也得不到三角形的阴影。

4.渐变

渐变有linear-gradient、radial-gradient、conic-gradient、reapeating-linear-gradient、repeating-radial-gradient。

渐变可以在任何使用 <image> 的地方使用,例如background-imageborder-image

利用背景渐变可以实现条纹、格子、波点以及各种东西。

线性渐变就是沿着一条渐变线,根据给出的若干色点,构建的一系列垂直于渐变色的着色线。

所以一个线性渐变定义为:

linear-gradient(
[ | to ,]? [, ]+ )

where = [left | right] || [top | bottom]
and = [ | ]?
such as = 45deg | 0.25turn

色点列表的规则

色点是描述了颜色、位置的点,两个色点中间的区域的颜色是介于这两个颜色中间的渐变色。

当两个色点处于同一位置时,就不会有渐变区域,形成鲜明的颜色分界线,这样就可以用来画条纹了。如果是3色以上的条纹,中间的色点可以重复一下,就能保证相邻不同颜色的色点位置相同,像下面这样:

background:linear-gradient(to right,violet 33%,rgb(37, 88, 228) 33%,rgb(37, 88, 228) 66%,#fb3 0%);
            background-repeat: repeat-x;
            background-size: 2.5em;

1619141-20190709150218994-1556206794.png

还有一个常用的规范:

如果某个色标的位置值比整个列表中在它之前的色标的位置值都要小, 则该色标的位置值会被设置为它前面所有色标位置值的最大值。

也就是说:#58a 33%, #fb3 0, #fb3 66%, #e45b5a 0 等价于 #58a 33%, #fb3 0, #fb3 66%, #e45b5a 66%。

除了线性渐变之外,还有径向渐变、圆锥渐变、重复渐变,使用规则也差不多,后面会结合例子来讲解,更详细的文档可以去MDN上查阅。

一个渐变可以有多个色点(绘图时透明色点很有用),一个background-imageborder-image可以叠加多个渐变,有时再配合其他属性(如background-repeat、background-size、border-image-repeat、border-image-width等)来分区域重复绘制,就可以画出很多东西。

那下面就让我也来画一只绿色的蜡笔吧!

终稿如下,同样可以在codepen上尝试一下。

1619141-20190709150232975-2093550214.png

笔头的阴影有点违和,是用radial-gradient画的,在只有div、:before、:after三个元素的情况下我也想不到其他什么了...

懒得码字,解释就交给代码注释了。

.div4{
    position:relative;
    height: 3rem;
    width: 16rem;
    margin:4rem;
    box-sizing: border-box;
    background: #237449;
    background-image:   linear-gradient(178deg,transparent 0,rgba(0, 0, 0, 0.4) 100%),  /*笔身的渐变*/
        linear-gradient(to right,transparent 6% ,rgba(41,237,133,.6) 0, 
            rgba(41,237,133,.6) 12%,rgba(0,0,0,0.3) 0,rgba(0,0,0,0.3) 14%, rgba(41,237,133,.6) 0,   /*从左到右四个细条纹*/
            rgba(41,237,133,.6) 16%,rgba(0,0,0,0.3) 0,rgba(0,0,0,0.3) 18%, rgba(41,237,133,.6) 0,
            rgba(41,237,133,.6) 82%,rgba(0,0,0,0.3) 0,rgba(0,0,0,0.3) 84%, rgba(41,237,133,.6) 0,
            rgba(41,237,133,.6) 86%,rgba(0,0,0,0.3) 0,rgba(0,0,0,0.3) 88%, rgba(41,237,133,.6) 0,
            rgba(41,237,133,.6) 94%, transparent 0),
        radial-gradient(ellipse at top, rgba(2, 37, 18, 0.9) 30%,transparent 0); /*笔身上半椭圆花纹*/
    border-radius:4px;
    box-shadow:2px 3px 3px 0 gray;
}
.div4::before{
    position: absolute;
    left:-3rem;
    top:0.1rem;
    content: '';
    box-sizing: border-box;
    height: 2.8rem;
    width: 1rem;
    border-radius:2px;
    /*梯形的笔头,实际看到的是border部分,所以不能在当前元素直接用backgroung-image来做渐变*/
    border-right: 3rem solid #237449;
    border-bottom: 1.1rem solid transparent;
    border-top: 1.1rem solid transparent;
}
.div4::after{
    position: absolute;
    left: -3rem;
    right: 0;
    content: 'green';
    box-sizing: border-box;
    height: 3.5rem;
    width: 19rem;
    background-image: linear-gradient(to bottom,transparent 25%,rgba(112, 182, 142, 0.3) 40%,transparent 60%),  /*整只笔中间的反光*/
        radial-gradient(ellipse at 2.2rem 3rem,gray,transparent 1.8rem);    /*笔头下方的阴影*/
    /*green字*/
    font-family: Arial, sans-serif;
    font-size: 12px;
    font-weight: bold;
    color: rgba(255,255,255,0.3);
    text-align: right;
    padding: 1.5rem 4rem 0 0 ;
}

参考文章

在不考虑成本的情况下,css是能画出许多有简单几何图形并、补、差得到的图画的。css是潜力十足的,或者应该说,使用css的人们是有无穷潜力的。

不过实际工程中也不需要用css来画很复杂的图像,直接用图片就好了,但用文中的一些技巧也能开发出一些简单、实用、美观的元素效果。

下面的参考文章中还有一些有趣的东西,不妨去看看,看一看别人的神仙操作。

1.基于单个div的CSS绘图

2.CSS Background 之神奇渐变色

3.45个值得收藏的 CSS 形状

转载于:https://www.cnblogs.com/mthz/p/powerfulCss.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30399055/article/details/95338742

智能推荐

Taro微信小程序底部动画弹窗_taro 底部弹出_kyyius的博客-程序员秘密

// 蒙层部分@keyframes slideBgUp { from { visibility: visible; background: transparent; } to { background: rgba(0,0,0,.7); }}@keyframes slideBgDown { from { background: rgba(0, 0 ,0 , .7); } to { background: transparent;

时间编程ctime - C/C++_c++ ctime_生活需要深度的博客-程序员秘密

c++ time函数_C++的日期和时间函数C++ 标准库没有提供所谓的日期类型。C++ 继承了 C 语言用于日期和时间操作的结构和函数。为了使用日期和时间相关的函数和结构,需要在 C++ 程序中引用 &lt;ctime&gt;头文件。有四个与时间相关的类型:clock_t、time_t、size_t 和tm。类型 clock_t、size_t 和 time_t 能够把系统时间和日期表示为某种整数。结构类型 tm 把日期和时间以 C 结构的形式保存,tm 结构的定义如下:#ifndef _TM

在elasticsearch官网查阅文档_elasticsearch官网文档_你的小伙伴啊的博客-程序员秘密

1.进入官网Free and Open Search: The Creators of Elasticsearch, ELK &amp; Kibana | Elastic2.点击docs进入如下:下拉找到Elasticsearch: Store, Search, and Analyze3.点击如下4.进入如下,点击(这里以java为例)5.选择对应版本,再点击如下6.点击快速开始,或者直接下拉查看下面的文档下...

SSD---NVMe介绍_nvme moodle_智小星的博客-程序员秘密

何为NVMe? NVMe即Non-Volatile Memory Express, 是非易失性存储器标准, 是跑在PCIe接口上的协议标准。 NVMe的设计之初就有充分利用了PCIe SSD的低延时以及并行性, 还有当代处理器、 平台与应用的并行性。 相比现在的AHCI标准, NVMe标准可以带来多方面的性能提升。 NVMe为SSD而生, 但不局限于以闪存为媒介的SSD, 它同样可以应用在高性能和低延时的3D XPoint这类新型的介质上。...

简单数字识别 python+tesseract-ocr_python tesseract识别数字_三疯文子的博客-程序员秘密

简单数字识别 python+tesseract-ocr需求实现一个简单数字图片识别功能,并在PC端跑起来场景相机拍照数据图片,程序识别出图片上简单数据并返回工具pycharm环境python3.7 + tesseract-ocr 5.0依赖matplotlib3.1.2numpy1.17.4opencv-python4.1.2.30Pillow6.2.1pyparsi...

run 参数_星月的雨的博客-程序员秘密

1  2345678910111213141516171819202122232425262728293031323334353637383940OPTIONS说明:  -d, --detach=false         

随便推点

引入解释性变量_allenlooplee的博客-程序员秘密

Introduce Explainning Variable(引入解释性变量)Summary: 将该复杂表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式用途。Tips: 在条件逻辑中,Introduce Explaining Variable可以用来将每个条件子句提炼出来,以一个良好命名的临时变量来解释对应条件子句的意义。 

u-boot 环境变量参数设置_我前年买了个表的博客-程序员秘密

今天本来是烧写内核,结果一不小心把uboot也整不能用了,无奈之下只好重新烧个uboot,等都弄好以后,发现系统还是启动不了,原来是启动参数设置不对,于是找到了这篇文章,//是我添加的内容。原文地址:http://blog.chinaunix.net/u3/94312/showart_1923637.html原文:     看到这个标题,可能觉得这个并没有什么的

ffmpeg 录屏命令_越努力越幸运~的博客-程序员秘密

window (安装dshow)ffmpeg -rtbufsize 100M -f dshow -i video="screen-capture-recorder":audio="virtual-audio-capturer" -vcodec libx264 -preset veryfast -crf 22 -tune:v zerolatency -pix_fmt yuv420p ...

Https在各种Web服务器下配置_weixin_33753003的博客-程序员秘密

前言前端很多情况需要用启动web服务器,而为了保证数据的安全性,都需要用Https对传输的数据进行加密传输,而且有些web-view只允许https通过访问,所以学习怎么配置https也成为大前端不可以少的功课之一。下面本妹子将先简单介绍下 Https,再依次介绍怎么在Node、webpack-dev-server和nginx这三个最常见的前端web服务器下配置Https,以及关于证书的扩展干货...

tf-faster-rcnn安装、修改记录_flashTianjiao的博客-程序员秘密

现在在用TensorFlow,所以找了这个 tf-faster-rcnn 实现faster rcnn。由于我的电脑是新装的,所以在安装过程中遇到不少问题,现在记录下来。 tf-faster-rcnn的github地址 https://github.com/endernewton/tf-faster-rcnn作者的readme写的挺好的,照着做没问题。现在补充些我遇到的。1、在pascal_voc上

Dell optiplex 7060ssf系统迁移到M.2 nvme 固态硬盘_dell7060加装固态硬盘_whutxxz0208的博客-程序员秘密

系统初始情况:Dell optiplex 7060ssf本来只有一块硬盘(1T的机械硬盘),其中预装了Windows 10。之后我自己买了1条256g的Intel的760p M.2 nvme固态硬盘。系统迁移分为两步:第一步,设置Bios;第二步,用AcronisTrueImage软件把机械硬盘里的系统克隆到M.2 nvme固态硬盘。第二步结束后拔掉机械硬盘的电源线,检查是否可以用M.2 ...

推荐文章

热门文章

相关标签