CssToInlineStyles icon indicating copy to clipboard operation
CssToInlineStyles copied to clipboard

Void elements are no longer closed when using xhtml

Open Stadly opened this issue 8 years ago • 7 comments

With version 2.2.0, void elements are no longer closed when using xhtml doctype.

The following document

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <title>Title</title>
   </head>
   <body>
      <div>Message</div>
      <img src="foo.jpg" alt="bar" />
      <br />
      <hr />
   </body>
</html>

Will be converted into this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Title</title>
</head>
<body>
      <div>Message</div>
      <img src="foo.jpg" alt="bar">
      <br>
      <hr>
   </body>
</html>

Notice that the void elements (meta, img, br, hr) are not closed according to the xhtml standard. The / at the end of the elements are removed, even though the doctype is xhtml.

Stadly avatar Sep 21 '16 13:09 Stadly

Opened in 2016, no response? Where are people using this CSS inliner for, other than email? So this is a serious matter, because despite it's 2020 the safest, most used DOCTYPE is still XHTML 1.0 Transitional which requires slashes on self-closing (void) tags. Anyone know of an alternative CSS inliner that does respect these tags, allowing for email templates that actually validate?

zmip avatar May 03 '20 09:05 zmip

Did you try submitting a PR?

barryvdh avatar May 03 '20 16:05 barryvdh

Was this not fixed with https://github.com/tijsverkoyen/CssToInlineStyles/pull/154 ?

barryvdh avatar May 03 '20 16:05 barryvdh

@barryvdh I did not submit a PR because... I don't have a fix ;-) I cannot quite follow what happens at #154, because I hope the proposed hack was not implemented in the actual code. Will have to go through the code to see where this is happening. But no, it doesn't seem fixed in v2.2.2, but I'll investigate further...

zmip avatar May 04 '20 05:05 zmip

@zmip @barryvdh Have any updates? I faced with same problem.

kvush avatar Apr 06 '22 17:04 kvush

I think I went with Pelago/Emogrifier, but looking at the code, it seems I'm also post-processing br, meta and img tags to make them self-closing.

$emogrifier = new \Pelago\Emogrifier($html, $css);
$output = str_replace( ['<br>', 'src="/'], ['<br />', 'src="'.WEB_HOST.'/' ], $this->minify( $emogrifier->emogrify() ) );
$output = preg_replace( '/(<img.*?)>/', '\1 />', $output );
$output = preg_replace( '/(<meta.*?)>/', '\1 />', $output );

zmip avatar Apr 06 '22 20:04 zmip

@zmip thanks for response. Yeah look like post-processing is only way for now.

kvush avatar Apr 10 '22 07:04 kvush