Seleccionando Elementos Padres Con CSS y jQuery

Ha habido ocasiones en las que he deseado poder seleccionar un elemento principal con CSS, y no estoy solo en este asunto. Sin embargo, no hay tal cosa como una Selector de Padres en CSS, por lo que simplemente no es posible por el momento.

En este tutorial, veremos algunos casos en los que tener un selector de padres CSS podría ser útil, junto con algunas posibles soluciones. Empecemos!

Espera, ¿qué es un selector de padres?

Los selectores de CSS nos permiten apuntar a los elementos, moviéndonos hacia abajo y hacia el árbol DOM, volviéndonos más específicos a medida que lo hacemos. Aquí hay un ejemplo del tipo de selector que puede encontrar en Bootstrap-it viaja por el árbol DOM desde el nav.navbar-dark elemento, a la ul, la li, entonces finalmente el a.nav-link.

.navbar-dark .navbar-nav .nav-item .nav-link 

 Un selector de padres nos permitiría viajar de regreso arriba el DOM, apuntando a los elementos padres de ciertas cosas. Por ejemplo, podríamos apuntar al padre de .enlace de navegación elementos utilizando:

.nav-link :: parent 

Nota: este ejemplo es puro pseudo código, no existe ni sugiere la mejor sintaxis posible!

Caso 1: Styling Legacy Content

Diseñar el contenido heredado, con un marcado y una estructura fechados, es un desafío clásico al rediseñar un sitio web. Antes de HTML5, por ejemplo, una imagen podría haber sido envuelta con un pag, div, o a veces con un lapso junto con un anidado pag utilizado para envolver el título de la imagen. No había una forma estándar de envolver una imagen y una leyenda. Más tarde, adoptamos la figura y figcaption Elementos, haciendo nuestra estructura documental más semántica..

Queremos que las imágenes del contenido heredado aparezcan como se muestra arriba. Pero como puede haber más div Las etiquetas de nuestro documento, las que no contienen imágenes, las siguientes declaraciones de estilo serían completamente imprácticas..

.page-content div padding: 15px; color de fondo: # f3f3f3; margen: 10px 0 20px;  .page-content div img marging: 0 0 10px;  .page-content div .img-caption color: # 999; tamaño de fuente: 12px; text-align: center; Wisplay: bloque; 

Se aplicaría el color de fondo, el relleno y los márgenes a todos los elementos div en el contenido. En realidad queremos aplicar estos estilos exclusivamente a div Elementos que envuelven una imagen y una leyenda de imagen..

Caso 2: Mantener la relación de video

Otro ejemplo se refiere al mantenimiento de la relación de video incorporado (como la de Youtube o Vimeo), así como a la fluidez del video. En estos días, en gran parte gracias al trabajo de investigación de Dave Rupert y amigos, es ampliamente aceptado que el mejor enfoque es aplicar acolchado superior o fondo acolchado al elemento padre.

Fragmento de código de CSS-Tricks: video de ancho fluido

Sin embargo, en un mundo real, es posible que no sepamos qué elemento contiene el video. Podemos encontrar algún video incrustado envuelto dentro de un div o un pag sin un nombre de clase identificable, por lo que es difícil seleccionar el elemento adecuado para aplicar los estilos. 

Por lo tanto, declarar los estilos como sigue no es práctico ya que impactará todos los divs dentro de .contenido de página Incluyendo los que no contienen un video incorporado.

.contenido de la página ancho: 560px; margen derecho: auto; margen izquierdo: auto; margen superior: 30px;  .page-content div position: relative; Fondo de relleno: 56,25%;  .page-content div iframe position: absolute; arriba: 0; ancho: 100%; altura: 100%; 

Qué maravilloso sería seleccionar directamente el elemento padre del video!

Caso 3: Respondiendo a la entrada del formulario

En este ejemplo tenemos un formulario con varias entradas. Cuando nos enfocamos en una de las entradas, se le da un color de borde más prominente, resaltando la posición del usuario dentro del formulario.

Algunas veces, también puede encontrarse con una situación en la que no solo se resalta el color del borde, sino también el elemento que envuelve la entrada, lo que hace que la entrada sea aún más prominente

Enfoque de formulario de entrada.

El elemento padre podría ser un div o un pag. Entonces, ¿cómo podemos seleccionar correctamente el elemento padre en función de ciertos estados de sus descendientes??

Posibles soluciones

Como hemos cubierto, no hay tal cosa como una selector de padres, así que seleccionar un padre no es posible. Podríamos estar tentados a evitar el problema, al reconsiderar completamente el diseño para evitar la selección del elemento primario. Pero si eso no es posible, aquí hay algunos enfoques potenciales..

Usando CSS :tiene() Selector 

los :tiene Selector se conoce oficialmente como la pseudo-clase relacional. Coincide con elementos basados ​​en sus descendientes, que se definen entre paréntesis. 

En el siguiente ejemplo, se aplica una color de fondo a cualquier div que contiene un título de imagen. Esto aparentemente aborda el caso 1.

.page-content div: has (.img-caption) padding: 15px; color de fondo: #ccc; 

O, si queremos ser más específicos, podemos reescribirlo para que coincida con cualquier div etiqueta con el .img-caption como el directo descendiente.

.page-content div: has (> .img-caption) padding: 15px; color de fondo: #ccc; 

Este selector está redactado para CSS Selector Level 4, aunque todavía no lo implementan los navegadores. Tendremos que esperar un poco más antes de que este selector salga a la luz. Hasta entonces, eche un vistazo al siguiente curso de video titulado CSS of the Future para averiguar cómo funciona el selector:

  • El: tiene pseudo-clase
  • Combinando: tiene y: no

Usando el Selector de Padres jQuery

Ninguna solución CSS puede solucionar nuestros problemas aquí, así que veamos qué puede hacer JavaScript por nosotros. En este ejemplo, vamos a utilizar jQuery por sus robustas API, conveniencia y compatibilidad con el navegador. Al momento de escribir, jQuery proporciona tres métodos para seleccionar elementos principales.

padre(); este método selecciona el elemento primario inmediato del elemento de destino. Podemos aprovechar este método para abordar todos nuestros casos de uso mencionados anteriormente en el tutorial..

Estructura de la imagen en contenido legado..

Por ejemplo, podemos usar padre() para agregar una clase especial al elemento de ajuste de las imágenes dentro del contenido.

$ (".img-caption") .parent () .addClass ("has-img-caption"); 

El código anterior seleccionará el elemento inmediato que envuelve la imagen, independientemente del tipo de elemento, agregando el has-img-caption clase para darnos más control sobre la selección de elementos y estilos, de la siguiente manera.

Estructura de la imagen en contenido legado con una clase extra..

padres () Note la forma plural de este método. Este método nos permite seleccionar los elementos principales desde el inmediato, hasta la raíz del documento, a menos que un selector se especifica como el argumento.

$ (".img-caption") .parents () .addClass ("has-img-caption"); 

Dado el ejemplo anterior, el padres () método selecciona todo el camino desde el div etiqueta que envuelve inmediatamente la imagen, la siguiente div, y por último el html, añadiendo el has-img-caption clase a todos los elementos.

La clase has-img-caption aplicada con el método parent ().

Tal exceso es redundante. El único elemento que probablemente necesitará que se agregue la clase, en este caso, es el inmediato div elemento. Por eso lo pasamos en el argumento del método..

$ (".img-caption") .parents ("div") .addClass ("has-img-caption"); 

Aquí el padres () El método viajará a través del árbol de antepasado de la imagen, seleccionando cualquier div encontrado y dandolo has-image-caption clase.

Si eso todavía es dominante, puede limitar la selección a un solo elemento especificando el índice. En el siguiente ejemplo, aplicamos la clase solo a la primera div.

var $ parents = $ (".caption") .parents ("div"); $ parents [0] .addClass ("has-img-caption"); // seleccionar el primer div add add the class. 

padresUntil (); este método selecciona los elementos principales hasta pero sin incluir el elemento especificado entre paréntesis.

$ (".caption") .parentsUntil (".page-content") .addClass ("has-img-caption"); 

Dado el código anterior, se aplicará el has-img-caption clase a todos los elementos padres, excepto el elemento con .contenido de página.

En algunos casos, donde tiene millones de elementos anidados, utilizando el padresUntil () El método es preferible. Es comparativamente más rápido que el padres () Método que evita el uso del motor de selección de jQuery (Sizzle) para viajar a través de todo el árbol DOM hasta la raíz del documento..

Terminando

¿Es probable que tengamos un selector de padres CSS en algún momento en el futuro??

Probablemente no. El tipo de selector de padres que hemos discutido anteriormente ha sido propuesto varias veces, pero nunca ha pasado la etapa de borrador del W3C por varias razones. Esas razones se centran principalmente en el rendimiento del navegador, debido a la forma en que los navegadores evalúan y representan las páginas. Lo más cercano que tendremos en el futuro es el selector relacional., :tiene().

Sin embargo, desde la :tiene() aún no es aplicable, JavaScript y jQuery son actualmente el enfoque más confiable. Tenga en cuenta que DOM Traversal es una operación costosa que puede afectar gravemente el rendimiento de representación de su sitio. Evitar el uso de padres () o padresUntil () con otras operaciones pesadas como animar(), fundirse() o fadeOut ()

Mejor aún, examine la estructura HTML siempre que sea posible para ver si se puede evitar por completo la selección del elemento principal!

Recursos adicionales

  • CSS Nivel 4 selectores a tener en cuenta
  • Selector de CSS para: segmentación principal (por favor)
  • ¿Por qué no tenemos un selector de padres?