Theme-Editor-Styles für Gutenberg erstellen

Mit WordPress 5 wird ein neuer Editor mit Codename »Gutenberg« kommen, der komplett anders ist als der aktuelle TinyMCE. Das bedeutet nicht nur eine Umstellung für die User, sondern auch für Theme-Developer, die die Styles im Editor so anpassen möchten, dass der Inhalt möglichst aussieht wie im Frontend. Hier zeige ich wie das für den neuen Editor funktioniert.

Das bisherige Vorgehen mit TinyMCE: ziemlich angenehm

Der Seiten- oder Beitrags-Inhalt des momentan noch genutzten TinyMCE-Editors lebt in einem iFrame, das heißt die Theme-spezifischen Styles können recht ähnlich zum Frontend geschrieben werden: es gibt einen normalen Website-Aufbau des DOM nur für den Inhalt, der sichtbare Inhalt ist innerhalb eines body-Elements und es kommen direkt die Elemente für Absätze, Überschriften, et cetera. Das sieht im DOM so aus:

DOM des bisherigen Inhalts dieses Beitrags hier im TinyMCE-Editor. (Screenshot: Firefox-Devtools)

Dadurch ist es kein sehr großer Aufriss, grundlegende Styles des Themes in TinyMCE zu integrieren.

Das Vorgehen für Gutenberg: weniger angenehm

Bei Gutenberg sieht das ein wenig anders aus. Der Editor sitzt zunächst nicht in einem iFrame, was an sich ja gut ist. Darüber hinaus sind alle Inhalte aber sogenannte Blöcke, die in div-Konstrukten eingebettet sind, die selbst noch Abstände haben, et cetera. Das DOM des Beitrags hier sieht wie folgt aus:

DOM des bisherigen Inhalts dieses Beitrags im Gutenberg-Editor. (Screenshot: Firefox-Devtools)

Ziemlich komplex im Vergleich zu dem Inhalts-Markup vom TinyMCE …

Soviel zu der Ausgangslage. Doch bevor wir uns jetzt mit dem Schreiben der CSS-Regeln auseinandersetzen können, fangen wir erst mal mit dem Laden des Stylesheets an. Hilfreich für mich war bei dem ganzen Thema der Artikel »How to add WordPress Theme Styles to Gutenberg« von Rich Tabor.

Ein Stylesheet für Gutenberg-Anpassungen einbinden

Das Einbinden selbst ist keine große Sache:

// Add backend styles for Gutenberg.
add_action( 'enqueue_block_editor_assets', 'photographus_add_gutenberg_assets' );

/**
 * Load Gutenberg stylesheet.
 */
function photographus_add_gutenberg_assets() {
	// Load the theme styles within Gutenberg.
	wp_enqueue_style( 'photographus-gutenberg', get_theme_file_uri( '/assets/css/gutenberg-editor-style.css' ), false );
}

Wir hängen eine Funktion an den enqueue_block_editor_assets-Action-Hook und fügen darin über wp_enqueue_style unser Stylesheet ein. Kommen wir jetzt zum Schreiben der Styles.

Styles für Gutenberg schreiben

Gutenberg bringt Styles mit, die wir überschreiben müssen. Als Wrapper-Element für den gesamten Inhalt kann .edit-post-visual-editor genutzt werden, die Blöcke selbst sind alle in .editor-block-list__block-Elementen.

Bei Anpassungen müssen wir aufpassen, dass wir keine Styles von der Inline-Toolbar oder den anderen Inline-Werkzeugen von Gutenberg verändern. Nützliche Klassen dafür sind:

  • .mce-content-body – ist vielen Text-Blockelementen zugewiesen, wie etwa Überschriften, Absätzen (aber nicht denen innerhalb eines blockquote-Elements), Listen, und so weiter.
  • .wp-block-quote – eine Klasse für erstellte Blockzitate.
  • .editor-block-list__block-edit – Wrapper innerhalb von .editor-block-list__block für das Inhaltselement.

Mein aktueller Stand bei den Editor-Styles für Gutenberg von meinem Photographus-Theme sieht damit in SASS so aus (Media-Queries habe ich rausgenommen, damit es etwas übersichtlicher ist):

@import "abstracts/variables";
@import "abstracts/functions";
@import "abstracts/mixins";

.edit-post-visual-editor .editor-block-list__block {
	color: $color-tundora;
	margin: 0 auto;
	max-width: $content-max-width;
}

.edit-post-visual-editor p,
.edit-post-visual-editor,
.blocks-rich-text__tinymce.mce-content-body {
	line-height: inherit;
	font-size: inherit;
}

.edit-post-visual-editor .editor-block-list__block-edit,
.edit-post-visual-editor {
	font-family: "PT Serif", Georgia, serif;
	font-size: 1em;
	line-height: $line-height;
}

.edit-post-visual-editor .editor-block-list__block {
	h1,
	h2,
	h3,
	h4,
	h5,
	h6 {
		&.mce-content-body {
			font-weight: 400;
		}

	}

	h1.mce-content-body {
		font-size: 1.802em;
		line-height: line-height(1.802, 1.5);
	}

	h2.mce-content-body {
		font-size: 1.602em;
		line-height: line-height(1.602, 1.5);
	}

	h3.mce-content-body {
		font-size: 1.424em;
		line-height: line-height(1.424, 1.25);
	}

	h4.mce-content-body {
		font-size: 1.266em;
		line-height: line-height(1.266, 1.25);
	}

	h5.mce-content-body {
		font-size: 1.125em;
		line-height: line-height(1.125, 1);
	}

	h6.mce-content-body {
		font-size: 1em;
		line-height: line-height(1, 1);
	}

	figure {
		line-height: 0;
		margin: add-unit($space-half, 'em') 0 0;

		figcaption,
		img {
			line-height: $line-height;
		}
	}

	figcaption {
		clear: both;
		color: inherit;
		font-size: $font-size-small;
		padding-top: add-unit($space-quarter, 'em');
		text-align: left;
	}

	blockquote.wp-block-quote {
		border-left: 2px solid;
		padding-left: add-unit($space-half, 'em');
	}

	blockquote.wp-block-quote cite {
		display: block;
		font-style: italic;
		margin: add-unit($space-quarter, 'em') 0 0;
	}

	table {
		border-spacing: 0;
	}

	td,
	th {
		border: none;
		border-bottom: 1px solid;
		padding: add-unit($space-quarter, 'em');
	}

	th {
		border-bottom: 2px solid;
		text-align: left;
	}

	table tr:last-of-type td {
		border-bottom: none;
	}

	dt {
		margin: add-unit($space-quarter, 'em') 0 0;
	}

	dd {
		margin: 0 0 0 add-unit($space, 'em');
	}

	ul,
	ol {
		padding-left: 1rem;
		margin-left: 0;
	}

	ul > li {
		list-style-type: none;
		position: relative;
	}

	ul > li::before {
		content: "·";
		left: -#{add-unit($space-half, 'em')};
		top: 0;
		position: absolute;
	}

	li + li {
		margin: add-unit($space-quarter, 'em') 0 0;
	}

	ul ol,
	ol ul,
	ul ul,
	ol ol {
		margin: add-unit($space-quarter, 'em') 0 0;
	}
}

.edit-post-visual-editor .mce-content-body {
	a {
		box-shadow: inset 0 -1px 0 currentColor;
		box-shadow: inset 0 -1px 0 currentColor, 4px 0 0 transparent, -4px 0 0 transparent;
		box-decoration-break: clone;
		color: inherit;
		padding-bottom: .05em;
		padding-top: .05em;
		text-decoration: none;
		-webkit-text-decoration-skip: objects;
		transition: box-shadow .2s ease 0s, background .2s ease 0s;
	}

	a:active,
	a:hover {
		box-shadow: inset 0 -1px 0 transparent;
		outline-width: 0;
	}

	a:focus {
		background: $color-tundora;
		box-shadow: inset 0 -1px 0 $color-tundora, 4px 0 0 $color-tundora, -4px 0 0 $color-tundora;
		color: $color-white;
		outline-width: 0;
	}
}

Zunächst setze ich ein paar Einstellungen der Gutenberg-Styles zurück und definiere meine neuen grundlegenden Designvorgaben wie Schrift und Zeilenhöhe. Dann gehe ich die einzelnen Block-Elemente durch und weise ihnen meine Styles zu. Am Ende folgen – bisher nur für Links – Styles für Inline-Elemente, die innerhalb von .mce-content-body liegen.

Ein bisher für mich ungelöstes Problem sind die Abstände von Elementen zueinander, die sich nicht wirklich gut in Gutenberg abbilden lassen. Wenn wir beispielsweise den Überschriften Abstände nach oben geben möchten, dann ist die Inline-Toolbar entsprechend weit vom Text der Überschrift entfernt.

Das hier ist ein Screenshot aus Gutenberg mit dem Ergebnis meiner bisherigen Bemühungen:

Die Editor-Styles für Gutenberg in Aktion. (Screenshot: eigene Installation)

Damit bin ich erst mal ganz zufrieden.

Wie ihr seht, ist das Schreiben von CSS für Gutenberg ein bisschen Ausprobieren und nicht ganz schnell gemacht. Was ihr auf keinen Fall tun solltet: einfach die Styles für TinyMCE kopieren und davon ausgehen, dass es schon passen wird. Eventuell zerschießt euch das den gesamten Editor.

Das könnte auch interessant sein

Schreib einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.