Escribir CSS eficaz

  • Enlace amigable (slug) de la revisión: Escribir_CSS_eficaz
  • Título de la revisión: Escribir CSS eficaz
  • Id de la revisión: 107680
  • Creada:
  • Creador: another_sam
  • ¿Es la revisión actual? No
  • Comentario mejor estilo gráfico. menos traducciones literales.; 777 words added, 759 words removed; page display name changed to 'Escritura de CSS eficiente en el UI de Mozilla'

Contenido de la revisión

Este documente da pautas para optimizar código CSS para su uso en la Interfaz de Usuario (UI) de Mozilla.

La primera sección es una discusión general de cómo el sistema de estilo de Mozilla clasifica reglas. Las siguientes secciones contienen pautas para escribir reglas que saquen provecho de la implementación del sistema de estilo de Mozilla.

Cómo el sistema clasifica reglas

El sistema de estilo clasifica reglas en cuatro categorías principales:

  1. Reglas ID
  2. Reclas de clase
  3. Reglas de etiqueta
  4. Reglas universales

Es crítico entender estas categorías, ya que son los bloques de construcción fundamental de la detección de reglas.

Se usa el término selector clave en los párrafos que siguen. El selector clave es la última parte del selector (la parte que coincide con el elemento siendo detectado, en lugar de sus ancestros).

Por ejemplo, en la regla...

a img, div > p, h1 + [title] {…} 

…los selectores clave son img, p, y {{ mediawiki.external('title') }}.

Reglas ID

La primera categoría consiste en aquellas reglas que tienen un selector ID como su selector clave.

Ejemplo

button#backButton {…}                               /* Esto es una regla de categoría ID */  #urlBar[type="autocomplete"] {…}                    /* Esto es una regla de categoría ID */  treeitem > treerow > treecell#myCell:active {…}     /* Esto es una regla de categoría ID */ 

Reglas del clase

Si una regla tiene una clase especificada como selector clave, va en esta categoría.

Ejemplo

button.toolbarButton {…}			/* Esto es una regla de clase */  .fancyText {…}					/* Esto es una regla de clase */  menuitem > .menu-left[checked="true"] {…}	/* Esto es una regla de clase */ 

Reglas de etiqueta

Si no se especifica clase o ID como selector clave, el siguiente candidato es la categoría etiqueta. Si una regla tiene una etiqueta especificada, entonces la regla va en esta categoría.

Ejemplo

td {…}				/* Esto es una regla de etiqueta */  treeitem > treerow {…}		/* Esto es una regla de etiqueta */ input[type="checkbox"] {…}	/* Esto es una regla de etiqueta */ 

Reglas universales

El resto de reglas van en esta categoría.

Ejemplo

[hidden="true"] {…}			/* Esto es una regla universal */  * {…}					/* Esto es una regla universal */  tree > [collapsed="true"] {…}		/* Esto es una regla universal */

Cómo el sistema detecta reglas

El sistema de estilo detecta reglas comenzando por el selector clave, y después yendo hacia la izquierda (buscando cualquier ancestro en el selector de la regla). Mientras el subárbol del selector continúa la búsqueda, el sistema de estilo continúa buscando hacia la izquierda hasta que o bien detecta la regla, o bien la abandona porque no coincide.

El concepto más fundamental es este filtrado de reglas. Las categorías existen para descargar reglas irrelevantes (para que el sistema no pierda el tiempo intentando detectarlas).

Ésta es la clave para aumentar el rendimiento de forma drástica: Cuantas menos reglas se requieran para un elemento dado, más rápida será la resolución.

Por ejemplo, si un elemento tiene un ID, sólo reglas de ID que detectan el ID del elemento serán comprobadas. Sólo reglas de clase para cada clase encontrada en el elemento serán comprobadas. Sólo reglas de etiqueta que detecten la etiqueta serán comprobadas. Las reglas universales serán siempre comprobadas.

 

Pautas para CSS eficiente

Evita reglas universales

¡Asegúrate de que ninguna regla es de la categoría universal!

No califiques reglas de ID con nombres de etiqueta o clases

Si una regla tiene un selector ID como selector clave, no añadas el nombre de la etiqueta a la regla. Dado que los IDs son únicos, añadir un nombre de etiqueta ralentizaría el proceso de detección innecesariamente.

Excepción: Cuando es deseable cambiar la clase de un elemento dinámicamente para aplicar diferentes estilos en diferentes situaciones, pero la misma clase se va a compartir con otros elementos.
MAL
button#backButton {…}
MAL
.menu-left#newMenuIcon {…}
BIEN
#backButton {…}
BIEN
#newMenuIcon {…}

No califiques reglas de clase con reglas de etiqueta

El concepto previo también aplica aquí. Todos los nombres de clase son únicos.

Una convención que puedes usar es incluir el nombre de etiqueta en el nombre de la clase. Sin embargo, esto puede costarte algo de flexibilidad; si se hacen cambios de diseño a la etiqueta, los nombres de clase deberán cambiar también. (Lo mejor es escoger nombres estrictamente semánticos, ya que la flexibilidad es uno de los objetivos de las hojas de estilo).

MAL
treecell.indented {…}
BIEN
.treecell-indented {…}
MEJOR
.hierarchy-deep {…}

Usa la categoría más específica posible

La mayor causa de lentitud es tener demasiadas reglas de etiqueta. Añadiendo clases a nuestros elementos, podemos subdividir más estas reglas en reglas de categoría, cosa que elimina el tiempo gastado intentando detectar reglas para cada etiqueta.

MAL
treeitem{{ mediawiki.external('mailfolder=\"true\"') }} > treerow > treecell {…}
BIEN
.treecell-mailfolder {…}

Evita el selector descendiente

El selector descendiente es el selector más costoso en CSS. Es terriblemente costoso - especialmente si el selector es de elemento o universal.

Con frecuencia, lo que realmente se quiere es el selector de hijo.  Usar el selector descendiente está prohibido en CSS de Interfaz de Usuario sin la aprobación explícita del propietario de tu módulo de skin.

MAL
treehead treerow treecell {…}
MEJOR, PERO AÚN ASÍ MAL (ver la siguiente pauta)
treehead > treerow > treecell {…}

Las reglas de etiqueta no deberían nunca contener un selector descendiente

Evita usar el selector descendiente con reglas de elemento. Esto aumentará drásticamente el tiempo de detección (especialmente si la regla se presta a ser detectada con frecuencia) para todas las apareic de ese elemento.

MAL
treehead > treerow > treecell {…}
BIEN
.treecell-header {…}

Cuestiona todos los usos del selector descendiente

Sé cauteloso usando el selector descendiente. Evítalo si puedes.

En particular, el selector descendente es usado con frecuencia por árboles RDF y menús, tal que así:

MAL
treeitem{{ mediawiki.external('IsImapServer=\"true\"') }} > treerow > .tree-folderpane-icon {…}

¡Recuerda que los atributos REF pueden estar duplicados en una plantilla! Aprovéchate de esto. Duplica las propiedades RDF en elementos XUL descendientes para cambiarlos según el atributo.

BIEN
.tree-folderpane-icon{{ mediawiki.external('IsImapServer=\"true\"') }} {…}

Cuenta con la herencia

¡Aprende qué propiedades se heredan, y permite que lo hagan!

Por ejemplo, los widgets XUL están explícitamente puestos para que las reglas list-style-image o font de un padre se filtren hasta contenido anónimo <!-- esto de "contenido anónimo"... yo por lo menos no lo entiendo -->. No es necesario gastar tiempo en reglas que tratan directamente con contenido anónimo.

MAL
#bookmarkMenuItem > .menu-left { list-style-image: url(blah) }
BIEN
#bookmarkMenuItem { list-style-image: url(blah) }

En el ejemplo de arriba, el querer dar estilo a contenido anónimo (sin aprovechar la herencia de list-style-image) ha resultado en una regla de clase, cuando la regla debeŕia haber sido de ID - ¡la categoría más específica de todas!

Recuerda: Todos los elementos tiene las mismas clases - especialmente el contenido anónimo!

La regla "mala" de arriba obliga a cada icono del menú a ser comprobado por si está dentro del ítem de menú de bookmarks.

¡Usa -moz-image-region!

Poner un montón de imágenes en un solo archivo de imagen y seleccionarlas con {{ Cssxref("-moz-image-region") }} pfunciona significativamente más rápido que poner cada imagen en su propio archivo.

Información del Documento Original

{{ languages( { "en": "en/Writing Efficient CSS for use in the Mozilla UI", "ja": "ja/Writing_Efficient_CSS" } ) }}

Fuente de la revisión

<p>Este documente da pautas para optimizar código CSS para su uso en la Interfaz de Usuario (UI) de Mozilla.</p>
<p>La primera sección es una discusión general de cómo el sistema de estilo de Mozilla clasifica reglas. Las siguientes secciones contienen pautas para escribir reglas que saquen provecho de la implementación del sistema de estilo de Mozilla.</p>
<h3 name="How_the_style_system_breaks_up_rules">Cómo el sistema clasifica reglas</h3>
<p>El sistema de estilo clasifica reglas en cuatro categorías principales:</p>
<ol> <li>Reglas ID</li> <li>Reclas de clase</li> <li>Reglas de etiqueta</li> <li>Reglas universales</li>
</ol>
<p>Es crítico entender estas categorías, ya que son los bloques de construcción fundamental de la detección de reglas.</p>
<p>Se usa el término selector clave en los párrafos que siguen. El selector clave es la última parte del selector (la parte que coincide con el elemento siendo detectado, en lugar de sus ancestros).</p>
<p>Por ejemplo, en la regla...</p>
<p><code style=""> </code></p>
<pre class="eval deki-transform"><code style="">a img, div &gt; p, h1 + [title] {…} </code></pre>
<p><code style=""> </code></p>
<p>…los selectores clave son <code>img</code>, <code>p</code>, y <code>{{ mediawiki.external('title') }}</code>.</p>
<h4 name="ID_Rules">Reglas ID</h4>
<p>La primera categoría consiste en aquellas reglas que tienen un selector ID como su selector clave.</p>
<h5>Ejemplo</h5>
<p><code style=""> </code></p>
<pre class="eval deki-transform"><code style="">button#backButton {…}                               /* Esto es una regla de categoría ID */  #urlBar[type="autocomplete"] {…}                    /* Esto es una regla de categoría ID */  treeitem &gt; treerow &gt; treecell#myCell:active {…}     /* Esto es una regla de categoría ID */ </code></pre>
<p><code style=""> </code></p>
<h4 name="Class_Rules">Reglas del clase</h4>
<p>Si una regla tiene una clase especificada como selector clave, va en esta categoría.</p>
<h5>Ejemplo</h5>
<p><code style=""> </code></p>
<pre class="eval deki-transform"><code style="">button.toolbarButton {…}			/* Esto es una regla de clase */  .fancyText {…}					/* </code><code style="">Esto es una regla de clase </code><code style="">*/  menuitem &gt; .menu-left[checked="true"] {…}	/* </code><code style="">Esto es una regla de clase</code><code style=""> */ </code></pre>
<p><code style=""> </code></p>
<h4 name="Tag_Rules">Reglas de etiqueta</h4>
<p>Si no se especifica clase o ID como selector clave, el siguiente candidato es la categoría etiqueta. Si una regla tiene una etiqueta especificada, entonces la regla va en esta categoría.</p>
<p>Ejemplo</p>
<p><code style=""> </code></p>
<pre class="eval deki-transform"><code style="">td {…}				/* Esto es una regla de etiqueta */  treeitem &gt; treerow {…}		/* Esto es una regla de etiqueta */ input[type="checkbox"] {…}	/* Esto es una regla de etiqueta */ </code></pre>
<p><code style=""> </code></p>
<h4 name="Universal_Rules">Reglas universales</h4>
<p>El resto de reglas van en esta categoría.</p>
<h5>Ejemplo</h5>
<p><code style=""> </code></p>
<pre class="eval deki-transform"><code style="">[hidden="true"] {…}			/* </code><code style="">Esto es una regla universal</code><code style=""> */  * {…}					/* </code><code style="">Esto es una regla universal</code><code style=""> */  tree &gt; [collapsed="true"] {…}		/* </code><code style="">Esto es una regla universal</code><code style=""> */</code></pre>
<p><code style=""> </code></p>
<h3 name="How_the_Style_System_Matches_Rules">Cómo el sistema detecta reglas</h3>
<p>El sistema de estilo detecta reglas comenzando por el selector clave, y después yendo hacia la izquierda (buscando cualquier ancestro en el selector de la regla). Mientras el subárbol del selector continúa la búsqueda, el sistema de estilo continúa buscando hacia la izquierda hasta que o bien detecta la regla, o bien la abandona porque no coincide.</p>
<p>El concepto más fundamental es este filtrado de reglas. Las categorías existen para descargar reglas irrelevantes (para que el sistema no pierda el tiempo intentando detectarlas).</p>
<p>Ésta es la clave para aumentar el rendimiento de forma drástica: <strong>Cuantas menos reglas se requieran para un elemento dado, más rápida será la resolución.</strong></p>
<p>Por ejemplo, si un elemento tiene un ID, sólo reglas de ID que detectan el ID del elemento serán comprobadas. Sólo reglas de clase para cada clase encontrada en el elemento serán comprobadas. Sólo reglas de etiqueta que detecten la etiqueta serán comprobadas. Las reglas universales serán siempre comprobadas.</p>
<p> </p>
<h3 name="Guidelines_for_Efficient_CSS">Pautas para CSS eficiente</h3>
<h4 name="Avoid_Universal_Rules.21">Evita reglas universales</h4>
<p>¡Asegúrate de que ninguna regla es de la categoría universal!</p>
<h4 name="Don.27t_qualify_ID-categorized_rules_with_tag_names_or_classes">No califiques reglas de ID con nombres de etiqueta o clases</h4>
<p><strong>Si una regla tiene un selector ID como selector clave, no añadas el nombre de la etiqueta a la regla.</strong> Dado que los IDs son únicos, añadir un nombre de etiqueta ralentizaría el proceso de detección innecesariamente.</p>
<div class="note"><strong>Excepción: </strong>Cuando es deseable cambiar la clase de un elemento dinámicamente para aplicar diferentes estilos en diferentes situaciones, pero la misma clase se va a compartir con otros elementos.</div>
<dl style="margin: 1em 12.5%;"> <dt><span style="color: rgb(128, 0, 0);">MAL</span></dt> <dd><code>button#backButton {…}</code></dd> <dt><span style="color: rgb(128, 0, 0);">MAL</span></dt> <dd><code>.menu-left#newMenuIcon {…}</code></dd> <dt><span style="color: rgb(51, 153, 102);">BIEN</span></dt> <dd><code>#backButton {…}</code></dd> <dt><span style="color: rgb(51, 153, 102);">BIEN</span></dt> <dd><code>#newMenuIcon {…}</code></dd>
</dl>
<h4 name="Don.27t_qualify_class-categorized_rules_with_tag_names">No califiques reglas de clase con reglas de etiqueta</h4>
<p>El concepto previo también aplica aquí. Todos los nombres de clase son únicos.</p>
<p>Una convención que puedes usar es incluir el nombre de etiqueta <em>en</em> el nombre de la clase. Sin embargo, esto puede costarte algo de flexibilidad; si se hacen cambios de diseño a la etiqueta, los nombres de clase deberán cambiar también. (Lo mejor es escoger nombres estrictamente semánticos, ya que la flexibilidad es uno de los objetivos de las hojas de estilo).</p>
<dl style="margin: 1em 12.5%;"> <dt><span style="color: rgb(128, 0, 0);">MAL</span></dt> <dd><code>treecell.indented {…}</code></dd> <dt><span style="color: rgb(153, 204, 0);">BIEN</span></dt> <dd><code>.treecell-indented {…}</code></dd> <dt><span style="color: rgb(51, 153, 102);">MEJOR<br> </span></dt> <dd><code>.hierarchy-deep {…}</code></dd>
</dl>
<h4 name="Try_to_put_rules_into_the_most_specific_category_you_can.21">Usa la categoría más específica posible</h4>
<p><strong>La mayor causa de lentitud es tener demasiadas reglas de etiqueta.</strong> Añadiendo clases a nuestros elementos, podemos subdividir más estas reglas en reglas de categoría, cosa que elimina el tiempo gastado intentando detectar reglas para cada etiqueta.</p>
<dl style="margin: 1em 12.5%;"> <dt><span style="color: rgb(128, 0, 0);">MAL</span></dt> <dd><code>treeitem{{ mediawiki.external('mailfolder=\"true\"') }} &gt; treerow &gt; treecell {…}</code></dd> <dt><span style="color: rgb(51, 153, 102);">BIEN</span></dt> <dd><code>.treecell-mailfolder {…}</code></dd>
</dl>
<h4 name="Avoid_the_descendant_selector.21">Evita el selector descendiente</h4>
<p><strong>El selector descendiente es el selector más costoso en CSS.</strong> Es <em>terriblemente</em> costoso - especialmente si el selector es de elemento o universal.</p>
<p>Con frecuencia, lo que realmente se quiere es <strong>el selector de hijo</strong>.  Usar el selector descendiente está prohibido en CSS de Interfaz de Usuario sin la aprobación explícita del propietario de tu módulo de skin.</p>
<dl style="margin: 1em 12.5%;"> <dt><span style="color: rgb(128, 0, 0);">MAL</span></dt> <dd><code>treehead treerow treecell {…}</code></dd> <dt><span style="color: rgb(153, 51, 0);">MEJOR, PERO AÚN ASÍ MAL (ver la siguiente pauta)</span></dt> <dd><code>treehead &gt; treerow &gt; treecell {…}</code></dd>
</dl>
<h4 name="Tag-categorized_rules_should_never_contain_a_child_selector.21">Las reglas de etiqueta no deberían <em>nunca</em> contener un selector descendiente</h4>
<p><strong>Evita usar el selector descendiente con reglas de elemento.</strong> Esto aumentará drásticamente el tiempo de detección (especialmente si la regla se presta a ser detectada con frecuencia) para todas las apareic de ese elemento.</p>
<dl style="margin: 1em 12.5%;"> <dt><span style="color: rgb(128, 0, 0);">MAL</span></dt> <dd><code>treehead &gt; treerow &gt; treecell {…}</code></dd> <dt><span style="color: rgb(51, 153, 102);">BIEN</span></dt> <dd><code>.treecell-header {…}</code></dd>
</dl>
<h4 name="Question_all_usages_of_the_child_selector.21">Cuestiona todos los usos del selector descendiente</h4>
<p><strong>Sé cauteloso usando el selector descendiente. </strong>Evítalo si puedes.</p>
<p>En particular, el selector descendente es usado con frecuencia por árboles RDF y menús, tal que así:</p>
<dl style="margin: 1em 12.5%;"> <dt><span style="color: rgb(128, 0, 0);">MAL<br> </span></dt> <dd><code>treeitem{{ mediawiki.external('IsImapServer=\"true\"') }} &gt; treerow &gt; .tree-folderpane-icon {…}</code></dd>
</dl>
<p>¡Recuerda que los atributos REF pueden estar duplicados en una plantilla! Aprovéchate de esto. Duplica las propiedades RDF en elementos XUL descendientes para cambiarlos según el atributo.</p>
<dl style="margin: 1em 12.5%;"> <dt><span style="color: rgb(51, 153, 102);">BIEN</span></dt> <dd><code>.tree-folderpane-icon{{ mediawiki.external('IsImapServer=\"true\"') }} {…}</code></dd>
</dl>
<h4 name="Rely_on_inheritance.21">Cuenta con la herencia</h4>
<p>¡Aprende qué propiedades se heredan, y permite que lo hagan!</p>
<p>Por ejemplo, los widgets XUL están explícitamente puestos para que las reglas list-style-image o font de un padre se filtren hasta contenido anónimo &lt;!-- esto de "contenido anónimo"... yo por lo menos no lo entiendo --&gt;. No es necesario gastar tiempo en reglas que tratan directamente con contenido anónimo.</p>
<dl style="margin: 1em 12.5%;"> <dt><span style="color: rgb(128, 0, 0);">MAL</span></dt> <dd><code>#bookmarkMenuItem &gt; .menu-left { list-style-image: url(blah) }</code></dd> <dt><span style="color: rgb(51, 153, 102);">BIEN</span></dt> <dd><code>#bookmarkMenuItem { list-style-image: url(blah) }</code></dd>
</dl>
<p>En el ejemplo de arriba, el querer dar estilo a contenido anónimo (sin aprovechar la herencia de list-style-image) ha resultado en una regla de clase, cuando la regla debeŕia haber sido de ID - ¡la categoría más específica de todas!</p>
<p><strong>Recuerda: </strong>Todos los elementos tiene las mismas clases - especialmente el contenido anónimo!</p>
<p>La regla "mala" de arriba obliga a cada icono del menú a ser comprobado por si está dentro del ítem de menú de bookmarks.</p>
<h4 name="Use_-moz-image-region.21">¡Usa <code>-moz-image-region</code>!</h4>
<p>Poner un montón de imágenes en un solo archivo de imagen y seleccionarlas con <code>{{ Cssxref("-moz-image-region") }} </code>pfunciona significativamente más rápido que poner cada imagen en su propio archivo. </p>
<div class="originaldocinfo">
<h3 name="Original_Document_Information">Información del Documento Original</h3>
<ul> <li>Autor: David Hyatt</li> <li>Última fecha de actualización: 2000-04-21</li> <li>URL del documento original: <a class=" external" href="http://www.mozilla.org/xpfe/goodcss.html" rel="freelink">http://www.mozilla.org/xpfe/goodcss.html</a></li>
</ul>
</div>
<p>{{ languages( { "en": "en/Writing Efficient CSS for use in the Mozilla UI", "ja": "ja/Writing_Efficient_CSS" } ) }}</p>
Revertir a esta revisión