Problemas al encolar hojas de estilo en temas padre e hijo con el método revisado del Codex
This post brings up a few questions I've encountered pertaining to the recent changes around stylesheet enqueueing methods brought up in this thread and this thread.
The issues I encountered came up in a general use-case scenario, using a widely used and well-maintained parent theme that is specifically child-theme ready on a WP 4.0 install. My child theme's functions.php only contains the wp_enqueue_style
function as detailed in the Codex.
Please note that while the code referenced below is specific to this theme, much of it uses current coding conventions used by parent themes. Additionally, my areas of concern are most likely duplicatable on a large number of established parent themes currently in the wild. Also, the questions these raise are applicable on a universal level, regardless of which parent theme is being used.
ISSUE 1: Twoqueueing
The Recommended Setup:
Parent theme is enqueueing styles and scripts using the wp_enqueue_scripts
hook, the relevent portion being as follows:
add_action('wp_enqueue_scripts', 'parent_theme_function_name');
function parent_theme_function_name() {
wp_register_style( 'avia-style' , $child_theme_url."/style.css", array(), '2', 'all' );
wp_enqueue_style( 'avia-base');
if($child_theme_url != $template_url) { wp_enqueue_style( 'avia-style'); }
}
My child theme functions.php
enqueues styles per recent codex changes:
add_action( 'wp_enqueue_scripts', 'enqueue_parent_theme_style' );
function enqueue_parent_theme_style() {
wp_enqueue_style( 'dm-parent-style', get_template_directory_uri().'/style.css' );
}
Note the following IDs as used by the referenced code:
id='dm-parent-style-css'
is the parent theme's stylesheetid='avia-style-css'
is my child theme's stylesheetid='dm-child-style-css'
is my child theme's stylesheet
The Results:
On first glance, everything was fine, with the <head>
showing the following order:
<link rel='stylesheet' id='dm-parent-style-css' href='testinstall.dev/wp-content/themes/enfold/style.css?ver=4.0' type='text/css' media='all' />
<!-- Multiple individual parent theme styles here -->
<link rel='stylesheet' id='avia-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
After installing a plugin, the enqueue order now changed as follows:
<link rel='stylesheet' id='dm-parent-style-css' href='testinstall.dev/wp-content/themes/enfold/style.css?ver=4.0' type='text/css' media='all' />
<!-- Multiple individual parent theme styles here -->
<link rel='stylesheet' id='avia-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
<!-- Pesky plugin styles -->
Ultimately, I need my child theme's css to load after any plugins, so I was forced to add a priority number to the function in my child theme (see previous discussion regarding priority number).
Because my function only enqueues the parent theme's css, however, the result is that now the parent theme css gets moved to the end, leaving my child theme's css in an even worse predicament than before.
<!-- Multiple individual parent theme styles here -->
<link rel='stylesheet' id='avia-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
<!-- Pesky plugin styles -->
<link rel='stylesheet' id='dm-parent-style-css' href='testinstall.dev/wp-content/themes/enfold/style.css?ver=4.0' type='text/css' media='all' />
Now I am forced to resort to enqueueing my child theme style as well, to ensure it gets moved back to the front of the line, causing the aforementioned issue of twoqueueing (new term? lol) the child theme css.
The Deprecated Setup:
Revised function in child theme:
add_action( 'wp_enqueue_scripts', 'enqueue_parent_theme_style', 99 );
function enqueue_parent_theme_style() {
wp_enqueue_style( 'dm-parent-style', get_template_directory_uri().'/style.css' );
wp_enqueue_style( 'dm-child-style', get_stylesheet_directory_uri().'/style.css' );
}
The Results:
Producing the following order in the <head>
:
<!-- Multiple individual parent theme styles here -->
<link rel='stylesheet' id='avia-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
<!-- Pesky plugin styles -->
<link rel='stylesheet' id='dm-parent-style-css' href='testinstall.dev/wp-content/themes/enfold/style.css?ver=4.0' type='text/css' media='all' />
<link rel='stylesheet' id='dm-child-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
My Shivm:
Though I would hardly suggest this be the recommended means (and I'm sure devs with more coding experience than myself will groan at this solution), I dequeued the parent theme's ID (used to enqueue my child theme's style) right above my own enqueue in my child theme's functions file as shown:
add_action( 'wp_enqueue_scripts', 'enqueue_parent_theme_style', 99 );
function enqueue_parent_theme_style() {
wp_enqueue_style( 'dm-parent-style', get_template_directory_uri().'/style.css' );
wp_dequeue_style( 'avia-style' );
wp_enqueue_style( 'dm-child-style', get_stylesheet_directory_uri().'/style.css' );
}
The Results:
This solved the issues at hand, resulting in :
<!-- Multiple individual parent theme styles here -->
<!-- Plugin styles -->
<link rel='stylesheet' id='dm-parent-style-css' href='testinstall.dev/wp-content/themes/enfold/style.css?ver=4.0' type='text/css' media='all' />
<link rel='stylesheet' id='dm-child-style-css' href='testinstall.dev/wp-content/themes/child-theme/style.css?ver=2' type='text/css' media='all' />
ISSUE 2: Relocated child stylesheets
To sum it all up...
- Is it safe to include the assumption that parent themes properly enqueue the child theme styles, from the standpoint of child theme standards?
- Removing the priority could potentially create more confusion for part of the WordPress community, when child theme styles start getting overwritten by a plugin. We expect themes to overwrite styles, but not so much with plugins.
- When using a custom stylesheet for the actual child theme styles (as supposed to putting them in the predefined
style.css
), manually enqueueing that file becomes necessary. In terms of maintaining continuity across a wide spectrum of developers, wouldn't it make sense to encourage manually enqueueing the child stylesheet regardless of the possible duplicate?

PREGUNTA 1
¿Es seguro asumir que los temas principales cargan adecuadamente los estilos del tema hijo, desde el punto de vista de los estándares de temas hijos?
Como regla general, sí. Pero, nunca debes asumir. La mayoría de los desastres y fallos en producción se deben a suposiciones o hechos basados en una suposición.
HECHOS SIN SUPOSICIONES
El functions.php del tema hijo se carga primero, luego el functions.php del tema padre. Esto asegura que la hoja de estilos principal del tema padre se cargue antes que la hoja de estilos principal del tema hijo, según el código actualizado en el codex.
Veamos el tema incluido, twentytwelve. La magia ocurre aquí
wp_enqueue_style( 'twentytwelve-style', get_stylesheet_uri() );
. Así es como se encola la hoja de estilos principal. Cuando el tema está activo como tema padre, el style.css se cargará desde el tema padre ya queget_stylesheet_uri()
apuntará al style.css del directorio padre.Cuando cambias a un tema hijo,
get_stylesheet_uri()
"cambia" su ruta para apuntar al style.css del tema hijo, lo que significa que ahorawp_enqueue_style( 'twentytwelve-style', get_stylesheet_uri() );
carga el style.css del hijo en lugar del padre.Todos los demás estilos del tema padre se cargan normalmente en el orden en que están escritos.
POTENCIALES PROBLEMAS
Estilos en línea y hojas de estilo añadidas directamente en la plantilla del encabezado. He realizado pruebas sobre este tema. Si la hoja de estilos del padre no se encola usando
wp_enqueue_scripts
y se carga directamente en el header, entonces la hoja de estilos principal del tema hijo se carga primero. Como solución, anteriormente he recomendado copiar el header.php del padre al tema hijo y eliminar esas llamadas. Luego tendrás que encolar tanto los estilos del tema padre como del hijo, además de cualquier otra hoja de estilos que se cargara directamente en el header.php como se describe en el OP función obsoletaMe he encontrado con esto un par de veces: estilos (y scripts) cargados directamente en el header, y debido a esto se omite la llamada a
wp_head
. Esto hará que tu acción de encolado falle silenciosamente, por lo que tus estilos simplemente no aparecerán.Prioridades mal configuradas. No es necesario establecer prioridades en las acciones del padre o del hijo al enganchar tus funciones de encolado. Cuando ambas tienen la misma prioridad por defecto, se aplica la regla de "primero en llegar, primero en servirse". Esto asegurará que el orden de carga sea correcto.
NOTA PARA AUTORES DE TEMAS PADRE
El método correcto y aceptado para añadir estilos y scripts a un tema es mediante el hook de acción wp_enqueue_scripts
. Nunca añadas estilos y scripts directamente en la plantilla del header, y no establezcas ninguna prioridad en tu acción al enganchar tu función.
Siempre carga la hoja de estilos principal así:
wp_enqueue_style( 'twentytwelve-style', get_stylesheet_uri() );
Esto asegurará que se cargue la hoja de estilos principal del hijo cuando esté en uso un tema hijo.
TU RESPONSABILIDAD COMO AUTOR DE TEMAS HIJO
Tómate tu tiempo para estudiar el tema padre. Conoce el tema padre, asegúrate de estar familiarizado con sus estructuras y cómo se usan las funciones y hooks en el tema. No puedes crear un tema hijo exitoso sin conocer a fondo cómo funciona el tema padre. Es tu responsabilidad asegurarte que los estilos y scripts se carguen correctamente para que tu código funcione como se espera.
Siempre informa al autor del tema padre sobre cualquier código con el que no estés satisfecho. Por ejemplo, si el autor añadió sus estilos directamente al header, hazle saber que esta es la forma incorrecta de hacerlo y pídele que lo corrija en una futura versión.
PREGUNTA 2
Eliminar la prioridad podría potencialmente crear más confusión para parte de la comunidad WordPress, cuando los estilos del tema hijo empiezan a ser sobrescritos por un plugin. Esperamos que los temas sobrescriban estilos, pero no tanto con los plugins.
Desafortunadamente no hay un método directo para protegerse contra esto. El hecho es que los estilos de plugins nunca deberían sobrescribir los estilos por defecto del tema sin el consentimiento del usuario final. En mi opinión, esto es mala práctica o negligencia por parte del autor del plugin. Sugeriría que en un caso así, contactes al autor del plugin y le informes sobre esto.
También siempre tienes la opción de desencolar y desregistrar un estilo (o script) que no necesites, o al que necesites cambiar la prioridad, y luego volver a encolarlo y registrarlo como en tu código anterior (lo cual está perfectamente bien). Solo una nota sobre tu shivm, es mejor práctica desencolar y desregistrar un estilo o script.
PREGUNTA 3
Cuando se usa una hoja de estilos personalizada para los estilos reales del tema hijo (en lugar de ponerlos en el style.css predefinido), se hace necesario encolar manualmente ese archivo. En términos de mantener continuidad entre una amplia gama de desarrolladores, ¿no tendría sentido fomentar el encolado manual de la hoja de estilos del hijo independientemente de la posible duplicación?
No creo que haya una respuesta directa blanco y negro para este tema. Respondería diciendo: haz con lo que te sientas cómodo siempre que esté dentro de ciertas pautas que gobiernan la acción.
Las hojas de estilos no están para añadir funcionalidad, sino para añadir experiencia visual al usuario. Los estilos también se envían directamente tal cual al navegador donde se procesan. WordPress no juega ningún rol aquí.
Basado en este hecho, realmente no veo banderas rojas amenazantes al cargar una hoja de estilos dos veces. Esto podría costar unos milisegundos en rendimiento. Para ser honesto, aparte de esto, no estoy seguro de cómo manejan los duplicados los diferentes navegadores. Esto es algo que tú como lector puedes ir a probar.
En mi humilde opinión, los duplicados nunca son buenos y siempre deberían evitarse. Sugeriría que si realmente quieres encolar manualmente la hoja de estilos principal del hijo por cualquier razón, deberías usar tu código en tu shivm. Desencola y desregistra el duplicado añadido por defecto y luego vuelve a encolar la hoja de estilos normalmente.
Solo una cosa más para recordar: las funciones de encolado y registro tienen un parámetro $dependancy
que también puedes usar. Así que es fácil cargar una hoja de estilos secundaria y hacerla dependiente de la hoja de estilos principal de tu tema hijo.
EN CONCLUSIÓN
Desde la actualización reciente del codex, el feedback ha sido increíble y me gustaría agradecer los comentarios de todos sobre esto. Me gustaría animar a todos a participar en cualquier tipo de feedback sobre esta pregunta en particular. Si tienes algo que añadir o comentar, por favor hazlo.

Pieter, gracias por tu respuesta detallada. Hoy he estado muy ocupado pero tengo algunas ideas basadas en lo que dijiste que espero añadir más tarde esta noche.
