CSS を使用してスタイルを設定する

Blockly アプリケーションは HTML 要素と SVG 要素で構成されています。これらの要素には、その要素が表すもの(blocklyBlockblocklyField など)と状態(blocklyEditingblocklySelected など)を識別する CSS クラスのラベルが付けられます。Blockly には、デフォルトの CSS ルールセットも用意されています。

CSS を使用してアプリケーションのスタイルを設定できます。

  • Blockly の CSS ルールを独自のルールでオーバーライドします。
  • Blockly コンポーネントに独自の CSS クラスを追加して、特異性を高めます。
  • CSS クラスとルールを使用して、カスタム コンポーネントのスタイルを設定します。

CSS クラス

Blockly アプリケーションは、スタイル設定する要素を識別するために CSS クラスを使用します。これにより、型(要素)セレクタよりもきめ細かい制御が可能になります。

Blockly CSS クラス

Blockly は CSS クラスを使用して、使用する HTML 要素と SVG 要素に関する次の種類の情報を提供します。

  • タイプ。Blockly のほとんどの CSS クラスは、要素が何を表しているかを識別します。たとえば、ブロックのルート要素には blocklyBlock というラベルが付けられます。一部の要素には複数のクラスがラベル付けされており、それぞれが前のクラスよりも具体的です。たとえば、テキスト入力フィールドのルート要素には blocklyFieldblocklyInputFieldblocklyTextInputField というラベルが付けられます。型クラスは、コンポーネントのライフサイクル中は変更されません。

  • State. Blockly は、CSS クラスを使用してコンポーネントの状態を指定します。たとえば、カーソルがテキスト入力フィールドにある場合、そのルート要素には blocklyEditing クラスのラベルが付けられます。カーソルが移動すると、このクラスは削除されます。

  • 追加情報。Blockly は、いくつかの CSS クラスを使用して追加情報を提供します。たとえば、インジェクション <div> には、ワークスペースの現在のレンダラとテーマの名前を提供するクラスがあります。これらのクラスは通常、アプリケーションのライフサイクルを通じて同じままです。

Blockly が使用する CSS クラスを調べる最も簡単な方法は、ブラウザのデベロッパー ツールを開き、アプリケーションで使用されている要素を検査することです。

カスタム CSS クラス

カスタム CSS クラスを使用すると、Blockly コンポーネントにさらに詳細な指定を行うことができます。

ワークスペース

ワークスペースのインジェクション <div> から CSS クラスを追加または削除するには、WorkspaceSvg.addClass または WorkspaceSvg.removeClass を呼び出します。

ツールボックス

ツールボックスのボタンまたはラベルに CSS クラスを追加するには、ツールボックスの JSON 定義で web-class キーを使用します。詳しくは、ボタンとラベルをご覧ください。

カテゴリのさまざまな部分に使用される CSS クラスをオーバーライドするには、カテゴリの JSON 定義で cssConfig キーを使用します。これにより、個々のカテゴリのスタイルを設定できます。詳細については、カテゴリの CSS をご覧ください。

Blocks

カスタムブロックに CSS クラスを追加するには、文字列または文字列の配列を 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,
}]);

BlockSvg.addClass または BlockSvg.removeClass を呼び出すことで、ブロックの <g> 要素から CSS クラスを追加または削除することもできます。

ラベル フィールド

ラベル フィールドまたはシリアライズ可能なラベル フィールドで使用される <text> 要素から CSS クラスを追加または削除するには、FieldLabel.setClass を呼び出します。クラス名をラベルのコンストラクタに渡すこともできます。

CSS クラスとカスタム コンポーネント

カスタム コンポーネントを構築する場合は、次のいずれかの方法でカスタム CSS クラスを追加します。

  • コンポーネントが Field または Icon のサブクラスである場合は、initView メソッドをオーバーライドします。次に例を示します。

    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');
        }
      }
    }
    

    詳細については、CSS を使用してフィールドをカスタマイズするまたはアイコンのビューを作成するをご覧ください。

  • SVG 要素を構築するときに、クラスを Blockly.utils.dom.createSvgElement に渡します。

    this.svgRoot = Blockly.utils.dom.createSvgElement(Svg.G, {'class': 'myCustomComponent'});
    
  • HTML 要素を構築するときは、Blockly.utils.dom.addClass を使用します。

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

構築後にクラスを追加または削除するには、Blockly.utils.dom.addClass または Blockly.utils.dom.removeClass を使用します。

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

CSS ルールの背景

SVG スタイリング プロパティと CSS カスケードを理解している場合は、このセクションをスキップできます。

SVG スタイル設定プロパティと CSS プロパティ

SVG 要素は SVG スタイリング プロパティでスタイル設定されます。これらは、SVG 要素の属性(プレゼンテーション属性)または CSS ルールで使用できます。したがって、次のすべてが同じ処理を行います。

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

SVG スタイリング プロパティのリストは CSS プロパティのリストと関連していますが、異なります。

  • 同じコンセプト、同じ名前。たとえば、SVG と CSS の両方で direction を使用して、テキストが LTR か RTL かを指定します。
  • 同じコンセプトで、名前が異なります。たとえば、SVG では fill を使用して塗りつぶし色を指定し、CSS では background-color を使用します。
  • CSS のみ。CSS には、marginpadding など、SVG にはないプロパティが多数あります。
  • SVG のみ。SVG には、xy など、CSS にはないプロパティがいくつかあります。

したがって、SVG 要素のスタイルを設定する場合は、SVG スタイルのプロパティを使用します。HTML 要素のスタイルを設定する場合は、CSS プロパティを使用します。

CSS カスケード

CSS カスケードは、CSS ルールの優先順位を決定します。この優先順位によって、特定のプロパティと要素に複数のルールが適用される場合に、どのルールを使用するかが決まります。次の簡略化されたカスケードは、Blockly で最も一般的に使用されるカスケードの部分を対象としており、「CSS が機能しないのはなぜですか?」という疑問を解決するのに役立ちます。

カスケードの簡素化

特定の要素とプロパティに適用されるルールを特定するには、次の手順に沿って、ルールが 1 つだけになるまで続けます。

  1. プロパティと要素に適用されるすべてのルールを収集します。
  2. !important アノテーションが付いたルールがある場合は、!important アノテーションが付いていないルールをすべて破棄します。
  3. 最も特異性の高いルールを選択します。

    • SVG プレゼンテーション属性の特異性は 0 です。
    • <style> タグまたは外部スタイルシートのルールの特異性は、通常どおり計算されます。
    • インライン スタイル(style 属性で設定されたスタイル)は、どのセレクタよりも特異性が高くなります。
  4. ドキュメントの最後に表示されるルールを選択します。

  5. ルールが適用されない場合は、プロパティの値を要素の親から継承します。

このアルゴリズムでは、カスケードの次の部分は考慮されません。

  • 優先度が最も高い transition プロパティ。Blockly では、これらのうちのいくつかを使用しています。
  • @media at-rule。Blockly はこれらのいずれかを使用します。
  • ブラウザまたはユーザーによって指定されたルール。
  • Blockly で使用されていない @scope@layer の @ 規則と animation プロパティ。

CSS ルール

CSS ルールは、アプリケーションのスタイル設定方法を指定します。Blockly には、独自のルールでオーバーライドできるデフォルトのルールセットが用意されています。

Blockly の CSS ルール

Blockly には、デフォルトの CSS ルールセットが用意されています。これらのルールが追加される方法と場所によって、優先度が決まります。

スタイルタグ

Blockly の CSS ルールの大部分は、2 つの <style> タグで指定されています。これらのタグはページの上部に配置されるため、同じ特異性を持つルールでも、ページの下部に配置されたルールよりも優先度が低くなります。

Blockly.css.register ルール

Blockly が挿入されると、<style> タグが <head> タグの子として追加されます。このタグのルールは次の場所から取得されます。

  • Blockly.css 名前空間。これらのルールを確認するには、core/css.ts を開き、let content を検索します。
  • 個々のコンポーネント。Blockly.css.register を呼び出して、コンポーネント固有の CSS ルールを追加します。css.register はこれらのルールを content 文字列の末尾に追加するため、以前に追加された同じ固有性のルールよりも優先度が高くなります。これらのルールを確認するには、Blockly.css.register への呼び出しをご覧ください。

これらのルールを使用しない場合は、css 構成オプションfalse に設定します。この場合、代替の CSS ルールセットを提供する必要があります。

レンダラールール

レンダラがインスタンス化されると、レンダラ固有の CSS ルールを含む <style> タグが <head> タグの子として追加されます。これらのルールは常に追加されます。css 構成オプションの影響を受けません。これらのルールを確認するには、レンダラで getCss_ メソッドを検索します。

インライン スタイル

インライン スタイルは style 属性で指定され、通常はコンポーネントの DOM が作成されるときに作成されます。部分的なリストについては、この GitHub クエリをご覧ください。

インライン スタイルは、発生した要素に直接適用され、セレクタよりも優先順位が高くなります。このため、通常は !important アノテーションを使用してオーバーライドする必要があります。

SVG プレゼンテーション属性

SVG プレゼンテーション属性は、SVG 要素の属性として使用される SVG スタイリング プロパティです。特異性は 0 で、!important アノテーションを含めることはできません。そのため、Blockly のすべてのルールの中で優先度が最も低くなります。Blockly は通常、createSvgElement の呼び出しでこれらを作成します。

独自の CSS ルールを追加する

Blockly と同じ方法で、独自の CSS ルールを追加できます。

  • Blockly を挿入する前に Blockly.css.register を呼び出します。ルールは Blockly の後に追加され、同じ特異性を持つ Blockly ルールよりも優先度が高くなります。
  • <head> タグの後続の子として、<style> タグまたは外部スタイルシートへのリンクを追加します。Blockly は <head> タグの最初の 2 つの子としてルールを追加するため、同じ特異性を持つ Blockly ルールよりも優先度が高くなります。
  • インライン スタイルを使用して、カスタム コンポーネントの要素にスタイルを追加します。これらのルールは、セレクタを含むルールよりも特異性が高くなります。
  • カスタム コンポーネントの SVG 要素でプレゼンテーション属性を使用します。これらのルールは、セレクタを含むルールよりも特異性が低くなります。

トラブルシューティング

CSS が機能しない場合は、次の原因が考えられます。

  • SVG 要素で CSS プロパティを使用しているか、HTML 要素で SVG スタイリング プロパティを使用している。SVG のスタイル設定プロパティと CSS プロパティをご覧ください。

  • ルールが別のルールよりも優先度が低い。通常は、特異性が低いことが原因です。この問題を解決する方法は次のとおりです。

    • 型(要素)セレクタの代わりにクラス セレクタを使用します。
    • 複数のセレクタを使用する。
    • 可能であれば、ターゲット要素にカスタムクラスを追加し、ルールでこのクラスを使用します。
    • 最後の手段として、ルールに !important アノテーションを追加します。競合するルールがインライン スタイル(style 属性)を使用して指定されている場合、この選択肢しかありません。
  • ルールが別のルールと同じ特異性を持つが、ページ内でより早く出現する。ルールの特異性を高めることができない場合は、ページの後ろに移動します。

オーバーライドできない CSS ルールは次の 2 種類です。

  • transition ルール内で設定されるプロパティ。
  • ブラウザで指定された !important ルール。