Estilo con CSS

Las aplicaciones de Blockly se construyen con elementos HTML y SVG. Estos elementos se etiquetan con clases de CSS que identifican lo que representan (p.ej., blocklyBlock, blocklyField), así como su estado (p.ej., blocklyEditing, blocklySelected). Blockly también proporciona un conjunto predeterminado de reglas de CSS.

Puedes usar CSS para diseñar tu aplicación:

  • Anula las reglas de CSS de Blockly con tus propias reglas.
  • Agrega tus propias clases de CSS a los componentes de Blockly para obtener mayor especificidad.
  • Usa clases y reglas de CSS para aplicar estilo a los componentes personalizados.

Clases de CSS

Las aplicaciones de Blockly usan clases de CSS para identificar los elementos a los que se les aplicará un diseño. Esto proporciona un control más detallado que los selectores de tipo (elemento).

Clases de CSS de Blockly

Blockly usa clases CSS para proporcionar los siguientes tipos de información sobre los elementos HTML y SVG que usa.

  • Tipo: La mayoría de las clases CSS de Blockly identifican lo que representa un elemento. Por ejemplo, el elemento raíz de un bloque se etiqueta como blocklyBlock. Algunos elementos están etiquetados con varias clases, cada una más específica que la anterior. Por ejemplo, el elemento raíz de un campo de entrada de texto se etiqueta como blocklyField, blocklyInputField y blocklyTextInputField. Las clases de escritura permanecen iguales durante la vida útil de un componente.

  • Estado: Blockly también usa clases CSS para especificar el estado de un componente. Por ejemplo, cuando el cursor se encuentra en un campo de entrada de texto, su elemento raíz se etiqueta con la clase blocklyEditing. Cuando se aleja el cursor, se quita esta clase.

  • Información adicional. Blockly usa algunas clases de CSS para proporcionar información adicional. Por ejemplo, la inyección <div> tiene clases que proporcionan el nombre del renderizador y el tema actuales del espacio de trabajo. Por lo general, estas clases permanecen iguales durante toda la vida útil de la aplicación.

La forma más sencilla de descubrir qué clases de CSS usa Blockly es abrir las herramientas para desarrolladores de tu navegador y, luego, inspeccionar los elementos que usa tu aplicación.

Clases de CSS personalizadas

Puedes usar clases de CSS personalizadas para proporcionar más especificidad a los componentes de Blockly.

Lugares de trabajo

Para agregar o quitar una clase CSS de la inyección <div> de un espacio de trabajo, llama a WorkspaceSvg.addClass o WorkspaceSvg.removeClass.

Cajas de herramientas

Para agregar una clase CSS a un botón o una etiqueta en una caja de herramientas, usa la clave web-class en la definición JSON de la caja de herramientas. Para obtener más información, consulta Botones y etiquetas.

Para anular las clases de CSS que se usan en las distintas partes de una categoría, usa la clave cssConfig en la definición JSON de la categoría. Esto te permite aplicar un diseño a categorías individuales. Para obtener más información, consulta CSS de categorías.

Bloqueos

Para agregar clases de CSS a un bloque personalizado, pasa una cadena o un array de cadenas a la clave classes.

Blockly.common.defineBlocksWithJsonArray([{
  "type": "string_length",
  "message0": 'length of %1',
  "args0": [
    {
      "type": "input_value",
      "name": "VALUE",
      "check": "String",
    }
  ],
  "classes": "myStringLengthBlock",
  "output": "Number",
  "colour": 160,
}]);

También puedes agregar o quitar una clase CSS del elemento <g> de un bloque llamando a BlockSvg.addClass o BlockSvg.removeClass.

Campos de etiqueta

Para agregar o quitar una clase de CSS del elemento <text> que usa un campo de etiqueta o un campo de etiqueta serializable, llama a FieldLabel.setClass. También puedes pasar un nombre de clase al constructor de la etiqueta.

Clases de CSS y componentes personalizados

Cuando construyas un componente personalizado, usa uno de los siguientes métodos para agregar clases de CSS personalizadas:

  • Si tu componente es una subclase de Field o Icon, anula el método initView. Por ejemplo:

    class MyCustomField extends Blockly.FieldTextInput {
      ...
    
      initView() {
        super.initView();
    
        // Add custom CSS class so we can style the field.
        if (this.fieldGroup_) {
          Blockly.utils.dom.addClass(this.fieldGroup_, 'myCustomField');
        }
      }
    }
    

    Para obtener más información, consulta Cómo personalizar campos con CSS o Cómo crear la vista del ícono.

  • Cuando construyas un elemento SVG, pasa tu clase a Blockly.utils.dom.createSvgElement:

    this.svgRoot = Blockly.utils.dom.createSvgElement(Svg.G, {'class': 'myCustomComponent'});
    
  • Cuando construyas un elemento HTML, usa Blockly.utils.dom.addClass:

    const myDiv = document.createElement('div');
    Blockly.utils.dom.addClass(myDiv, 'myInformation');
    

Para agregar o quitar clases después de la construcción, usa Blockly.utils.dom.addClass o Blockly.utils.dom.removeClass.

setMyHighlight(highlight) {
  if (highlight) {
    Blockly.utils.dom.addClass(this.svgRoot, 'myHighlight');
  } else {
    Blockly.utils.dom.removeClass(this.svgRoot, 'myHighlight');
  }
}

Antecedentes de las reglas de CSS

Si comprendes las propiedades de diseño de SVG y la cascada de CSS, puedes omitir esta sección.

Propiedades de diseño de SVG en comparación con las propiedades de CSS

Los elementos SVG se diseñan con propiedades de diseño SVG. Se pueden usar como atributos en elementos SVG (también conocidos como atributos de presentación) o en reglas CSS. Por lo tanto, todas las siguientes opciones hacen lo mismo.

<!-- SVG file with presentation attributes. -->
<circle fill="red" ... />
<!-- SVG file with <style> tag. -->
<style>
  circle {fill:red;}
</style>
<circle ... />
/* External CSS file.*/
circle {fill:red;}
<!-- SVG file with inline style. -->
<circle style="fill:red;" ... />

La lista de propiedades de diseño de SVG está relacionada con la lista de propiedades de CSS, pero es diferente:

  • Mismo concepto, mismo nombre. Por ejemplo, tanto SVG como CSS usan direction para especificar si el texto es LTR o RTL.
  • Mismo concepto, nombre diferente. Por ejemplo, SVG usa fill para especificar el color de relleno, mientras que CSS usa background-color.
  • Solo CSS. CSS tiene muchas propiedades que no están en SVG, como margin y padding.
  • Solo SVG. SVG tiene algunas propiedades que no están en CSS, como x y y.

Por lo tanto, si le aplicas un diseño a un elemento SVG, usa las propiedades de diseño de SVG. Si le aplicas diseño a un elemento HTML, usa propiedades CSS.

Cascada de CSS

La cascada de CSS determina las prioridades de las reglas de CSS, que determinan qué regla usar si más de una regla se aplica a una propiedad y un elemento determinados. La siguiente cascada simplificada abarca las partes de la cascada que Blockly usa con mayor frecuencia y puede ayudarte a responder la pregunta: "¿Por qué no funciona mi CSS?".

Cascada simplificada

Para determinar qué regla se aplica a un elemento y una propiedad en particular, sigue estos pasos y detente cuando solo quede una regla:

  1. Recopila todas las reglas que se aplican a la propiedad y al elemento.
  2. Si alguna regla tiene una anotación !important, descarta todas las reglas que no tengan una anotación !important.
  3. Elige las reglas con la mayor especificidad.

    • Los atributos de presentación SVG tienen una especificidad de cero.
    • La especificidad de las reglas en una etiqueta <style> o en una hoja de estilo externa se calcula de forma normal.
    • Los estilos intercalados (los que se establecen con un atributo style) tienen una especificidad mayor que cualquier selector.
  4. Elige la regla que aparece al final del documento.

  5. Si no se aplica ninguna regla, hereda el valor de la propiedad del elemento principal.

Este algoritmo no considera las siguientes partes de la cascada:

  • La propiedad transition, que tiene la prioridad más alta. Blockly usa algunos de estos.
  • La regla @media @. Blockly usa uno de estos.
  • Son las reglas especificadas por el navegador o el usuario.
  • Las reglas @ @scope y @layer, y la propiedad animation, que no usa Blockly.

Normas CSS

Las reglas de CSS especifican cómo se diseña tu aplicación. Blockly proporciona un conjunto predeterminado de reglas que puedes anular con tus propias reglas.

Reglas de CSS de Blockly

Blockly proporciona un conjunto predeterminado de reglas CSS. La forma y el lugar en que se agregan estas reglas afectan su prioridad.

Etiquetas de estilo

La mayoría de las reglas CSS de Blockly se especifican en dos etiquetas <style>. Debido a que estas etiquetas aparecen cerca de la parte superior de la página, las reglas que contienen tienen una prioridad más baja que las reglas con la misma especificidad que aparecen más adelante en la página.

Reglas de Blockly.css.register

Cuando se inyecta Blockly, se agrega una etiqueta <style> como elemento secundario de la etiqueta <head>. Las reglas de esta etiqueta provienen de las siguientes fuentes:

  • Es el espacio de nombres Blockly.css. Para ver estas reglas, abre core/css.ts y busca let content.
  • Componentes individuales que llaman a Blockly.css.register para agregar reglas CSS específicas del componente Debido a que css.register agrega estas reglas al final de la cadena content, tienen mayor prioridad que las reglas con la misma especificidad que se agregaron antes. Para ver estas reglas, consulta las llamadas a Blockly.css.register.

Si no quieres usar estas reglas, establece la opción de configuración css en false. En este caso, eres responsable de proporcionar un conjunto alternativo de reglas CSS.

Reglas del renderizador

Cuando se crea una instancia del renderizador, se agrega una etiqueta <style> que contiene reglas CSS específicas del renderizador como elemento secundario de la etiqueta <head>. Ten en cuenta que estas reglas siempre se agregan, y no se ven afectadas por la opción de configuración css. Para ver estas reglas, busca el método getCss_ en tu renderizador.

Estilos intercalados

Los estilos intercalados se especifican con el atributo style y, por lo general, se crean cuando se crea el DOM de un componente. Para ver una lista parcial, consulta esta consulta de GitHub.

Los estilos intercalados se aplican directamente al elemento en el que aparecen y tienen una especificidad mayor que cualquier selector. Por este motivo, anularlos generalmente requiere que uses una anotación !important.

Atributos de presentación de SVG

Los atributos de presentación de SVG son propiedades de diseño de SVG que se usan como atributos de elementos SVG. Tienen una especificidad de cero y no pueden contener una anotación !important, por lo que tienen la prioridad más baja de todas las reglas de Blockly. Por lo general, Blockly los crea en llamadas a createSvgElement.

Agrega tus propias reglas de CSS

Puedes agregar tus propias reglas de CSS con los mismos métodos que Blockly:

  • Llama a Blockly.css.register antes de insertar Blockly. Tus reglas se agregarán después de las de Blockly y tendrán una prioridad más alta que las reglas de Blockly con la misma especificidad.
  • Agrega una etiqueta <style> o un vínculo a una hoja de estilo externa como un elemento secundario posterior de la etiqueta <head>. Debido a que Blockly agrega sus reglas como los dos primeros elementos secundarios de la etiqueta <head>, tus reglas tendrán una prioridad más alta que las reglas de Blockly con la misma especificidad.
  • Usa estilos intercalados para agregar estilos a los elementos de un componente personalizado. Estas reglas tendrán una especificidad mayor que cualquier regla con un selector.
  • Usa atributos de presentación en elementos SVG en un componente personalizado. Estas reglas tendrán una especificidad menor que cualquier regla con un selector.

Solución de problemas

Si tu CSS no funciona, estas son algunas posibles causas:

  • Estás usando propiedades CSS en un elemento SVG o propiedades de diseño SVG en un elemento HTML. Consulta Propiedades de diseño de SVG en comparación con las propiedades de CSS.

  • Tu regla tiene una prioridad más baja que otra regla. Por lo general, esto se debe a una especificidad más baja. Estas son algunas formas posibles de solucionar el problema:

    • Usa un selector de clase en lugar de un selector de tipo (elemento).
    • Usa varios selectores.
    • Si es posible, agrega una clase personalizada a tu elemento objetivo y usa esta clase en tu regla.
    • Como último recurso, agrega una anotación !important a tu regla. Esta es tu única opción si se especifica una regla en competencia con un estilo intercalado (atributo style).
  • Tu regla tiene la misma especificidad que otra regla, pero aparece antes en la página. Si no puedes aumentar la especificidad de tu regla, muévela más abajo en la página.

Existen dos tipos de reglas de CSS que no puedes anular:

  • Son las propiedades que se establecen dentro de una regla transition.
  • Reglas !important especificadas por el navegador.