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 astext/html
which (historically at least) gets processed by browsers using a different parser than documents served asapplication/xhtml+xml
. The W3C provides compatibility guidelines to follow for XHTML astext/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
How to Create a Triangle in CSS3 Using Border-Radius
How to Center Multiple Divs Inside a Container in CSS
How to Add a Highlight Behind The Text via CSS So It Looks Like Instagram-One Below
Jenkins Content Security Policy
How to Communicate Between Frames
Avoiding Repeated Constants in CSS
How to Pre-Populate HTML Form Input Fields from Url Parameters
Removing Space at The Top Left and Right of Div
CSS: Image Link, Change on Hover
<Div> into a <Tr>: Is It Correct
Play Audio Local File with HTML
How to Set Thymeleaf Th:Field Value from Other Variable
Wrap a Text Within Only Two Lines Inside Div
CSS Box Shadow Around a Custom Shape
Understanding CSS2.1 Specification Regarding Height on Inline-Level Boxes
Browser Canvas Cors Support for Cross Domain Loaded Image Manipulation