我有一个项目,需要在其中插入气泡/消息框。我想要达到的总体形状是这样的:
.bubble {
height: 100px;
width: 200px;
border: 3px solid gray;
background: lightgray;
position: relative;
cursor:pointer;
}
.triangle {
width: 0;
border-top: 20px solid black;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
cursor:pointer;
}
<div class="bubble">Speech bubble
</div>
<div class="triangle">
</div>
由于透明边框也是可点击的,因此当前未通过点击测试。
目标
命中框(可单击/可悬停区域)需要遵守形状的边界(此处的透明边界也是可悬停的,因此无效)。
我需要在各种内容(图像,坡度,文本...)上显示形状,
问题
操作此形状时遇到的主要问题是:
能够根据其所指元素的位置(顶部/左侧/右侧/底部)在气泡周围移动三角形
需要强调时在其周围添加边框或框阴影
无论如何,有没有解决这些问题?
最佳答案
为了实现这一点,您应该考虑更改标记,以使html更高效。这可以使用伪元素来实现。我将分别解决每个问题,并在回答的最后将它们放在一起。
首先,
使用伪元素以避免多余的元素
您可以使用伪元素删除多余的.triangle
div。这不仅减少了div数量,而且还有助于定位,因为可以使用top:
left:
right:
和bottom:
css属性来根据您的主要元素进行定位。可以在下面看到:
.oneAndOnlyDiv {
height: 100px;
width: 200px;
border: 3px solid gray;
background: lightgray;
position: relative;
}
.oneAndOnlyDiv:before {
content: "";
position: absolute;
top: 100%;
left: 20px;
width: 0;
border-top: 20px solid black;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
}
<div class="oneAndOnlyDiv">Main div</div>
命中测试
为了创建“命中测试”,您可能希望使用旋转的元素而不是边界hack。
就像是:
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
}
div:before {
content: "";
position: absolute;
top: 100%;
left: 20px;
height: 20px;
width: 20px;
background: black;
transform: rotate(45deg);
transform-origin:top right;
}
<div>Only element</div>
或使用倾斜的伪元素:
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
}
div:before {
content: "";
position: absolute;
top: 90%;
left: 20px;
height: 30%;
width: 20px;
background: black;
transform: skewY(-45deg);
transform-origin:bottom left;
z-index:-1;
}
<div>Only element</div>
仅当将正方形或主元素悬停时才会显示指针。
但是,等等,这弄乱了定位吗?你怎么处理呢?
有一些解决方案。其中之一是使用
calc
CSS属性。div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
}
div:before {
content: "";
position: absolute;
top: -webkit-calc(100% - 10px); /*may require prefix for old browser support*/
top: calc(100% - 10px); /*i.e. half the height*/
left: 20px;
height: 20px;
width: 20px;
background: gray;
transform: rotate(45deg);
}
<div>Only element</div>
添加边框
您现在可以非常轻松地添加边框,只需在主元素上添加边框声明,然后将伪元素的
border-bottom
和border-right
设置为inherit
边境
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
border:3px double black;
}
div:before {
content: "";
position: absolute;
top: -webkit-calc(100% - 10px); /*may require prefix for old browser support*/
top: calc(100% - 10px); /*i.e. half the height*/
left: 20px;
height: 20px;
width: 20px;
background: gray;
transform: rotate(45deg);
border-bottom:inherit;
border-right:inherit;
box-shadow:inherit;
}
<div>Only element</div>
方块阴影:
为了具有框阴影,我使用了
:after
伪元素,以便将框阴影隐藏在另一个伪元素上,使该元素看起来像一个元素。div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
box-shadow: 5px 5px 10px 2px black;
}
div:before,div:after {
content: "";
position: absolute;
top: -webkit-calc(100% - 10px); /*may require prefix for old browser support*/
top: calc(100% - 10px); /*i.e. half the height*/
left: 20px;
height: 20px;
width: 20px;
background: gray;
transform: rotate(45deg);
z-index:-1;
box-shadow:inherit;
}
div:after{
box-shadow:none;
z-index:8;
}
<div>Only element</div>
全部放在一起
您还可以使用border-radius属性再次向消息框或气泡添加边界半径:
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
border:3px double black;
border-radius:10px;
}
div:before {
content: "";
position: absolute;
top: -webkit-calc(100% - 10px); /*may require prefix for old browser support*/
top: calc(100% - 10px); /*i.e. half the height*/
left: 20px;
height: 20px;
width: 20px;
background: gray;
transform: rotate(45deg);
border-bottom:inherit;
border-right:inherit;
box-shadow:inherit;
}
<div>Only element</div>
这甚至允许您不仅创建三角形,而且创建圆形。
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
border:3px double black;
border-radius:10px;
}
div:before {
content: "";
position: absolute;
top: -webkit-calc(100% - 13px); /*may require prefix for old browser support*/
top: calc(100% - 13px); /*i.e. half the height + border*/
left: 20px;
height: 20px;
width: 20px;
background: gray;
transform: rotate(45deg);
border:3px double transparent;
border-bottom:inherit;
border-right:inherit;
box-shadow:inherit;
border-radius:50%;
}
<div>Only element</div>
如果您遇到内容溢出并被“隐藏”在此伪元素后面的问题,而不必担心有边框,则可以使用负Z索引来解决此问题。
不喜欢使用“魔术数字”?
如果您不喜欢使用calc值的想法(我的答案中的定位当前正在使用(虽然有效)),则不妨使用
transform:translate(50%)
这将是一个更好的方法,因为:
您不需要知道边框的大小,也不需要知道一半的宽度
您将使您的消息框/气泡的定位更加动态,并支持进一步的调整。
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor: pointer;
border: 3px double black;
border-radius: 10px;
}
div:before {
content: "";
position: absolute;
top: 100%;
left: 30px;
height: 20px;
width: 20px;
background: gray;
box-sizing:border-box;
transform: rotate(45deg) translate(-50%);
border-bottom: inherit;
border-right: inherit;
box-shadow: inherit;
}
<div>Only element</div>
要移动吗?您可以!
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor: pointer;
border: 3px double black;
border-radius: 10px;
}
div:before {
content: "";
position: absolute;
top: 100%;
left: 10%;
height: 20px;
width: 20px;
background: gray;
box-sizing: border-box;
transform: rotate(45deg) translate(-50%);
border-bottom: inherit;
border-right: inherit;
box-shadow: inherit;
transition: all 0.8s;
}
div:hover:before {
left: 90%;
}
<div>Only element</div>
想要它正确吗?
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor: pointer;
border: 3px double black;
border-radius: 10px;
}
div:before {
content: "";
position: absolute;
top: 15%;
left: 100%;
height: 20px;
width: 20px;
background: gray;
box-sizing:border-box;
transform: rotate(45deg) translate(-50%);
border-top: inherit;
border-right: inherit;
box-shadow: inherit;
transition:all 0.8s;
}
div:hover:before{
top:80%;
}
<div>Only Element</div>
希望它是其他形状的三角形吗?
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor: pointer;
border-radius: 10px;
}
div:before {
content: "";
position: absolute;
top: 70%;
left: 100%;
height: 20px;
width: 20px;
background: gray;
box-sizing:border-box;
transform: translate(-50%) skewX(45deg);
box-shadow: inherit;
transition:all 0.8s;
z-index:-1;
}
div:hover:before{
transform: translate(-50%);
border-radius:50%;
top:20%;
}
<div>Only Element</div>
关于css - 带有箭头的气泡,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34791962/