CSS揭秘之形状

一.自适应的椭圆

问题:

我们肯定都注意到过,我们给一个正方形元素添加一个足够大的border-radius(指定大于正方形元素边长一半的半径),就可以使其变成一个圆形(如图1-1.png)。

示例:

width: 200px;
height: 200px;
backgrund: #FFC727;
border-radius: 100px;
图1-1.png
图1-1.png

规范还特别指出了其中的原因:

“当任意两个相邻圆角的半径之和超过border box的尺寸时,用户代理必须按比例减小各个边框半径所使用的值,直到它们不会相互重叠为止。”

我们有时可能不愿意给一个元素设置固定的宽高,而是希望让元素能根据内容自己调整并适应。如果我们现在需要这样的效果:如果元素的宽高相等,就显示为一个圆,如果不相等就显示为椭圆。我们前面的代码并不能满足这样的效果,那我们应该怎么来产生一个椭圆呢?

解决方案:

其实就是一个你可能并不知道的真相,那就是border-radius它可以单独指定水平半径和垂直半径,用(/)分隔两值即可。这样我们就可以得到一个相对精确的椭圆(图1-2.png)。

示例:

width: 200px;
height: 150px;
background: #ffc727;
border-radius: 100px / 75px;
图1-2.png
图1-2.png

这样就得到了一椭圆,但是它元素的尺寸变化,border-radius值也需要改变,那也是有点麻烦的。那我们怎么办呢?
其实呢,哈哈,那就是border-radius值是接收百分比值的;
所以设置border-radius: 50%;就可以实现一个自适应的椭圆了;

好吧,那我们就来看看border-radius吧。
1. border-radius:<length-percentage>{1,4} [ / <length-percentage>{1,4} ]?
where
<length-percentage> = <length> | <percentage>

(1.1) border-radius 用来设置边框圆角。当使用一个半径时确定一个圆形;当使用两个半径时确定一个椭圆,这个(椭)圆与边框的交集形成圆角效果。(图1-3.png)

图1-3.png---来自MDN
图1-3.png---来自MDN

(1.2)border-radius前一个语法取值可以取1~4个值,看下图(图1-4.png)就很清楚了,指定的是水平半径;
后一个语法取值也可以取1~4个值(同前一个语法),指定的是垂直半径;

图1-4.png---来自css揭秘
图1-4.png---来自css揭秘

(1.3)看一些示例吧

二分之一椭圆(图1-5.png)

width: 200px;
height: 150px;
background: #ffc727;
border-radius: 50% /100% 100% 0 0;
<!--border-top-left-radius: 50% 100%;-->
<!--border-top-right-radius: 50% 100%;-->
<!--border-bottom-right-radius: 50% 0px;-->
<!--border-bottom-left-radius: 50% 0px;-->
图1-5.png
图1-5.png

四分之一椭圆(图1-6.png)

width: 200px;
height: 150px;
background: #ffc727;
border-radius: 100% 0 0 0;
图1-6.png
图1-6.png

随便加了点阴影(图1-7.png)

width: 200px;
height: 150px;
background: #ffc727;
border-radius: 50%/100% 0;
box-shadow: 0px 10px 20px 0;
图1-7.png
图1-7.png

二.平行四边形

问题:

我们可以通过skew()来对矩形进行拉伸来生成一个平行四边形(如图2-1.png);


图2-1.png
图2-1.png

平行四边形是生成了,但是里面的内容“hello”也进行了拉伸,这样就比较难阅读,也不好看。那么有什么办法只让形状拉伸,而保持内容不变呢?

解决方案:

我们可以把所有样式都应用到为元素上,然后对伪元素进行变形。因为我们的内容并不是包含在伪元素里,所以内容不会受到形变的影响。

示例:(图2-2.png)

.box{
    margin: 100px;
    width:100px;
    height:40px;
    position:relative;
    text-align: center;
    line-height:40px;
    color: #fff;
}
.box::before{
    content: "";
    position: absolute;
    top:0;
    left: 0;
    right:0;
    bottom: 0;
    background: #ffc727;
    transform: skew(-45deg);
    z-index:-1;
}
图2-2.png
图2-2.png

三.菱形图片

我们可以通过clip-path属性来快速实现菱形图片的效果,不过它现在还是一个实验中的功能,它的兼容性不是很好。
clip-path:<clip-source> | [ <basic-shape> || <geometry-box> ] | none
where
<clip-source> = <url>
<basic-shape> = <inset()> | <circle()> | <ellipse()> | <polygon()>
<geometry-box> = <shape-box> | fill-box | stroke-box | view-box

示例:(图3-1.png)

img{
    clip-path: polygon(50% 0,100% 50%,50% 100%,0 50%);
}
图3-1.png
图3-1.png

basic-shape有四种基本形状(inset,cicle,ellipse,polygon),感觉好方便啊,那我们就一起来看看吧。
(3.1)<inset()> :定义一个插图矩形
where
<inset()> = inset( <length-percentage>{1,4} [ round <border-radius> ]? )
inset()可以传入5个参数(第5个参数可选),分别对应top,right,bottom,left,round radius,我们看一下下面的示例(图3-2.png),就清楚了;

示例:(图3-2.png)

clip-path: inset(10px 10px 50px 20px round 30px);
图3-2.png
图3-2.png

(3.2)<circle()>:圆
where
<circle()> = circle( [ <shape-radius> ]? [ at <position> ]? )
circle()可以传人2个可选参数;
第一个参数是圆的半径,默认为图片宽高中短的那个为直径;
注意:这个参数是支持百分比的,如果用百分比:
圆的半径/百分比=sqrt(width2+height2)/sqrt(2)。

第二个参数是圆心位置,默认为图片中心。

示例:(图3-3.png)

clip-path: circle(30% at 150px 120px);

图3-3.png
图3-3.png

圆的半径 = [sqrt(3002+2252)/sqrt(2)]*30% ≈ 80 px;

(3.3)<ellipse()>:椭圆
where
<ellipse()> = ellipse( [ <shape-radius>{2} ]? [ at <position> ]? )
ellipse()可以传入3个可选参数;
前2个参数表示的分别是椭圆X轴半径和Y轴半径,默认是图片宽(高)的一半,支持百分比;
第三个参数是椭圆中心位置,默认图片中心。

示例:(图3-4.png)

clip-path: ellipse(25% 25% at 50% 25%);
图3-4.png
图3-4.png

(3.4)<polygon()>:多边形
where
<polygon()> = polygon( <fill-rule>? , [ <length-percentage> <length-percentage> ]# )
polygon()中前一个语法<fill-rule>表示填充规则用来确定该多边形的内部。可能的值有nonzero和evenodd,默认值是nonzero;
后面列表中的每对参数表示多边形的顶点坐标(X,Y);

示例:(图3-5.png)

clip-path: polygon(50% 0,100% 50%,0 100%);
图3-5.png
图3-5.png

clip-path这个属性还可以参与动画呢,只要我们使用的是同一种形状函数。

示例:(图3-6.png)

img{
    clip-path: ellipse(75% 25%);
    transition: 1s clip-path;
}
img:hover{
    clip-path: ellipse(50% 50%);
}
图3-6.png
图3-6.png

四.切角效果
我这里用上面的clip-path来实现下,可以通过css渐变和border-image实现。
(4.1)clip-path实现切角效果

示例:(图4-1.png)
CSS

.box{
width:200px;
height:200px;
background: #FFc727;
clip-path: polygon(20px 0,calc(100% - 20px) 0,100% 20px,100% calc(100% - 20px),calc(100% - 20px) 100%,20px 100%,0 calc(100% - 20px),0 20px);
}

>
这样要改一切角,就要改好多地方,不是很方便,我们就用一下预处理器,我使用的是LESS,这样就稍稍好了一些,但也不够DRY。
LESS
>>```
.corner(@radius){
    @ca: e("calc(100% - @{radius})");
    <!--@ca: calc(~"100% - @{radius}");-->
    clip-path: polygon(@radius 0,@ca 0,100% @radius,100% @ca,@ca 100%,@radius 100%,0 @ca,0 @radius);
}
.box{
    width:200px;
    height:200px;
    background: #FFc727;
    .corner(20px);
}
图4-1.png
图4-1.png

未来,可能会引入一个新的属性corner-shape,配合border-radius使用,这样就可以快速实现一些切角的问题。
corner-shape介绍:http://lea.verou.me/2013/03/border-corner-shape-is-in-danger-and-you-can-help/
corner-shape体验:http://leaverou.github.io/corner-shape/


本内容根据《css揭秘》, MDN 和自己的理解进行整理;
感谢您的阅读。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,468评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,620评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,427评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,160评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,197评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,334评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,775评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,444评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,628评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,459评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,508评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,210评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,767评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,850评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,076评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,627评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,196评论 2 341

推荐阅读更多精彩内容

  • 各种纯css图标 CSS3可以实现很多漂亮的图形,我收集了32种图形,在下面列出。直接用CSS3画出这些图形,要比...
    剑残阅读 9,425评论 0 8
  • 选择qi:是表达式 标签选择器 类选择器 属性选择器 继承属性: color,font,text-align,li...
    wzhiq896阅读 1,725评论 0 2
  • 选择qi:是表达式 标签选择器 类选择器 属性选择器 继承属性: color,font,text-align,li...
    love2013阅读 2,300评论 0 11
  • 1.CSS简介 Cascading Style Sheet 层叠样式表 主要用来定义页面中的表现,HTML 描述页...
    hyt222阅读 805评论 0 0
  • 文:豆芽菜 从毕业到工作四年了,鬼使神差的我的工作都是跟英语有关的,理工科出身的我,真的做不到啊。在自己乱七八糟的...
    麻豆札记阅读 9,759评论 4 97