html - posicionamiento - Cómo afectar a otros elementos cuando se mueve un div
posicionamiento css ejemplos (6)
¡Muchas gracias a Mike y Robertc por sus útiles publicaciones!
Si tiene dos elementos en su HTML y desea :hover
sobre uno y buscar un cambio de estilo en el otro, los dos elementos deben estar directamente relacionados: padres, hijos o hermanos. Esto significa que los dos elementos deben estar uno dentro del otro o ambos deben estar contenidos dentro del mismo elemento más grande.
Quería mostrar las definiciones en un cuadro en el lado derecho del navegador mientras mis usuarios leen mi sitio y :hover
sobre los términos resaltados; por lo tanto, no quería que el elemento ''definición'' se mostrara dentro del elemento ''texto''.
Casi me di por vencido y acabo de agregar javascript a mi página, pero este es el futuro, ¡arréglalo! ¡No deberíamos tener que aguantar la burla de CSS y HTML que nos dice dónde debemos colocar nuestros elementos para lograr los efectos que queremos! Al final nos comprometimos.
Si bien los elementos HTML reales en el archivo deben estar anidados o contenidos en un solo elemento para que sean válidos :hover
objetivos entre sí, el atributo de position
css se puede usar para mostrar cualquier elemento donde desee. Utilicé position: fix para ubicar el objetivo de mi acción :hover
donde lo deseara en la pantalla del usuario, independientemente de su ubicación en el documento HTML.
El html:
<div id="explainBox" class="explainBox"> /*Common parent*/
<a class="defP" id="light" href="http://en.wikipedia.or/wiki/Light">Light /*highlighted term in text*/
</a> is as ubiquitous as it is mysterious. /*plain text*/
<div id="definitions"> /*Container for :hover-displayed definitions*/
<p class="def" id="light"> /*example definition entry*/ Light:
<br/>Short Answer: The type of energy you see
</p>
</div>
</div>
El css:
/*read: "when user hovers over #light somewhere inside #explainBox
set display to inline-block for #light directly inside of #definitions.*/
#explainBox #light:hover~#definitions>#light {
display: inline-block;
}
.def {
display: none;
}
#definitions {
background-color: black;
position: fixed;
/*position attribute*/
top: 5em;
/*position attribute*/
right: 2em;
/*position attribute*/
width: 20em;
height: 30em;
border: 1px solid orange;
border-radius: 12px;
padding: 10px;
}
En este ejemplo, el objetivo de un comando :hover
desde un elemento dentro de #explainBox
debe ser #explainBox
o también dentro de #explainBox
. Los atributos de posición asignados a #definiciones obligan a aparecer en la ubicación deseada (fuera de #explainBox
), aunque se encuentre técnicamente en una posición no deseada dentro del documento HTML.
Entiendo que se considera incorrecto utilizar el mismo #id
para más de un elemento HTML; sin embargo, en este caso, las instancias de #light
se pueden describir de forma independiente debido a sus respectivas posiciones en los elementos #id
únicos. ¿Hay alguna razón para no repetir el id
#light
en este caso?
Creo que esta es una pregunta muy básica, pero no estoy seguro de cómo se puede hacer.
Lo que quiero hacer es que cuando un determinado div
se desplace, afectará las propiedades de otro div
.
Por ejemplo, en este sencillo ejemplo , cuando se #cube
sobre #cube
, cambia el background-color
pero lo que quiero es que cuando pase sobre #container
, #cube
se vea afectado.
div {
outline: 1px solid red;
}
#container {
width: 200px;
height: 30px;
}
#cube {
width: 30px;
height: 100%;
background-color: red;
}
#cube:hover {
width: 30px;
height: 100%;
background-color: blue;
}
<div id="container">
<div id="cube">
</div>
</div>
Aquí hay otra idea que le permite afectar a otros elementos sin tener en cuenta ningún selector específico y solo utilizando el estado de :hover
del elemento principal.
Para esto, confiaré en el uso de propiedades personalizadas (variables CSS). Como podemos leer en la specification :
Las propiedades personalizadas son propiedades normales , por lo que se pueden declarar en cualquier elemento, se resuelven con las reglas normales de herencia y en cascada ...
La idea es definir las propiedades personalizadas dentro del elemento principal y usarlas para diseñar elementos secundarios y, como estas propiedades se heredan, simplemente debemos cambiarlas dentro del elemento principal al pasar el cursor.
Aquí hay un ejemplo:
#container {
width: 200px;
height: 30px;
border: 1px solid var(--c);
--c:red;
}
#container:hover {
--c:blue;
}
#container > div {
width: 30px;
height: 100%;
background-color: var(--c);
}
<div id="container">
<div>
</div>
</div>
¿Por qué esto puede ser mejor que usar un selector específico combinado con el hover?
Puedo proporcionar al menos 2 razones que hacen que este método sea bueno para considerar:
- Si tenemos muchos elementos anidados que comparten los mismos estilos, esto nos evitará un selector complejo para apuntar a todos ellos al pasar el cursor. Usando las propiedades personalizadas, simplemente cambiamos el valor al pasar el cursor sobre el elemento principal.
- Una propiedad personalizada puede usarse para reemplazar un valor de cualquier propiedad y también un valor parcial de la misma. Por ejemplo, podemos definir una propiedad personalizada para un color y la usamos dentro de un
border
,linear-gradient
,background-color
, unbox-shadow
etc. Esto nos evitará restablecer todas estas propiedades al pasar el cursor.
Aquí hay un ejemplo más complejo:
.container {
--c:red;
width:400px;
display:flex;
border:1px solid var(--c);
justify-content:space-between;
padding:5px;
background:linear-gradient(var(--c),var(--c)) 0 50%/100% 3px no-repeat;
}
.box {
width:30%;
background:var(--c);
box-shadow:0px 0px 5px var(--c);
position:relative;
}
.box:before {
content:"A";
display:block;
width:15px;
margin:0 auto;
height:100%;
color:var(--c);
background:#fff;
}
/*Hover*/
.container:hover {
--c:blue;
}
<div class="container">
<div class="box"></div>
<div class="box"></div>
</div>
Como podemos ver arriba, solo necesitamos una declaración CSS para cambiar muchas propiedades de diferentes elementos.
El uso del selector de hermanos es la solución general para diseñar otros elementos cuando se desplaza sobre un elemento dado, pero funciona solo si los otros elementos siguen al elemento en el DOM . ¿Qué podemos hacer cuando los otros elementos deberían estar en realidad antes que el flotante? Digamos que queremos implementar un widget de calificación de barra de señal como el que se muestra a continuación:
Esto se puede hacer fácilmente usando el modelo CSS flexbox, configurando flex-direction
para reverse
, de modo que los elementos se muestren en el orden opuesto al de ellos en el DOM. La captura de pantalla anterior es de un widget de este tipo, implementado con CSS puro.
Flexbox está muy bien soportado por el 95% de los navegadores modernos.
.rating {
display: flex;
flex-direction: row-reverse;
width: 9rem;
}
.rating div {
flex: 1;
align-self: flex-end;
background-color: black;
border: 0.1rem solid white;
}
.rating div:hover {
background-color: lightblue;
}
.rating div[data-rating="1"] {
height: 5rem;
}
.rating div[data-rating="2"] {
height: 4rem;
}
.rating div[data-rating="3"] {
height: 3rem;
}
.rating div[data-rating="4"] {
height: 2rem;
}
.rating div[data-rating="5"] {
height: 1rem;
}
.rating div:hover ~ div {
background-color: lightblue;
}
<div class="rating">
<div data-rating="1"></div>
<div data-rating="2"></div>
<div data-rating="3"></div>
<div data-rating="4"></div>
<div data-rating="5"></div>
</div>
En este ejemplo particular, puede utilizar:
#container:hover #cube {
background-color: yellow;
}
Esto solo funciona ya que cube
es un hijo de container
. Para escenarios más complicados, necesitarías usar javascript.
Si el cubo está directamente dentro del contenedor:
#container:hover > #cube { background-color: yellow; }
Si el cubo está al lado de (después de que los contenedores cierren la etiqueta) el contenedor:
#container:hover + #cube { background-color: yellow; }
Si el cubo está en algún lugar dentro del contenedor:
#container:hover #cube { background-color: yellow; }
Si el cubo es un hermano del contenedor:
#container:hover ~ #cube { background-color: yellow; }
Solo esto me funcionó:
#container:hover .cube { background-color: yellow; }
Donde .cube
es CssClass del #cube
.
Probado en Firefox , Chrome y Edge .