css - globo - Bocadillo de diálogo con flecha
flecha izquierda css (3)
SVG
Esto no pasa una prueba de impacto ya que también se puede hacer clic en el borde transparente
Esto se puede hacer usando los eventos de puntero en svg.
pointer-events:visibleFill;
Solo seleccionará la parte donde hay pintura.
Este ejemplo usa filter_box-shadow y no es compatible con IE.
También usa dos formas.
html,
body {
margin: 0;
padding: 0;
}
.bubble {
width: 150px;
height: 150px;
-webkit-filter: drop-shadow(5px 5px 0px #aaa);
filter: drop-shadow(5px 5px 0px #aaa);
}
.bubble-shape {
fill: #1e1;
}
.shape-text {
color: black;
}
<svg class="bubble" viewBox="0 0 110 110" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<g class="bubble-shape" style="cursor:pointer; pointer-events:visibleFill;">
<rect x="10" y="10" width="90" height="90" rx="15" ry="15" />
<polygon points="20,94 40,94 30,105" />
</g>
</svg>
Este ejemplo usa una ruta
Debería ser totalmente compatible con IE.
html,
body {
margin: 0;
padding: 0;
}
.bubble {
width: 150px;
height: 150px;
}
.bubble-shape {
stroke-width: 15;
stroke: #ddd;
fill: #1e1;
}
.shape-text {
color: black;
}
<svg class="bubble" viewBox="-70 -10 390 370" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<g style="cursor:pointer; pointer-events:visible;">
<path class="bubble-shape" d="m 0,0 250,0 c 25,0 50,20 50,50 l 0,225 c 0,25 -25,50 -50,50 l -175,0 -25,20 -20,-20 -40,0 c -25,0 -50,-25 -50,-50 l 0,-225 C -50,25 -50,0 0,0 Z" />
</g>
</svg>
Tengo un proyecto donde necesito insertar burbujas de diálogo / cuadros de mensaje . La forma general que estoy tratando de lograr es esta:
.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>
Actualmente, esto no pasa una prueba de impacto ya que también se puede hacer clic en el borde transparente.
Objetivos
-
El cuadro de golpe (áreas en las que se puede hacer clic / desplazables) debe adherirse a los límites de la forma (los bordes transparentes aquí también son desplazables, invalidando esto).
-
Necesito mostrar la forma sobre varios contenidos (imágenes, grados, texto ...),
Cuestiones
Los principales problemas que tengo al manipular esta forma son:
- Tener la capacidad de mover el triángulo alrededor del globo de diálogo de acuerdo con la posición del elemento al que se refiere (lados superior / izquierdo / derecho / inferior)
- Agregar un borde o una sombra de cuadro a su alrededor cuando se necesita énfasis
¿Hay alguna forma de abordar estos problemas?
He encontrado este maravilloso servicio para hacer flechas CSS personalizables. Simplemente genere y use con cualquier bloque.
Para lograr esto, debe considerar alterar su marcado para que su html sea más eficiente. Esto se puede lograr utilizando un pseudo elemento. Abordaré cada punto individualmente y lo pondré todo junto al final de mi respuesta.
Ante todo,
Usa pseudo elementos para evitar elementos extra
Puede usar un pseudo elemento para eliminar el div
.triangle
extra.
Esto no solo reduce sus números div, sino que también ayuda con el posicionamiento, ya que puede usar las propiedades
top:
left:
right:
e
bottom:
css para posicionar de acuerdo con su elemento principal.
Esto se puede ver a continuación:
.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>
Prueba de golpe
Para crear su "prueba de impacto", es posible que desee utilizar un elemento girado en lugar de un corte de borde.
Algo como:
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>
o use un pseudo elemento sesgado:
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>
que mostrará el puntero solo cuando el elemento cuadrado o principal esté suspendido. Pero espera, ¿eso arruina el posicionamiento? ¿Cómo puedes lidiar con eso?
Hay algunas soluciones para eso.
Una de ellas es usar la propiedad
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>
Agregar un borde
Puede agregar un borde con bastante facilidad ahora, simplemente agregando una declaración de borde al elemento principal y configurando el
border-bottom
y el
border-right
del pseudo elemento para
inherit
Frontera
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>
Sombra de la caja:
Para tener una sombra de cuadro, he usado el pseudo elemento
:after
para ocultar la sombra de cuadro sobre el otro pseudo elemento, haciendo que el elemento parezca un solo elemento.
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>
Poniendolo todo junto
También puede agregar un radio de borde a su cuadro de mensaje o burbuja de diálogo nuevamente, utilizando la propiedad de radio de borde:
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>
Esto incluso le permite crear no solo un triángulo, sino ¿qué tal un círculo en su lugar?
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>
Si tiene problemas con el contenido que se desborda y está ''oculto'' detrás de este pseudo elemento, y no está preocupado por tener un borde, puede usar un índice z negativo que resolverá este problema.
¿No te gusta usar ''números mágicos''?
Si no le gusta la idea de usar un valor de cálculo, en el que el posicionamiento en mi respuesta está usando actualmente (mientras trabaja), puede usar
transform:translate(50%)
Este sería un enfoque mucho mejor, ya que:
- No necesita saber el tamaño del borde, ni la mitad del ancho
- Hará que su cuadro de mensaje / burbuja sea mucho más dinámico en su posicionamiento, y admitiría más tamaños.
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>
¿Quieres moverlo? ¡Usted puede!
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>
¿Quieres uno el correcto?
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>
¿Quieres que sea una forma diferente de triángulo?
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>