css – 带箭头的语音气泡

我有一个项目,我需要插入语音气泡/消息框。我想要实现的一般形状就是这样:
.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数量,还可以帮助定位,您可以使用顶部: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>

打测试

为了创建“命中测试”,您可能希望使用旋转的元素而不是边框​​黑客。

就像是:

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>

添加边框

您可以很容易地添加一个边框,只需在主元素中添加边框声明,并将伪元素的边框底部和边框右边设为继承

边境

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>

相关文章

Css3如何实现鼠标移上变长特效?(图文+视频)
css3怎么实现鼠标悬停图片时缓慢变大效果?(图文+视频)
jquery如何实现点击网页回到顶部效果?(图文+视频)
css3边框阴影效果怎么做?(图文+视频)
css怎么实现圆角边框和圆形效果?(图文+视频教程)
Css3如何实现旋转移动动画特效