CSS定位方式与相对宽度

前段时间有个后端小伙伴被拉去写前端,出现了一个让他困惑不已的问题:明明给子元素设置了width:80%;可为什么还是子元素超出了父元素的宽度?

这里涉及到width属性的值的类型:width属性可以设置两种值,一种是绝对长度值,另外一种是相对长度值,相对长度值又根据参照物不同分为view height/view widthpercentage

所谓相对长度,那肯定会有参照物,其中vh/vw方式是参照窗口高宽确定的(浏览器参照),percentage方式是参照DOM元素确定的(页面内部参照)。但是问题就出现在这里,percentage参照的是哪个元素呢?是body、父级、还是兄弟元素?它又有哪些规则?

为了说明,我写了个简单的演示。

当然,我只写了几个组合,剩下的读者可以亲自试一试,实践出真知嘛。

顺便给出Mozilla对position属性的说明文档:Position – CSS: Cascading Style Sheets

(未完待续)

:hover伪类选择器设置背景图片时闪烁的解决办法

今天遇到了【用:hover使光标悬停在A时改变B的背景,但悬停时背景一直闪烁】这种常见问题。

于是心血来潮把解决方法和原理写出来,方便初学者避开这些容易遇到的小坑。

HTML代码

<div id="div">
<div id="div1"><center><a>ssssssssssssssssssss</a></center>
</div>
<div id="div2">
</div>
</div>

CSS代码

#div1 {
width: 350px;
position: fixed;
left: 0;
right: 0;
margin: auto;
}

#div2 {
background: url(https://seek.moe/MyPixivFav/_________%209.jpg) center no-repeat;
background-size: cover;
background-attachment: fixed;
height: 100vh;
}

#div1:hover + #div2, #div1:active + #div2 {
filter: blur(4px);
}

演示

在有鼠标的设备上可以看到闪烁,在触屏设备上按住文字可以看到文字消失(即#div1被遮罩了)

其实原因很简单,由于使用了position属性,且#div1和#div2在同一个#div中,所以默认z-index:auto,即堆叠顺序与父元素相等。

#div1中a标签的内容在#div2的背景的上层,所以:hover可以被触发。

但是当

#div1:hover + #div2{}

被触发时,#div2处于活动状态出现在上层。此时随着#div1被遮罩,上面这条css规则失效,如此反复,就形成了我们看到的闪烁。

解决方法显而易见,只需指定#div1和#div2的z-index属性,使#div2的z-index值比#div1的小,即#div2永远在#div1下层,就不会闪烁了。

即追加以下两条样式:

#div1 { z-index:2; }
#div2 { z-index:1; }

追加之后再用触屏设备点击文字,会发现文字一直处于显示状态(#div1始终处于上层),马上动手粘贴到上面的codepen里试试吧?

如果对本文提到的:hover很陌生,可以查看之前的文章:hover伪类选择器常见用法示例

:hover伪类选择器常见用法示例

光标悬停在父元素上时更改子元素样式

HTML代码
<div id="father">
<div id="son">
<center>
<a href="https://urusai.me" target="_blank" class="links" id="a1">🍭前往博客</a><a class="links"> ・ </a><a class="links" href="https://debugging.work" target="_blank" id="a2">🍢前往CV页</a><a class="links"> ・ </a><a class="links" href="https://ide.seek.moe" target="_blank" id="a3">🍡前往IDE</a>
</center>
</div>
</div>
CSS代码
/*定义动画*/
/*循环摆动*/
@keyframes thrill {
from {
transform: rotate(2deg);
}
to {
transform: rotate(-2deg);
}
}
/*从下方进入*/
@keyframes comeIn {
from {
bottom: -20px;
}
to {
bottom: 20px;
}
}
/*father样式*/
#father {
width: 350px;
padding: 16px 0 16px 0;
position: fixed;
left: 0;
right: 0;
bottom: 0px;
margin: auto;
border-radius: 16px;
/*绑定动画*/
animation: thrill 2s infinite alternate ease-in-out;
}
/*son样式*/
#son {
width: 350px;
padding: 16px 0 16px 0;
position: fixed;
left: 0;
right: 0;
bottom: 20px;
margin: auto;
border-radius: 16px;
background: rgba(255,150,173,.4);
box-shadow: 0 3px 6px 0 rgba(0,0,0,.2);
/*绑定动画,此处为动画嵌套*/
animation: comeIn .5s;
}
/*调整不同屏幕下的宽度*/
@media all and (min-width:1280px){
#comeIn, #blog{
width:380px;
}
}
/*优化小屏体验(滑稽)*/
@media all and (max-width:369px){
#blog
{
display:none;
}
}
/*鼠标悬停时或激活时更改背景颜色*/
#son:hover,#son:active {
background-color: rgba(255,150,173,.8);
}
/*文本样式*/
.links {
width: 100%;
text-decoration: none;
color: black;
font-weight: 300;
padding: 16px 0 16px 0;
}

/*div激活时,改变.links(即文本)的颜色,具体用法为上级元素(的id或class):hover .下级元素(的id或class){样式}*/
div:hover .links {
color: #f2f2f2;
}

/*文本激活时的颜色*/
#a1:hover, #a2:hover, #a3:hover {
color:white;
}

光标悬停时改变兄弟元素的CSS样式

HTML代码
<div id="father">
<div id="son1">bbb</div>
<div id="son2">ccc</div>
</div>
CSS代码
/*设置字体为红色*/
#son1,#son2 {
color:red;
}
/*当光标悬停于#son1时,son2的字体颜色从红变黑,与上面的示例相比较,关键在于一个+号,以及兄弟元素之间不得有其他元素隔断。另外,它还可以结合nth-child() 选择器灵活使用,这里就不细说了,请自行编写代码去实验理解。规则为共同父元素(的id或class) 悬停的子元素(的id或class):hover + 要改变的子元素(的id或class){样式}*/
#father #son1:hover + #son2 {
color:black;
}
 更多请参阅CSS 相邻兄弟选择器

效果展示

展示1:
SeekMoe

展示2:

bbb
ccc