Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Style element for "Skip to content" produces HTML validation error #31365

Closed
thompcha opened this issue Apr 30, 2021 · 7 comments
Closed

Style element for "Skip to content" produces HTML validation error #31365

thompcha opened this issue Apr 30, 2021 · 7 comments
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Type] Bug An existing feature does not function as intended

Comments

@thompcha
Copy link

thompcha commented Apr 30, 2021

Description

I recently updated to Gutenberg 10.5.2 and I noticed that my posts now contain a <style> element inside the page’s <body> with styles pertaining to the “Skip to content” link (an accessibility feature that appears when a page is loaded and the user presses tab). Thus when a post is submitted to W3.org’s HTML Validator, it reports the following error:

Error: Element style not allowed as child of element body in this context. (Suppressing further errors from this subtree.)

From line 355, column 3; to line 355, column 31

/div>↩↩↩	<style id=”skip-link-styles”>↩	.sk

Contexts in which element style may be used:
Where metadata content is expected.
In a noscript element that is a child of a head element.
Content model for element body:
Flow content.

Can this style element be moved to the head?

Step-by-step reproduction instructions

  1. Enable Gutenberg 10.5.2
  2. Load a post in your browser
  3. View source
  4. Search source for <style id="skip-link-styles">

Expected behaviour

Posts are valid HTML

Actual behaviour

Posts fail HTML validation

Screenshots or screen recording (optional)

image
image

Code snippet (optional)

<style id="skip-link-styles">
  .skip-link.screen-reader-text {
    border: 0;
    clip: rect(1px,1px,1px,1px);
    clip-path: inset(50%);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute !important;
    width: 1px;
    word-wrap: normal !important;
  }

  .skip-link.screen-reader-text:focus {
    background-color: #eee;
    clip: auto !important;
    clip-path: none;
    color: #444;
    display: block;
    font-size: 1em;
    height: auto;
    left: 5px;
    line-height: normal;
    padding: 15px 23px 14px;
    text-decoration: none;
    top: 5px;
    width: auto;
    z-index: 100000;
  }
</style>

WordPress information

  • WordPress version: 5.7.1
  • Gutenberg version: 10.5.2
  • Are all plugins except Gutenberg deactivated? No
  • Are you using a default theme (e.g. Twenty Twenty-One)? No

Device information

  • Device: Desktop
  • Operating system: Windows 10
  • Browser: Firefox 88.0 (64-bit)
@thompcha
Copy link
Author

I found the function that prints these styles in
wp-content/plugins/gutenberg/lib/full-site-editing/templates.php:

function gutenberg_the_skip_link() {

	// Early exit if not an FSE theme.
	if ( ! gutenberg_supports_block_templates() ) {
		return;
	}
	?>

	<?php
	/**
	 * Print the skip-link styles.
	 */
	?>
	<style id="skip-link-styles">
		.skip-link.screen-reader-text {
			border: 0;
			clip: rect(1px,1px,1px,1px);
			clip-path: inset(50%);
			height: 1px;
			margin: -1px;
			overflow: hidden;
			padding: 0;
			position: absolute !important;
			width: 1px;
			word-wrap: normal !important;
		}

		.skip-link.screen-reader-text:focus {
			background-color: #eee;
			clip: auto !important;
			clip-path: none;
			color: #444;
			display: block;
			font-size: 1em;
			height: auto;
			left: 5px;
			line-height: normal;
			padding: 15px 23px 14px;
			text-decoration: none;
			top: 5px;
			width: auto;
			z-index: 100000;
		}
	</style>
	<?php
	/**
	 * Print the skip-link script.
	 */
	?>
	<script>
	( function() {
		var skipLinkTarget = document.querySelector( 'main' ),
			parentEl,
			skipLinkTargetID,
			skipLink;

		// Early exit if a skip-link target can't be located.
		if ( ! skipLinkTarget ) {
			return;
		}

		// Get the site wrapper.
		// The skip-link will be injected in the beginning of it.
		parentEl = document.querySelector( '.wp-site-blocks' ) || document.body,

		// Get the skip-link target's ID, and generate one if it doesn't exist.
		skipLinkTargetID = skipLinkTarget.id;
		if ( ! skipLinkTargetID ) {
			skipLinkTargetID = 'wp--skip-link--target';
			skipLinkTarget.id = skipLinkTargetID;
		}

		// Create the skip link.
		skipLink = document.createElement( 'a' );
		skipLink.classList.add( 'skip-link', 'screen-reader-text' );
		skipLink.href = '#' + skipLinkTargetID;
		skipLink.innerHTML = '<?php esc_html_e( 'Skip to content', 'gutenberg' ); ?>';

		// Inject the skip link.
		parentEl.insertAdjacentElement( 'afterbegin', skipLink );
	}() );
	</script>
	<?php
}

For now, I'm going to turn them off with remove_action()

@annezazu annezazu added [Type] Bug An existing feature does not function as intended [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). labels May 6, 2021
@mcsf
Copy link
Contributor

mcsf commented May 21, 2021

(cc @aristath, per the introduction of automatic skip links in #30336)

@aristath
Copy link
Member

I recently updated to Gutenberg 10.5.2 and I noticed that my posts now contain a <style> element inside the page’s with styles pertaining to the “Skip to content” link (an accessibility feature that appears when a page is loaded and the user presses tab). Thus when a post is submitted to W3.org’s HTML Validator, it reports the following error:

Error: Element style not allowed as child of element body in this context.

<style> elements inside <body> have been allowed for a decade and they are used in multiple places. The group block uses inline style elements to add styles for layouts, block styles get inlined in the footer if they are small enough, the list goes on.

To put it simply, the validator is wrong and that is a false positive.
<style> elements were not allowed inside the <body> in HTML4, but those days are long gone.

Can this style element be moved to the head?

Everything is possible.... But fixing something that is not a problem just because a tool reports a false-positive would just be wrong 👍

@thompcha
Copy link
Author

The WHATWG spec currently used by the W3C validator specifies that a style element is contained within the head:
https://html.spec.whatwg.org/#the-style-element

Why didn't Gutenberg print style elements inside the body until the 10.5.2 patch?

@aristath
Copy link
Member

https://www.w3.org/TR/html52/document-metadata.html#the-style-element

styles can be inside the body in HTML5, It was not allowed in HTML4.

Why didn't Gutenberg print style elements inside the body until the 10.5.2 patch?

Because it didn't need to. Now it needs to, and it does. This instance is not the only one, there are multiple elements that do this.For example layouts CSS is printed inline using a <style> element: https://github.com/WordPress/gutenberg/blob/v10.6.0/lib/block-supports/layout.php#L106

@aristath
Copy link
Member

Closing due to lack of activity for almost 4 months.
If you feel this should be reopened please feel free to leave a comment and I'll reopen it so the discussion can continue.

@chthonic-ds
Copy link
Contributor

https://www.w3.org/TR/html52/document-metadata.html#the-style-element
styles can be inside the body in HTML5, It was not allowed in HTML4.

This seems to have changed again, the W3C link now redirects to the WHATWG spec one. The line:

In the body, where flow content is expected.

has been removed from the allowable contexts for <style>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

No branches or pull requests

5 participants