我有一个项目,需要在其中插入气泡/消息框。我想要达到的总体形状是这样的:





.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-bottomborder-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/

10-13 00:37