Estilo com CSS

Os aplicativos do Blockly são construídos com elementos HTML e SVG. Esses elementos são rotulados com classes CSS que identificam o que eles representam (por exemplo, blocklyBlock, blocklyField) e o estado (por exemplo, blocklyEditing, blocklySelected). O Blockly também oferece um conjunto padrão de regras CSS.

Você pode usar CSS para estilizar seu aplicativo:

  • Substitua as regras CSS do Blockly pelas suas próprias.
  • Adicione suas próprias classes CSS aos componentes do Blockly para mais especificidade.
  • Use classes e regras de CSS para estilizar componentes personalizados.

Classes CSS

Os aplicativos do Blockly usam classes CSS para identificar elementos que serão estilizados. Isso oferece um controle mais refinado do que os seletores de tipo (elemento).

Classes CSS do Blockly

O Blockly usa classes CSS para fornecer os seguintes tipos de informações sobre os elementos HTML e SVG que ele usa.

  • Tipo. A maioria das classes CSS do Blockly identifica o que um elemento representa. Por exemplo, o elemento raiz de um bloco é rotulado como blocklyBlock. Alguns elementos são rotulados com várias classes, cada uma mais específica que a anterior. Por exemplo, o elemento raiz de um campo de entrada de texto é rotulado como blocklyField, blocklyInputField e blocklyTextInputField. As classes de tipo permanecem as mesmas durante todo o ciclo de vida de um componente.

  • Estado. O Blockly também usa classes CSS para especificar o estado de um componente. Por exemplo, quando o cursor está em um campo de entrada de texto, o elemento raiz é rotulado com a classe blocklyEditing. Quando o cursor é movido para longe, essa classe é removida.

  • Mais informações O Blockly usa algumas classes CSS para fornecer mais informações. Por exemplo, a injeção <div> tem classes que fornecem o nome do renderizador e do tema atuais do espaço de trabalho. Essas classes geralmente permanecem as mesmas durante todo o ciclo de vida do aplicativo.

A maneira mais fácil de descobrir quais classes CSS o Blockly usa é abrir as ferramentas para desenvolvedores do navegador e inspecionar os elementos usados pelo aplicativo.

Classes CSS personalizadas

É possível usar classes CSS personalizadas para dar mais especificidade aos componentes do Blockly.

Espaços de trabalho

Para adicionar ou remover uma classe CSS da injeção <div> de um espaço de trabalho, chame WorkspaceSvg.addClass ou WorkspaceSvg.removeClass.

Caixas de ferramentas

Para adicionar uma classe CSS a um botão ou rótulo em uma caixa de ferramentas, use a chave web-class na definição JSON da caixa de ferramentas. Para mais informações, consulte Botões e rótulos.

Para substituir as classes CSS usadas nas várias partes de uma categoria, use a chave cssConfig na definição JSON da categoria. Assim, é possível estilizar categorias individuais. Para mais informações, consulte CSS de categoria.

Bloqueios

Para adicionar classes CSS a um bloco personalizado, transmita uma string ou matriz de strings à chave 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,
}]);

Você também pode adicionar ou remover uma classe CSS do elemento <g> de um bloco chamando BlockSvg.addClass ou BlockSvg.removeClass.

Campos de marcador

Para adicionar ou remover uma classe CSS do elemento <text> usado por um campo de rótulo ou campo de rótulo serializável, chame FieldLabel.setClass. Também é possível transmitir um nome de classe para o construtor do rótulo.

Classes CSS e componentes personalizados

Ao construir um componente personalizado, use um dos seguintes métodos para adicionar classes CSS personalizadas:

  • Se o componente for uma subclasse de Field ou Icon, substitua o método initView. Exemplo:

    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 mais informações, consulte Personalizar campos com CSS ou Criar a visualização do ícone.

  • Ao construir um elemento SVG, transmita sua classe para Blockly.utils.dom.createSvgElement:

    this.svgRoot = Blockly.utils.dom.createSvgElement(Svg.G, {'class': 'myCustomComponent'});
    
  • Ao construir um elemento HTML, use Blockly.utils.dom.addClass:

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

Para adicionar ou remover classes após a construção, use Blockly.utils.dom.addClass ou Blockly.utils.dom.removeClass.

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

Contexto das regras CSS

Se você entende as propriedades de estilo SVG e a cascata CSS, pode pular esta seção.

Propriedades de estilo SVG x propriedades de CSS

Os elementos SVG são estilizados com propriedades de estilização SVG. Eles podem ser usados como atributos em elementos SVG (também conhecidos como atributos de apresentação) ou em regras CSS. Portanto, todos os comandos a seguir fazem a mesma coisa.

<!-- 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;" ... />

A lista de propriedades de estilização do SVG está relacionada, mas é diferente da lista de propriedades do CSS:

  • Mesmo conceito, mesmo nome. Por exemplo, SVG e CSS usam direction para especificar se o texto é LTR ou RTL.
  • Mesmo conceito, nome diferente. Por exemplo, o SVG usa fill para especificar a cor de preenchimento, e o CSS usa background-color.
  • Apenas CSS. O CSS tem muitas propriedades que não estão no SVG, como margin e padding.
  • Somente SVG. O SVG tem algumas propriedades que não estão no CSS, como x e y.

Portanto, se você estiver estilizando um elemento SVG, use propriedades de estilização do SVG. Se você estiver estilizando um elemento HTML, use propriedades de CSS.

Cascata CSS

A cascata do CSS determina as prioridades das regras de CSS, que definem qual regra usar se mais de uma se aplica a uma determinada propriedade e elemento. A seguinte cascata simplificada abrange as partes mais usadas pelo Blockly e pode ajudar a resolver a questão: "Por que meu CSS não funciona?"

Cascata simplificada

Para determinar qual regra se aplica a um elemento e uma propriedade específicos, siga estas etapas e pare quando restar apenas uma regra:

  1. Reúna todas as regras que se aplicam à propriedade e ao elemento.
  2. Se alguma regra tiver uma anotação !important, descarte todas as regras que não têm uma anotação !important.
  3. Escolha as regras com a maior especificidade.

    • Os atributos de apresentação SVG têm uma especificidade de zero.
    • A especificidade das regras em uma tag <style> ou em uma folha de estilo externa é calculada normalmente.
    • Os estilos inline (definidos por um atributo style) têm uma especificidade maior do que qualquer seletor.
  4. Escolha a regra que aparece por último no documento.

  5. Se nenhuma regra se aplicar, herde o valor da propriedade do elemento pai.

Esse algoritmo não considera as seguintes partes da cascata:

  • A propriedade transition, que tem a prioridade mais alta. O Blockly usa alguns deles.
  • A regra-at @media. O Blockly usa um deles.
  • Regras especificadas pelo navegador ou pelo usuário.
  • As regras @ @scope e @layer e a propriedade animation, que não são usadas pelo Blockly.

Regras CSS

As regras de CSS especificam como o aplicativo é estilizado. O Blockly fornece um conjunto padrão de regras que podem ser substituídas pelas suas.

Regras CSS do Blockly

O Blockly fornece um conjunto padrão de regras CSS. Como e onde essas regras são adicionadas afeta a prioridade delas.

Tags de estilo

A maioria das regras CSS do Blockly é especificada em duas tags <style>. Como essas tags aparecem perto da parte de cima da página, as regras nelas têm prioridade menor do que as regras com a mesma especificidade que aparecem mais tarde na página.

Regras Blockly.css.register

Quando o Blockly é injetado, ele adiciona uma tag <style> como filha da tag <head>. As regras nesta tag vêm de:

  • O namespace Blockly.css. Para conferir essas regras, abra core/css.ts e pesquise let content.
  • Componentes individuais, que chamam Blockly.css.register para adicionar regras de CSS específicas do componente. Como css.register adiciona essas regras ao final da string content, elas têm prioridade maior do que as regras com a mesma especificidade adicionadas anteriormente. Para conferir essas regras, consulte as chamadas para Blockly.css.register.

Se você não quiser usar essas regras, defina a opção de configuraçãocss como false. Nesse caso, você é responsável por fornecer um conjunto alternativo de regras de CSS.

Regras do renderizador

Quando o renderizador é instanciado, ele adiciona uma tag <style> que contém regras de CSS específicas do renderizador como um filho da tag <head>. Essas regras são sempre adicionadas e não são afetadas pela opção de configuração css. Para conferir essas regras, pesquise o método getCss_ no seu renderizador.

Estilos inline

Os estilos inline são especificados com o atributo style e geralmente são criados quando o DOM de um componente é criado. Para ver uma lista parcial, consulte esta consulta do GitHub.

Os estilos inline são aplicados diretamente ao elemento em que ocorrem e têm uma especificidade maior do que qualquer seletor. Por isso, para substituir esses valores, geralmente é necessário usar uma anotação !important.

Atributos de apresentação SVG

Os atributos de apresentação do SVG são propriedades de estilo do SVG usadas como atributos de elementos SVG. Elas têm uma especificidade de zero e não podem conter uma anotação !important. Por isso, têm a prioridade mais baixa de todas as regras do Blockly. O Blockly geralmente os cria em chamadas para createSvgElement.

Adicionar suas próprias regras de CSS

É possível adicionar suas próprias regras de CSS usando os mesmos métodos do Blockly:

  • Chame Blockly.css.register antes de injetar o Blockly. Suas regras serão adicionadas depois das do Blockly e terão uma prioridade maior do que as regras do Blockly com a mesma especificidade.
  • Adicione uma tag <style> ou um link a uma folha de estilo externa como um filho posterior da tag <head>. Como o Blockly adiciona as regras dele como os dois primeiros filhos da tag <head>, suas regras terão uma prioridade maior do que as do Blockly com a mesma especificidade.
  • Use estilos in-line para adicionar estilos a elementos em um componente personalizado. Essas regras têm uma especificidade maior do que qualquer regra com um seletor.
  • Use atributos de apresentação em elementos SVG em um componente personalizado. Essas regras têm uma especificidade menor do que qualquer regra com um seletor.

Solução de problemas

Se o CSS não estiver funcionando, confira algumas possíveis causas:

  • Você está usando propriedades CSS em um elemento SVG ou propriedades de estilo SVG em um elemento HTML. Consulte Propriedades de estilo SVG x propriedades de CSS.

  • Sua regra tem uma prioridade menor do que outra. Isso geralmente se deve a uma especificidade menor. Algumas maneiras de corrigir isso:

    • Use um seletor de classe em vez de um seletor de tipo (elemento).
    • Use vários seletores.
    • Se possível, adicione uma classe personalizada ao elemento de destino e use essa classe na regra.
    • Como último recurso, adicione uma anotação !important à sua regra. Essa é sua única opção se uma regra concorrente for especificada usando um estilo inline (atributo style).
  • Sua regra tem a mesma especificidade que outra, mas aparece antes na página. Se não for possível aumentar a especificidade da regra, mova-a para mais tarde na página.

Há dois tipos de regras de CSS que não podem ser substituídas:

  • Propriedades definidas em uma regra transition.
  • Regras !important especificadas pelo navegador.