谈谈一些有趣的CSS题目(2)-- 条纹边框的多种实现方式
chokcoco opened this issue · 29 comments
开本 issues
,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节。
解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉到生僻的 CSS 属性,赶紧去补习一下吧。
不断更新,不断更新,不断更新,重要的事情说三遍。
2、类似下面这个图形,只使用一个标签,可以有多少种实现方式:
假设我们的单标签为 div
:
<div></div>
定义如下通用 CSS:
div{
position:relative;
width: 180px;
height: 180px;
}
这一题主要考查的是盒子模型 Box Model
与 背景 background
的关系,以及使用 background-clip
改变背景的填充方式。
background
在 Box Model
中,他是布满整个元素的盒子区域的,并不是从 padding
内部开始(也就是说从 border 就开始啦),只不过实线边框(solid)部分遮住了部分 background
,所以我们使用虚线边框(dashed)就可以看到背景色是从 border
内部开始的。
我们给 div
添加如下样式:
div{
background:#9c27b0;
border:20px dashed #2196f3;
}
结果如下:
但有一点需要注意,background-color
是从元素的边框左上角起到右下角止,而 background-image
却不一样,他是从 padding
边缘的左上角起而到 border
的右下角边缘止。
background image 的绘制中有两个因素决定了绘图区域:
- background positioning area。
background-origin
属性决定了这个相对定位位置,默认为padding-box
。所以默认的背景图片绘制是从 padding box 的左上顶点开始的。 - background painting area。
background-clip
属性决定了绘制区间,默认为border-box
。所以在background-repeat: repeat
的情况下:
The image is repeated in this direction as often as needed to cover the background painting area.
嗯,什么意思呢,你可以戳进这个 demo 看看,正常情况下的背景图填充如下:
当然,这个填充规则是可以通过 background-clip
改变的。
background-clip
设置元素的背景(背景图片或颜色)是否延伸到边框下面。
语法:
background-clip: border-box; // 背景延伸到边框外沿(但是在边框之下)
background-clip: padding-box; // 边框下面没有背景,即背景延伸到内边距外沿。
background-clip: content-box; // 背景裁剪到内容区 (content-box) 外沿。
继续说回本题,接下来,只需要将中间部分填充为白色即可,这个用伪元素可以轻松完成,所以,其中一个方法如下:
div{
background:#9c27b0;
border:20px dashed #2196f3;
}
div::after{
content:"";
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
background:#fff;
}
法二:
上面的方法,我们使用了 div
的背景色默认情况下从 border
开始填充,及伪元素设置白色背景色填充 div
的中间的 padding-box
区域完成图形。
也可以反过来,使用伪元素背景色从 border-box
开始填充,使用 div
的背景色填充中间 padding-box
区域。
div{
background:#fff;
background-clip:padding-box;
border:20px dashed #cccc99;
}
div::before{
content:"";
position:absolute;
top:-20px;
left:-20px;
bottom:-20px;
right:-20px;
background:#996699;
z-index:-1;
}
具体的 Demo 戳这里 。
上面 法二
除了用到了 background-clip
改变背景的填充区域,还用到了 z-index
触发元素生成了堆叠上下文(stacking context),改变了元素的层叠顺序(stacking levle),让伪元素背景色
叠到了 div 背景色
之下,这两个概念下题会提及。
法....
本题主要是想讨论一下 CSS 的盒子模型 Box Model
与 背景 background
的关系,其实本题就是在于一个 dashed 边框,内部使用颜色填充即可,与上面第一题异曲同工,使用阴影、渐变都可以完成,感兴趣可以自己尝试一下其他解法。
+1
@idiotWu
刚刚没看清楚就瞎回复了,见谅。
看你图中的确实是从 border 开始的,有demo吗,我这边的demo都是从
paading-box 开始的。
CssBackground
@chokcoco
查了相关的标准,发现原因在于你设定了 background-repeat: no-repeat
。
background image 的绘制中有两个因素决定了绘图区域:
- background positioning area。
background-origin
属性决定了这个相对定位位置,默认为padding-box
。所以默认的背景图片绘制是从 padding box 的左上顶点开始的。 - background painting area。
background-clip
属性决定了绘制区间,默认为border-box
。所以在background-repeat: repeat
(default)的情况下:
The image is repeated in this direction as often as needed to cover the background painting area.
嗯 吹毛求疵一下。
第四题的法2为什么不直接用rotateX = =
@wangpengfei15975
厉害了我的哥,两个写法确实是一样的,rotateX 应该是更简洁的。
第五个, 已经用了 flex box, 可以直接在侧轴方向上居中. DEMO
sorry, 刚刚发错地方了。第二个dashed border box 的outline解法
.style_outline {
&::before{
content:"";
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
outline:20px solid #ffc107;
background:#fff;
z-index:-1;
}
感觉这样更合理一点。
非常有意思
啊哈,脑洞好大啊
第5题,如果加上点击加载更多呢…要如何实现?
第1题,当用border-left设置样式的时候,div的整个宽度就会加长,如果想要div整体宽度不变的话,就需要加上box-sizing:border-box;
使用外 box-shadow的时候div宽度也会加长,内 box-shadow就不会,所以如果需求还要保证div整体宽度不变的话,得注意下这些点。
`.demo1 {
position:relative;
width:200px;
height:60px;
background:#ddd;
}
.demo2 {
position:relative;
width:200px;
height:60px;
background:#ddd;
}
.demo2:after {
position:absolute;
left:0;
top:0;
content:'';
width:5px;
height:60px;
background: deeppink;
}
.demo3 {
position:relative;
width:200px;
height:60px;
background:#ddd;
box-shadow: inset 5px 0 0 deeppink;
}
.demo4 {
position:relative;
width:200px;
height:60px;
background:#ddd;
border-left:solid 5px deeppink;
box-sizing:border-box;
}
.demo5 {
position:relative;
width:200px;
height:60px;
background:#ddd;
box-shadow:-5px 0 0 deeppink;
}
.demo6 {
position:relative;
width:200px;
height:60px;
background:#ddd;
border-left:solid 5px deeppink;
}
` 可以对比看下容器宽度
好厉害啊,刚入前端,真的学习到很多。谢谢
- 法3 [code] box-shaodw -> shadow
第一个:不知道用背景图片(repeat-y)算不算
关于移动端多行省略 我这里有个更好的实现
https://codepen.io/isjemair/pen/oMRZvm
切换最外层的folded类名就可以实现查看更多和收起状态
法一的实现不能实现点击查看更多
法二的实现很容易造成文字被截一半
原本的方法是在网上找到一个老外的 我在做的时候是把其中的参数抽出来作为变量
关于前两个问题,其实还可以直接用img标签嘛(要是说不能包含外部图片,可以把图片转成base64编码嘛),同理还可以使用svg标签嘛。
@zsjun 我尝试了下现版本的chrome下确实是上图你发的效果。
因为写这个这篇文章的时间距离现在有一段时间了,我再去确认考究下,再给你个答复~
好的,多谢,我用的是goole浏览器的69.0.3497.100版本,最新的版本
关于移动端多行省略 我这里有个更好的实现
https://codepen.io/isjemair/pen/oMRZvm
切换最外层的folded类名就可以实现查看更多和收起状态法一的实现不能实现点击查看更多
法二的实现很容易造成文字被截一半原本的方法是在网上找到一个老外的 我在做的时候是把其中的参数抽出来作为变量
@Jemair 你的demo的问题是展开是用颜色盖在上边的,所以底部背景变化,或不是纯色会露出马脚
第3个父元素 display: flex;flex-direction: row-reverse; 子元素margin-left:负值 好像也行
大神你好,这些思考非常值得学习。关于第2道思考题我在backgroun-image和background-color上有点疑惑想请教下。下图是我通过伪元素实现的,但我想通过background-image的多背景实现,内部的background-image的终止点总是在border右下角,我想把它终止点在padding右下角,请问可以怎么实现呢?
以下是我想实现的代码,但不起作用
div{
margin:20px;
width: 400px;
height:400px;
border: 10px dashed green;
padding: 20px;
background-repeat: no-repeat, no-repeat;
background-image:
url(./img/1.jpg),
linear-gradient(to right, red,red);
background-clip: padding-box, border-box;
}
"嗯,什么意思呢,你可以戳进这个 demo 看看,正常情况下的背景图填充如下" 感觉这个demo里面的和后面加菲猫配图讲解的不太相符 代码中background-clip 默认都是border-box 在border之下 但是加菲猫图片说背景图是padding左上角到border 右下角 还是我的理解有问题?
background-image: linear-gradient(to left,white,white);
background-repeat: no-repeat;
直接在div加上这两个样式好像也行