El elemento no permanecerá centrado, especialmente al cambiar el tamaño de la pantalla
Mi problema es que no puedo centrar horizontalmente un puntero triangular.
Bueno, puedo centrar el puntero para algunos tamaños de ventana, pero cuando reduzco o extiendo la ventana, la coloca nuevamente en el lugar equivocado.
¿Qué me estoy perdiendo?
body {
background: #333333;
}
.container {
width: 98%;
height: 80px;
line-height: 80px;
position: relative;
top: 20px;
min-width: 250px;
margin-top: 50px;
}
.container-decor {
border: 4px solid #C2E1F5;
color: #fff;
font-family: times;
font-size: 1.1em;
background: #88B7D5;
text-align: justify;
}
.container:before {
top: -33px;
left: 48%;
transform: rotate(45deg);
position: absolute;
border: solid #C2E1F5;
border-width: 4px 0 0 4px;
background: #88B7D5;
content: '';
width: 56px;
height: 56px;
}
<div class="container container-decor">great distance</div>
Tienes tu flecha centrada con left:48%
. Esto posiciona la flecha cerca del centro del contenedor según el borde izquierdo del elemento de flecha.
En otras palabras, supongamos que usó left:50%
(que es la forma correcta de hacerlo), esto no centra el elemento de flecha en el contenedor. En realidad, centra el borde izquierdo del elemento en el contenedor.
En la imagen de abajo, un marcador está centrado en la página usando text-align:center
.
A modo de comparación, vea la flecha centrada con left:50%
.
El elemento está colocado en el centro-derecha. Esta desalineación se vuelve más notoria a medida que la ventana se hace más pequeña.
Como resultado, es común ver que elementos centrados y absolutamente posicionados utilicen la transform
propiedad:
.triangle {
position: absolute;
left: 50%;
transform: translate(-50%,0);
}
La transform
regla le dice al triángulo que se desplace hacia atrás el 50% de su ancho. Esto lo hace perfectamente centrado en la línea. Ahora emula text-align:center
.
En translate(-50%,0)
, el primer valor apunta al eje x (horizontal), el otro se aplica al eje y. Una regla equivalente sería transform:translateX(-50%)
(también existe transform:translateY()
).
Además, aquí se explica cómo centrar un elemento tanto horizontal como verticalmente usando este método:
.triangle { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); }
Nota: Si estuviera usando
right: 50%
obottom: 50%
, lostranslate
valores respectivos serían50%
(no negativos) .
Sin embargo, en esta pregunta en particular surge un problema porque transform:rotate(45deg)
también está en el bloque de declaración. Agregar un segundo transform
significa que el primero se ignora (según la cascada).
Entonces, como solución, prueba esto:
.container::before {
left: 50%;
transform: translate(-50%,0) rotate(45deg);
}
Al encadenar funciones, se pueden aplicar múltiples funciones.
Sólo tenga en cuenta que el orden importa. Si translate
y rotate
se invirtieran, el triángulo primero rotaría 45 grados y luego se desplazaría -50% a lo largo del eje rotado , rompiendo el diseño. Así que asegúrese de que eso translate
vaya primero. (Gracias @Oriol por señalar esto en los comentarios).
Aquí está el código completo:
body {
background: #333333;
}
.container {
width: 98%;
height: 80px;
line-height: 80px;
position: relative;
top: 20px;
min-width: 250px;
margin-top: 50px;
}
.container-decor {
border: 4px solid #C2E1F5;
color: #fff;
font-family: times;
font-size: 1.1em;
background: #88B7D5;
text-align: justify;
}
.container::before {
top: -33px;
left: 50%;
transform: translate(-50%,0) rotate(45deg);
position: absolute;
border: solid #C2E1F5;
border-width: 4px 0 0 4px;
background: #88B7D5;
content: '';
width: 56px;
height: 56px;
}
<div class="container container-decor">great distance</div>
jsFiddle
Podrías utilizar la nueva calc()
función CSS3 que te permite hacer aritmética para determinar el punto central.
Para obtener su punto central, el cálculo deberá ser:
50% - (56px / 2)
Entonces esto termina siendo
50% - 28px
Poner esto en la calc()
función debería resolverlo dentro del navegador y colocarlo perfectamente en el centro.
body {
background: #333333;
}
.container {
width: 98%;
height: 80px;
line-height: 80px;
position: relative;
top: 20px;
min-width: 250px;
margin-top: 50px;
}
.container-decor {
border: 4px solid #C2E1F5;
color: #fff;
font-family: times;
font-size: 1.1em;
background: #88B7D5;
text-align: justify;
}
.container:before {
top: -33px;
left: calc(50% - 28px);
transform: rotate(45deg);
position: absolute;
border: solid #C2E1F5;
border-width: 4px 0 0 4px;
background: #88B7D5;
content: '';
width: 56px;
height: 56px;
}
<div class="container container-decor">great distance</div>