Closing Svg Tags, Explicit or Self Closing

Closing SVG tags, explicit or self closing?

Whatever validation you're using is working incorrectly.

The HTML standard says that SVG and MathML elements “must either have a start tag and an end tag, or a start tag that is marked as self-closing, in which case they must not have an end tag”. I.e. You can write a path as <path></path> or <path/> but you can't write it as <path>

Can SVG markup in HTML5 omit self-closing tags?

Below are some rules I found out in the W3 SVG and MathML elements in HTML documents documentation

  • SVG and MathML elements whose start tags have a single "/" character before the closing ">" character are said to be marked as
    self-closing.
  • SVG and MathML elements must either have a start tag and an end tag, or a start tag that is marked as self-closing, in which case they
    must not have an end tag.
  • SVG and MathML elements whose start tag is marked as self-closing, can’t have any contents.
  • The contents of an SVG or MathML element whose start tag is not marked as self-closing are any elements, character data, comments, and
    CDATA sections that it contains, with the restriction that any
    character data it contains must be normal character data.

I think the second point enforces svg elements to have a explicit closing tag or a self-closing tag.

Are (non-void) self-closing tags valid in HTML5?

  • (Theoretically) in HTML 4, <foo / (yes, with no > at all) means <foo> (which leads to <br /> meaning <br>> (i.e. <br>>) and <title/hello/ meaning <title>hello</title>). I use the term "theoretically" because this is an SGML rule that browsers did a very poor job of supporting. There was so little support (I only ever saw it work in emacs-w3m) that the spec advises authors to avoid the syntax.

  • In XHTML, <foo /> means <foo></foo>. This is an XML rule that applies to all XML documents. That said, XHTML is often served as text/html which (historically at least) gets processed by browsers using a different parser than documents served as application/xhtml+xml. The W3C provides compatibility guidelines to follow for XHTML as text/html. (Essentially: Only use self-closing tag syntax when the element is defined as EMPTY (and the end tag was forbidden in the HTML spec)).

  • In HTML5, the meaning of <foo /> depends on the type of element:

    • On HTML elements that are designated as void elements (essentially "An element that existed before HTML5 and which was forbidden to have any content"), end tags are simply forbidden. The slash at the end of the start tag is allowed, but has no meaning. It is just syntactic sugar for people (and syntax highlighters) that are addicted to XML.
    • On other HTML elements, the slash is an error, but error recovery will cause browsers to ignore it and treat the tag as a regular start tag. This will usually end up with a missing end tag causing subsequent elements to be children instead of siblings.
    • Foreign elements (imported from XML applications such as SVG) treat it as self-closing syntax.

Update HTML to have closing tags with JavaScript or jQuery

Feels like a work-around but got the SVG saving by removing .pipe(gulp.dest(paths.svg.out)); and instead making use of fs.

const gulp = require('gulp');
const cheerio = require('gulp-cheerio');
const fs = require('fs');
const rename = require('gulp-rename');

const rootPath = './src/assets';
const paths = {
svg: {
in: `${rootPath}/icons/raw/**/*.svg`,
out: `${rootPath}/icons/svg`,
}
};

const svg = () => {
let dirName;
let fileName;

return gulp
.src(paths.svg.in)
.pipe(rename((path) => {
// Ensure the file name is kebob-case
path.basename = path.basename
.replace(/[^A-Za-z0-9\ ]/g, '')
.replace(/([a-z])([A-Z])/g, '$1-$2')
.replace(/\s+/g, '-')
.toLowerCase();

dirName = path.dirname;
fileName = path.basename;
}))
.pipe(cheerio({
run: ($, file) => {
$('svg').attr('class', `svg-${fileName}`);

const path = `${paths.svg.out.svg}/${dirName}/${fileName}.svg`;
const updatedHtml = $.html().replace(/<\s*([^\s>]+)([^>]*)\/\s*>/g, '<$1$2></$1>');

fs.writeFile(path, updatedHtml);
}
}))
};

which, based on the above SVG, returns

<svg width="24" height="24" viewbox="0 0 24 24" class="svg-email">
<path fill="#AFAFB0" fill-rule="evenodd" d="M1,5 L23,5 C23.5522847,5 24,5.44771525 24,6 L24,18 C24,18.5522847 23.5522847,19 23,19 L1,19 C0.44771525,19 6.76353751e-17,18.5522847 0,18 L0,6 C-6.76353751e-17,5.44771525 0.44771525,5 1,5 Z M21.2034005,7.09747208 L12,13.8789251 L2.79659952,7.09747208 C2.57428949,6.93366469 2.26127947,6.98109045 2.09747208,7.20340048 C1.93366469,7.42571051 1.98109045,7.73872053 2.20340048,7.90252792 L11.7034005,14.9025279 C11.8797785,15.0324907 12.1202215,15.0324907 12.2965995,14.9025279 L21.7965995,7.90252792 C22.0189095,7.73872053 22.0663353,7.42571051 21.9025279,7.20340048 C21.7387205,6.98109045 21.4257105,6.93366469 21.2034005,7.09747208 Z"></path>
</svg>

Is a self-closing li tag valid?

No, it isn't. You can test this with a validator.

The / is an error so browsers will ignore it, treating it as a start tag.

The <p> elements are therefore children of the <li> elements (which they have to be since they aren't allowed to be children of <ul> elements).

The next <li> (or </ul>) implicitly ends the previous <li> because the end tag is optional for that element.



Related Topics



Leave a reply



Submit