Hacker News new | past | comments | ask | show | jobs | submit login
SVG: The Good, the Bad and the Ugly (eisfunke.com)
220 points by davebloggt on Feb 12, 2021 | hide | past | favorite | 219 comments

>Furthermore the XML-based syntax is pretty ugly and needlessly verbose. It’s tiring to write by hand and just as tiring to parse or generate automatically.

What's even worse is that because XML is a garbage fire of a format, SVG actually builds its own micro-DSL to work around limitations.

So for instance you have something like:

    <circle cx="10" cy="10" r="2" fill="red"/>
Ok, fair enough. Readable, self-describing.

But then you have:

     <path d="M 10 10 H 90 V 90 H 10 L 10 10"/>
Oh. You can almost hear the designer saying "well fuck it, we'll just jam it all into a string.

The fact that SGML-based formats managed to become as popular as they are is really proof that there's something fundamentally rotten in software engineering.

I do quite like SVG though. I mean, if the alternative is drawing with CSS, it's pretty amazing. I don't really agree that it's hard to generate programmatically either, you just have to decide what subset of the format you need, look at what inkscape generates and go from there. If you need to generate basic shapes it's fairly straightforward.

Can't wait for the improved JSON version:

   {"path": {"d": ["M", 10, 10, "H", 90, "V", 90, "H", 10, "L", 10, 10]}}

Since this is HN I will point out that s-expressions are vastly superior:

    (path (d (M 10 10) (H 90) (V 90) (H 10) (L 10 10)))

You probably mean

  (path d M 10 10 H 90 V 90 H 10 L 10 10)
Shore up some nesting for the commands with pattern matching, returning a path struct:

  This is the TXR Lisp interactive listener of TXR 251.
  Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet.
  Garbage collection is on Tuesdays: bring unwanted pointers to curb by 7:30.
  1> (defstruct path () name args)
  #<struct-type path>
  2> (defun parse-path-args (args)
       (match-case args
         ((M @x @y . @rest) ^((M ,x ,y) ,*(parse-path-args rest)))
         ((L @x @y . @rest) ^((L ,x ,y) ,*(parse-path-args rest)))
         ((H @x . @rest) ^((H ,x) ,*(parse-path-args rest)))
         ((V @x . @rest) ^((V ,x) ,*(parse-path-args rest)))
         (@else (error "bad path arguments: ~s" else))))
  3> (defun-match parse-path
       (((path @(symbolp @name) . @args))
        (new path name name args (parse-path-args args)))
       ((@else) (error "bad path syntax: ~s" else)))
  4> (parse-path '(path d M 10 10 H 90 V 90 H 10 L 10 10))
  #S(path name d args ((M 10 10) (H 90) (V 90) (H 10) (L 10 10)))
Error cases:

  5> (parse-path '(path d M 10 10 H 90 V 90 X 10 L 10 10))
  ** bad path arguments: (X 10 L 10 10)
  ** during evaluation of form (error "bad path arguments: ~s"
  ** ... an expansion of (progn (error "bad path arguments: ~s"
  ** which is located at expr-2:2
  ** run with --backtrace to enable backtraces
  6> (parse-path '(paath d M 10 10 H 90 V 90 X 10 L 10 10))
  ** bad path syntax: paath d M 10 10 H 90 V 90 X 10 L 10 10
  ** during evaluation of form (error `bad path syntax: @else`)
  ** ... an expansion of (progn (error `bad path syntax: @else`))
  ** which is located at expr-3:1
  ** run with --backtrace to enable backtraces

I think that’s too flat. There’s no easy place to put the width and suchlike. I think you’d want something like:

  (path (M 10 10 H 90 V 90 H 10 L 10 10) :color red)
Though probably I would prefer something more nested if possible, so you have a list of instructions rather than needing to parse them out of a flattened list. And I would likely use an alist rather than a plist for attributes like colour or stroke width.

Even superior:

    path 10 10 M 90 H 90 V 10 H 10 10 L #000 stroke

I know you're joking but I still don't understand why (+ x y) is a good idea: clearly the first argument has a different meaning than the other, IMHO +(x y) show better the difference between the operation a d the arguments..

That significantly complicates the grammar, as now nested function calls require context from their parent to form an AST node. S-exps are the literal representation of the AST which allows for easily modifying and inspecting code, for example through macros. It's not so much "the first element is significant", it's more like "this is the convention of what a function looks like so you can pass it around and modify it as a single list".

I'm only half joking. The different notations all have pros and cons, but the benefit of s-expressions are their simplicity. A list can be either an expression (+ x y) but can also be a list of things like (red blue green) and an empty list can be written as (). It is basically the simplest possible structured notation.

+(x y) would be fine for expressions but weird for lists of things.

           M: 10, 10
           H: 90
           V: 90
           H: 10
           L: 10, 10
Just beautiful.

Nope, it should be an array. You use a hash so order isn't preserved and duplicate keys are removed. (Assuming that's Yaml)

Well clearly it'd be part of the specification to say that it's ordered and non-unique, it's obviously your fault if you expected standard yaml!

Thanks for pointing out what I expected, and making it even more delightful.

How is XML a garbage fire? In comparison to what? Also, representing paths succinctly as text is inherently complicated. You're trying to represent a very 2D thing in a linear 1D syntax. It's not a limitation of XML, it's a limitation of text being 1D.

XML/SGML are a very effective way of representing tree data (again, non-1D data) in 1D strings. And they're wonderfully extensible, while still keeping a well defined schema. Is there an alternative language that is better? How is it better?

> How is XML a garbage fire?

If you decided to go fully XML on "<path d="M 10 10 H 90 V 90 H 10 L 10 10"/>" it would probably look like this:

Some would say the fact the designers of XML went for "M 10 10 H 90 V 90 H 10 L 10 10" instead shows they thought XML is too verbose.

simias likely agrees that XML is too verbose - and wonders why they used XML at all

Because it was popular, especially in web-development-adjacent circles back then. And there weren’t many open-standard extensible general-purpose structured data formats. (There are a few more now, but still not that many.) JSON technically did exist (as a subset of JavaScript), but it wasn’t until Crockford named it that it became widely known.

And it’s not like XML has no good ideas in it either. You may disagree about the execution, but the idea of seamlessly mixing structured data defined by independent standards in a single document is pretty damn powerful.

Also, your example is rather strawman-ish: there is no point in using separate elements for individual coordinates, and anyone designing the format would know this. A more realistic example would have <path> contain an ordered sequence of <move-to x="..." y="..." /> and <line-to x="..." y="..." /> elements. (In fact, SVG already contains <line /> and <circle /> which use roughly this structure.)

> Also, your example is rather strawman-ish: there is no point in using separate elements for individual coordinates, and anyone designing the format would know this.

You say that - but here's some real world XML from the widely used 'GPX' file format[1]

      <trkpt lat="47.644548" lon="-122.326897">
The truth is I could have put the X coordinate as an attribute and the Y coordinate as a child element and it would still have been a fair representation of real-world XML documents.

And GPX is one of the better XML formats! You want to see nightmare XML? Go look at SAML.

[1] https://en.wikipedia.org/wiki/GPS_Exchange_Format#Sample_GPX...

These are still examples of crappy DSLs that use XML syntax, not specific problems with XML itself. Designing good DSLs is a hard problem, but is it any less hard in JSON or YAML? If so, it would be helpful for me if people could provide specific examples of why XML itself leads to poor DSLs. As it stands, I'm left wondering if there are so many bad XML DSLs simply because XML is (has been) a popular format.

Pertinent to this specific discussion is that XML distinguishes syntactically between "elements" and "attributes", but it's often not clear what the purpose of the distinction is (search for "elements vs attributes").

JSON and YAML do not make such a distinction.

True, but the lack of a clear distinction also seems like a weakness in the specific DSLs rather than a weakness in the format. HTML has (with some exceptions) a very clear distinction between them: attributes are for metadata, elements are for visible page content. Android's XML draws a similar distinction, with attributes used to describe properties of a view and elements used to describe child views.

(I do concur with others who have noted here that the "elements" versus "attributes" distinction makes XML a poor choice for serialization, but XML as a serialization format isn't really the issue here.)

XML was based on SGML, which was originally intended for marking up text documents, so TEXT was given a special place in the Pantheon of Nodes, even above Attributes.

So using XML to represent data structures instead of marking up text can be pretty awkward, inefficient, and nuanced.

XML Attributes are second class citizens compared to TEXT nodes which can contain CDATA, because attributes undergo "Attribute-Value Normalization" -- having their line breaks, entity references, and white space normalized. Newlines are normalized, leading and trailing white space removed, repeating white space replaced with a single space.

SVG path attributes (as well as simple values like numbers, booleans, enums, etc) are impervious to Attribute Value Normalization corruption, because they don't depend on white space being perfectly preserved (by design, of course), so they are fine to put in attributes.

But if you really care about preserving the exact value of a string, like a password or arbitrary string, you should use <!CDATA[[ ]]> in a text node, not an attribute!

I Wanna Be <![CDATA[ https://donhopkins.medium.com/twenty-twenty-twenty-four-esca... ]]>


3.3.3 Attribute-Value Normalization

Before the value of an attribute is passed to the application or checked for validity, the XML processor must normalize the attribute value by applying the algorithm below, or by using some other method such that the value passed to the application is the same as that produced by the algorithm.

All line breaks must have been normalized on input to #xA as described in 2.11 End-of-Line Handling, so the rest of this algorithm operates on text normalized in this way.

Begin with a normalized value consisting of the empty string.

For each character, entity reference, or character reference in the unnormalized attribute value, beginning with the first and continuing to the last, do the following:

For a character reference, append the referenced character to the normalized value.

For an entity reference, recursively apply step 3 of this algorithm to the replacement text of the entity.

For a white space character (#x20, #xD, #xA, #x9), append a space character (#x20) to the normalized value.

For another character, append the character to the normalized value.

If the attribute type is not CDATA, then the XML processor must further process the normalized attribute value by discarding any leading and trailing space (#x20) characters, and by replacing sequences of space (#x20) characters by a single space (#x20) character.

Note that if the unnormalized attribute value contains a character reference to a white space character other than space (#x20), the normalized value contains the referenced character itself (#xD, #xA or #x9). This contrasts with the case where the unnormalized value contains a white space character (not a reference), which is replaced with a space character (#x20) in the normalized value and also contrasts with the case where the unnormalized value contains an entity reference whose replacement text contains a white space character; being recursively processed, the white space character is replaced with a space character (#x20) in the normalized value.

All attributes for which no declaration has been read should be treated by a non-validating processor as if declared CDATA.

It is an error if an attribute value contains a reference to an entity for which no declaration has been read.

Some of the most incredibly awfully bad XML DSLs are official standards, themselves. COUGH XMLSchema COUGH

You should read some of James Clark's criticisms of the official XML Schema (XSD) standard, which motivated him to develop TREX (Tree Regular Expressions for Xml), which he combined with Makoto Murata's RELAX (REgular LAnguage description for XML) to create Relax/NG.



>Some people, including Murata and James Clark, had critical attitudes toward XML Schema. XML Schema is a modern XML schema language designed by W3C XML Schema Working Group. W3C intended XML Schema to supersede traditional DTD (Document Type Definition). XML Schema supports so many features that its specification is large and complex. Murata, James Clark and those who criticised XML Schema, pointed out the following:

>It is difficult to implement all features of XML Schema.

>It is difficult for engineers to read and write XML Schema definitions.

>It does not permit nondeterministic content models.

>Murata and collaborators designed another modern schema language, RELAX (Regular Language description for XML), more simple and mathematically consistent. They published RELAX specification in 2000. RELAX was approved as JIS and ISO/IEC standards. At roughly the same time, James Clark also designed another schema language, TREX (Tree Regular Expressions for XML).

>Murata and James Clark designed a new schema language RELAX NG based on TREX and RELAX Core. RELAX NG syntax is the expansion of TREX. RELAX NG was approved by OASIS in December 2001. RELAX NG was also approved as Part 2 of ISO/IEC 19757: Document Schema Definition Languages (DSDL).




Schema Wars: XML Schema vs. RELAX NG (1/2) - exploring XML




>James Clark used Haskell to design and implement an algorithm for validating Relax NG XML schemas (he co-designed Relax NG, and designed its predecessor TREX), to work the ideas out before re-implementing it in (many many more lines of tedious brittle) Java (JING). Haskel works wonderfully as a design and standard definition language, that way.


>James Clark's compact syntax for Relax/NG XML schema validation language is quite tastefully designed, an equivalent but more convenient alternative syntax than XML, for writing tree regular expressions matching XML documents. It's way more beautiful and coherent than the official "XML Schema" standard.


>There's a wonderful DDJ interview with James Clark called "A Triumph of Simplicity: James Clark on Markup Languages and XML" where he explains how a standard has failed if everyone just uses the reference implementation, because the point of a standard is to be crisp and simple enough that many different implementations can interoperate perfectly.

>A Triumph of Simplicity: James Clark on Markup Languages and XML:


"The standard has to be sufficiently simple that it makes sense to have multiple implementations." -James Clark

Fair enough. But SVG was defined by the W3C, the very same organisation that standardised XML itself. If anyone, they would know what they’re doing.

> And there weren’t many open-standard extensible general-purpose structured data formats.

The thing is, just having an XML parser isn't enough to parse SVG. You also have to parse a DSL. So I think the argument is "why not just use only a DSL, that does a good job of describing the data model?"

The boundary where the XML ends and the DSL begins is at least a little arbitrary, but it does have important ramifications. By using XML, you can use the XPath query language to index down to a `path` (the end of the XML), but not within a `path` (the beginning of the DSL). That means, at least conceptually, you can attach colors, and events, and such to a path. And the fact that you cannot do it within a path (not without introducing a query language for the DSL) is inelegant, but also might not have much bearing in 99% of applications.

Because then you’d have to define its syntax and extension points. XML and namespaces solve that problem for you, so the only thing left for you to design is the actual structure of your data.

Except that's not what happened. They also had to define new syntax for the DSLs they embed in strings.

True. But it would have been much harder if they had to define a syntax for the entire document.

I imagine they thought that the path DSL is simple enough to parse (and I seem to vaguely recall PostScript has something similar), while the overhead of representing path nodes as XML elements would be too high.

I'm not arguing against using an existing format, BTW, just seems like a weird mixture here.

I can't help but think s-expressions would have been a better choice.

I think its relationship with HTML, JavaScript and CSS would be a lot worse if it didn't reuse XML to the extent that it did.

Alternatively, with SGML:

    <point x=10 y=10/>
    <point x=90 y=10/>
    <point x=90 y=90/>
    <point x=10 y=90/>
    <point x=10 y=10/>

Same as other commenters, you removed the information about that this coordinate means. Does <point x=10 y=10/> means I will trace a line to 10,10, move to 10,10, trace a bezier curve, ...

This could be a better format, but still a lot heaver in term of bandwidth.

    <move x=10 y=10/>
    <line x=90 y=10/>
    <curve x=90 y=90/>

This is pretty clearly a more accurate "xml-ification" of a bunch of points. X/Y are un-ordered attributes of a point, not part of an ordered list of things contained within a point.

Just because XML isn't perfect for everything, doesn't mean it's a garbage fire. XML is great for trees -- specifically document trees. So XML is used to manage the document-like properties of an SVG (elements/position, nested groups, etc). XML is not great for representing potentially gargantuan lists of drawing instructions. So the SVG folks smartly decided to use a more compact DSL to handle that use case. In the same way CSS was created, or JS. Could you instead have used XML for styling? Of course (XAML does this if you want an example). You could even force JS to be written in XML. The fact that in those forced applications XML is very verbose, doesn't mean XML is verbose in general.

Also just in general, SVG's d-path syntax is a fantastic example of smart meeting of and understanding of requirements and users. If they used something more verbose (like `move-to` instead of `M` or whatever), then the file becomes WAY less human readable (too much noise at the XML-level), but more novice friendly. But... will novices need to edit d-paths manually? Of course not! Will they need to edit the XML structure manually? Way more likely. So you can use a more compact expert syntax for paths, because the people who will want to use it will likely be experts. It also means that SVG files are smaller, require less memory to parse, and more human-readable. Seriously great choice on their part.

This would work:

      <m x=“10” y=“10” />
      <h dx=“90” />
      <v dy=“90” />
      <h dx=“10” />
      <l x=“10” y=“10” />
Perfectly sane.

Someone complained about JSON above, but I think it does a nicer job here:

   "path": [
    [10, 10],
    [90, 10],
    [90, 90],
    [10, 90],
    [10, 10]
No need for the x and y, really. And it's still quite legible on one line.

  {"path": [[10, 10], [90, 10], [90, 90], [10, 90], [10, 10]]}

You clearly didn't understand how the path element in SVG works. The M, L and other characters contains valuable information. M stand for move, L for trace a line, but you can also have instructions for bezier curve or Z for closing a path. Your json format by removing this information is useless.

I believe something like this would work (excuse the comments normally not allowed in JSON):

      paths: [
          points: [
            [10, 10],  // 0
            [90, 10],  // 1
            [90, 90],  // 2
            [10, 90]   // 3
          lines: [
            [0, 1, 2, 3, 0]  // connect point 0 to 1 to 2 to (...)
          curves: {
            0: [5, 15, 15, 5]  // bezier control points for point 0 (x1, y1, x2, y2)
The downside (other than the bloat) would be when writing the code by hand, you'd have to keep track of the indices in the `points` array.

i'd much rather have

    [ { line: [10, 10] }, { cubic: [ 5, 15, 15, 5 ] }, ... ] 
or even

    [ ["line", 10, 10], ["cubic", ...], ... ] 
- anything as long as there's a way to stream the data (which is not possible with your format as you need to receive the whole object before being able to do anything).

this makes me realize that xml maps relatively well to JSON array whose elements are object with 1 fields (or 2 fields) whose value is again a similar array.

> You clearly didn't understand how the path element in SVG works.

No, I didn't. I was working from the parent's code. I don't appreciate your attitude though. There's much nicer ways to correct people online.

While there's truth in this, it's irrelevant to their point which was:

> No need for the x and y, really

SGML (and descendants) is a markup language. It's in the name really.

>XML/SGML are a very effective way of representing tree data

Completely disagree:

- It's not effective density-wise because the format is very verbose

- It's not effective parsing-wise because the format is very complicated.

- It's not effective human-wise because you have meaningless distinctions between attributes and child nodes which makes sense for a markup language but not for a serialization format. It's also very verbose which makes it annoying to read and write.

Imagine that you have an object like:

   struct Object {
        name: "foo",
Should you serialize like:

   <object name="foo" />

   <object> <name>foo</name> </object>
And to be clear, that's a rhetorical question. My point is that this distinction doesn't make a lot of sense for a serialization format and forces the developer to make pointless decisions. Here you might say that an attribute makes more sense, but then if later you realize that you can have several names you're screwed, because you either have to come up with your own custom format to store those in an attribute (coma-separated? But what if there's a coma in the name?) or split them off into child nodes.

It makes perfect sense for a markup language though, because there's (usually) a clear distinction between the textual and metatextual content. The stuff between the tags is meant to be displayed to the user, whereas the attributes are meant to be interpreted by the machine.

Actually it's not a pointless distinction. If you care about the integrity of your string, you'd better use text nodes with CDATA, not attributes, because of the dreaded obscure XML feature called "Attribute Value Normalization".

XML just tempts you to use attributes to represent strings, then kicks you in the ass when you least expect it by corrupting your data unexpectedly and unfairly but with full legal authority of the xml standard itself.

I wrote about it in this other comment:


Agreed; XML is best for document trees more than just generic tree data in general. I think the meaning between attributes/child nodes is pretty clear for like ~85% of use cases. Namely: attributes are for properties of the current node, child nodes are separate elements which are contained in the current node. I agree it can be complicated to parse, and don't agree it's exceptionally verbose. It is more verbose than say, a CSV or something, or than JSON (only because of the ending tags), but I wouldn't call it exceptionally verbose. That verbosity often makes things easier to read to than e.g. JSON, where you need a `type: "paragraph"` or equivalent on every element to simulate how HTML works. XML is better for document trees, JSON is better for generic tree data.

(Note: XAML does have a nice duality between attributes and nodes (sort of) which is kind of interesting. It's been a while since I've used it though, so can't quite recall the details).

The presentations/articles on how to unambiguously decode the XML Signature Spec are almost as long as the spec itself. When it was my turn to parse it, I found a couple of cases they missed.

In XML ID fields are supposed to be unique to the document. Nobody enforces this. Instead getByID returns the first ID. Which means if you ask a DOM element and the root element for an element by ID, you can get two different answers.

Composing multiple schemas into the same file is a wordy, confusing mess, DTDs are straight up broken, and the only time I ever saw someone generate a Grade A XML Schema was by feeding examples into XMLSpy instead of writing their own.

XML asks a question we already knew the answer to: What if we made everyone into a programming language designer? And the answer was "anarchy" because we know that many people cannot design a syntactically consistent language, and hardly anybody can design a semantically consistent one.

James Strachan, as I recall, retired from Groovy before they ever figured out an unambiguous grammar for it. There comes a point where you realize you've made a mess that you are not qualified to clean up (Kernighan's Law). You can either do the very hard work of maturing into the responsibility, or bow out. Strachan is no different than a dozen people I've worked with and countless people I've heard about second or third hand, who I'm more than a little glad moved on.

The guilt is not theirs alone. Part must fall to this shared delusion that you can do anything with software if you only put your mind to it. We have mathematical proofs that tell us that's not true, and yet we still believe in the power of belief. Unfortunately if we didn't believe it a little, then we'd probably never write anything at all, so I'm not sure there's so much a cure as a condition that has to be managed. A little bit can go a long way, and most of us take it too far, sooner or later.

Tagged interchange formats like https://en.wikipedia.org/wiki/Interchange_File_Format were IMO much better to work with than XML from a programming point of view.

If I want something free-form text based, I've been more happy with e.g. YAML based formats.

Exactly, in the canvas API this is written like:

    <path d="M 10 10 H 90 V 90 H 10 L 10 10"/>

    ctx.moveTo(10, 10);
    ctx.lineTo(90, 10);
    ctx.lineTo(90, 90);
    ctx.lineTo(10, 90);
    ctx.lineTo(10, 10);
Not much better.

I disagree, the JS code is immediately understandable without having to lookup anything. You could do it in pure XML but the result would probably be much more verbose.

To be equivalent the SVG `<path>` element would probably need to take an idref to something like a `<draw>` element. This is how I would guess the equivalent would be:

    <draw id="my-path">
      <move-to x="10" y="10" />
      <line-to x="90" y="10" />
      <line-to x="90" y="90" />
      <line-to x="10" y="90" />
      <line-to x="10" y="10" />

    <path draw="my-path" />
EDIT: Come to think of it, the above is probably a lot easier to animate using CSS or SMIL. Animating the `d` attribute on `<path>`s is theoretically possible but in practice weird at best or browser inconsistent or simply impossible at worst.

EDIT 2: In D3 it is not uncommon to draw area graphs with a thick border on top. The only way to do this is with two `<path>`s with almost identical `d` attributes. Allowing drawings to be strung together with multiple idrefs could solve that:

    <draw id=line-path><!-- ... --></draw>
    <draw id="area-box-close">
      <line-to x="100" y="100" />
      <line-to x="0" y="100" />
      <end />
    <path draw="line-path" class="line" />
    <path draw="line-path area-box-close" class="area" />
Maybe this isn’t such a bad idea after all.

Yes! That's a lot better IMO, but I suspect that the reason for the custom string with single letter "operators" is because the size overhead was unbearable for SVGs with complex paths (which, being a vector format, should be considered the baseline). The overhead is already pretty massive with the current spec, gzipped you can usually divide the file size by an order of magnitude.

I SVG is pretty inelegant, but it's pragmatical.

I would argue that using something like this would result in a less readable file overall. 85% of people editing SVGs by hand have 0 interest in modifying paths by hand. They likely want to move elements around, change groups, etc. If the d-path was written less compactly, these path definitions, which, again most people don't even care about, would end up taking up the vast majority of the space in the file. It would be impossible to get an idea of the nesting, and super annoying to move things around since they would be huge.

Also: Reminder SVGs goal is presentation, so paths even for a simple monochrome icon have _hundreds_ of control points. Something more intricate or a larger graphic? Thousands easily. All the examples here are toy examples, that don't scale to what SVG is actually used for.

> Oh. You can almost hear the designer saying "well fuck it, we'll just jam it all into a string.

I'll throw in my 2 cents here because the responses aren't addressing why the path descriptors are stylised in this way. Whether SVG's underlying document format was XML, JSON, SGML, CSS or whatever is irrelevant. However else you did it, any alternative would be more verbose because the 'd' tag already offers the most compact way of describing vector paths in text form.

And that's the point - it's small. Even in this compact form, it's not unusual for path strings to reach kilobytes in length when floating point numbers are catered for. Thus we need the path descriptions to be as small as possible for optimal parsing of the file and keeping the file size down.

As a side-note I disagree with the author's conjecture that SVG doesn't succeed as a machine-focused language or a human-focused language. I think it serves both sides of the coin quite well in practice (certainly more-so than HTML) and a pared back version already exists in the form of SVG Tiny.

I wonder though why does that matter for a web format that can be served with GZIP encoding? Wouldn't GZIP eat the duplicative <move-to /> tags for breakfast? It would be so much easier to write, read, manipulate and animate.

Let's imagine for a moment that path instructions could be mapped out with more verbose instructions. Would this really get enough practical use to be worthy of standardisation?

For the most part, SVG path outlines are almost always defined in software like Illustrator and Inkscape. Bezier curves are beyond the average person's ability to create or modify without visual aids. Simple path constructs aren't all that common in practice and the examples I see posted here aren't representative of real-world use.

SVG does provide transform capabilities to move, rotate and scale paths easily, and those features can be applied within a text editor. For anything else there are plenty of visual tools to aid path modification. Personally I've modified many an SVG file manually, but when it comes to the paths I can't say that seeing them laid bare would be of a help to my workflow.

I'll reference you to a comment elsewhere in the tree, and its parents[0], which came up with this s-expression:

    (path (M 10 10 H 90 V 90 H 10 L 10 10) :color red)
It's legitimately hard to beat sexprs for the combination of compactness, generality, and ease of use. If I were to start from first principles in making a vector graphics format, I'd probably make it a schema over EDN. I bet the extra complexity of having explicit maps and vectors would pay off.

[0]: https://news.ycombinator.com/item?id=26118727

I think that's reasonable, but is syntactic sugar really going to help you modify a path when the vector points will look more like this in reality:

  (path (M 368.296, 1.514) (c -0.908, 0 -1.818, 0.011 -2.716, 0.021) 
  (c 0.053, 0, 0.106, 0, 0.159,0) (c 147.196, 0.836, 265.306, 94.672, 267.029, 183.784)
  (c 0, 0.581, 0.065, 35.087, 0.065, 35.087) (h 49.415)
  (v -33.471) (h 37.094) (v -31.376)
  (C 719.342, 77.099, 575.826, 1.514, 368.296, 1.514)

I've used SVG pretty heavily for years, in particular for the last couple of months as I've been writing libraries/tools that render SVG output (parsing for the cli tool side, lots of hand-writing & testing, cleaning, rendering).

Yes an s-expression is imo normally the best representation (more specifically, an x-expression (see Racket) would be ideal). However, practically, it's not actually that useful. It is very useful as an intermediary step.

For example for a tool where the SVG is parsed to an x-expression and cleaned then compiled back. This is one of the [aborted] things I was working on, as the three best existing tools [in JS, Python and Rust] for this all have issues of one kind or another. Or you have a tool that allows you to write x-expressions then compile. But always with this, if that's the case, can't really directly jnterop with the host language/platform -- as you say, would have to be from first principles. And further to that, it would need HTML from first principles because one of the huge, huge benefits is that SVG drops directly into HTML with virtually the same semantics, same styling, same JS interactivity hooks. And the issue is compounded by SVG not just being XML, that it is also a DSL (NB solution is normally to restrict to a subset of features), so the clean structure breaks down pretty often. Imo SVG has to be the way it is, that the tradeoffs of the bastardised XML it uses have to have been made for it to be actually useful. Those tradeoffs also make it difficult to use, and often very difficult to parse easily. But without changing how HTML works, how web browser rendering works, I don't see how there are any alternatives that are substantially better.

I think the other desiderata mentioned in the original post are more important than choice of serialization format. SVG already exists, and we're kind of stuck with it. There are other applications where having a better-designed vector graphics format might pay off, and tying it to the browser all over again wouldn't be a win.

At that point, using an s-expression format (x-expression, EDN, I'm agnostic) should be the first choice. One of the first things that would have to be implemented, of course, is a translator to SVG.

My interest in vector graphics is such that, on the few occasions I need them, I just shrug and deal with the format we have.

> The fact that SGML-based formats managed to become as popular as they are is really proof that there's something fundamentally rotten in software engineering.

HTML is a pretty good syntax though. SGML-like syntax is just less appropriate for formats which are not text-centered, since the element/attribute distinction becomes superfluous noise in the syntax.

I agree, HTML is fine (still a bit too verbose IMO, in particular having to repeat the tag to close it always felt useless and very noisy).

But HTML is a markup language, the problem is that for some insane reason a big chunk of the industry at some point decided that XML was a reasonable serialization format. That's where it went really wrong IMO.

In HTML you can leave out the end tag in cases where they can be unambiguously inferred, like:

   <p>First paragraph<p>Second paragraph</p>
P-element can't be nested, so a <p> will automatically close the previous p-element.

But this also means it is necessary to indicate the tag name in the closing tag. For example this would be ambiguous:

It cannot be inferred if it is the div or p which is closed.

XML is of course different. Since all element have to be explicitly closed, repeating the tag-name in the close tag is in principle superfluous. I think it makes it easier to read though, at the cost of more effort to write.

> "well fuck it, we'll just jam it all into a string.

This is an almost universal disease of people trying to write XML grammars (or database schemas before that). Everyone thinks they can unambiguously decode multiple pieces of data stuffed into the same fixed-width field, and pretty much all of those people are wrong. Over, and over again.

That they never learn is a testament to the developer's ability to make fixing their Kruger-Dunning moments Someone Else's Problem. Get promoted or switch teams before the consequences are unavoidable. You can make an argument that even Tim Bray did this.

There are a lot of reasons XML was never going to succeed, and this is far from the most important, but it's a substantial contributing factor.

So one reason for XML failing is that people who nominally used XML didn’t fully use its capabilities to capture data structure and kept their habits from the days of representing all data by fixed-width records?

XML and Java both come out of the same era. Java was supposed to be Object Oriented, but what we got instead is stringly typed code.

Array literals in programming languages are pretty much as compact as you can get (start, end, one character element separator), and the type system or a little code often allows you to fix a 1:1 mistake after the fact. This attribute is now a number or an array of numbers.

In XML if you want a properly formatted list you have to use child elements, which gets expensive really quickly so people balk. Especially if you already failed the attribute/child test by mistaking the value for 1:1 when it turned out to be 1:many.

We also already have HTML class, style, and on* attributes as prior art that we use to convince ourselves that one more will be okay. Basically XML gets it from both ends. XML makes entity relationships and irreversible decision, in an era where UML existed and harped constantly on it.

I don't know if there was any fixing it at that point. What I do know is that a lot of us shot meaningful glances at each other and tried as hard as we could to find something else to do until the dust settled. But you really could not avoid XML in the 00's.

> If you need to generate basic shapes it's fairly straightforward.

You'd think so. While integrating TeX into my editor[0], using JMathTeX[1] as a starting point, I wanted to convert font glyphs to vector paths. At the time, every Java-based SVG renderer (Batik, JFreeSVG, SVG Salamander) suffered from the exact same performance problem: they all used Java's DecimalFormat class to convert floating point numbers to strings. These strings were then concatenated as paths into the output document. Sometimes the strings were re-copied numerous times because of buffer re-allocations and other reasons. (Part 5 of my series[2] on developing a TeX-oriented text editor covers this in depth.)

To get great performance---in Java, at least---even for basic shapes requires a sufficiently large, reusable buffer that doesn't incur memory re-allocations and an efficient algorithm to convert floats to strings---such as Ryu[3]. See my implementation that converts glyph paths to vector paths for details[4]. With these two changes I was able to improve upon JFreeSVG's implementation four-fold.

[0]: https://github.com/DaveJarvis/keenwrite (my editor)

[1]: https://github.com/DaveJarvis/JMathTeX/ (my fork)

[2]: https://bell-sw.com/announcements/2020/11/02/TeXnical-Writin... (my blog series)

[3]: https://github.com/ulfjack/ryu

[4]: https://github.com/DaveJarvis/JMathTeX/blob/d2d678717505765b...

Using D3 to draw plots and other data visualizations is really golden. Next to other good plotting libraries (such as ggplot2) having SVG as my canvas really gives me the feeling that I can do everything that I want.

Its good if you need dynamic charts in JS but if you just want a graphic or a logo I wouldn't use it. Its also a huge pain to maintain, they update the library once a year with breaking changes and then it takes me a day or 2 to work out how the old version worked, how the new one works and how to move all my graphics over.

For the note, Sciter (https://sciter.com) and Sciter.JS support inline vector images in its CSS.

Instead of SVG and things like FontAwesome in 99% UI cases we use just these

    button {
      background-image: url(path:M 10 10 H 90 V 90 H 10 L 10 10);
      fill: red;

    <img src="path:M 10 10 H 90 V 90 H 10 L 10 10">

You don't edit raw png values either, with rgb/index values in a list. SVGs are meant to be created and used like any image file.

The fact that they are almost human-editable and can be inlined means we are bound to be disappointed when working with them in this manner

I disagree, I routinely manually mess with SVG (even SVG generated with a program like inkscape) because it lets me add interactivity and animations. That's the killer feature for me: you can draw arbitrary vector shapes in a website, then hook into them using javascript the way you would any DOM element. There are a few subtleties to make it work well, but it's pretty straightforward.

Here's an example: https://svkt.org/~simias/up/20210212-185105_svg.png

All the elements and paths are SVG generated from some javascript. You can interact with the various elements, move them around and the paths are updated in real time.

Of course you could do the same thing with a raster format by using a canvas and drawing a bitmap for instance, but SVG works at a higher level and lets you do these things a lot faster and probably with better performance. You can use CSS-styling, you can register javascript event callbacks etc...

Or to put it another way: if SVG was meant as an opaque machine-to-machine format, why even bother with the insane overhead of XML instead of using some dense binary format?

Getting your hands dirty by manually messing with SVG elements allows you so much freedom while plotting in D3, it is amazing. If you do any sort of advanced data visualization on the web, being able to read and write parts of SVGs is essential.

Along those lines, I recently encountered this project that enables the use of SVG to design maps etc for games developed with the Rust language game engine Bevy: https://github.com/carrascomj/bevy_svg_map

"The properties of the lines (color, opacity, fill...) can be used to programmatically add functionality..."

Yes, but SVG is not good as a machine-focused format as well, that's kind of the point.

I like this kind of compromise where illustrator etc generates the SVG but you can read elements in the actual text so you can animate or transform with css or js.

Fir example I recently made this 'hack' for gradient transform. even 'hacking' that was easier than maintaining and understanding complex canvas JS - at least to me.


Love it! I'm just wondering, aside from the animation part do you ever need to edit an Illustrator-generated svg?

I do personally for color control. You can see my heavy use of SVGs here at a site I'm in the middle of implementing [0]. For example, if you look in the :root {} you will see a lot of CSS variables that are declared and which manipulate their HSL value based on base variables like --hue. The SVGs implement these. So you can change the global --hue, and the hue of all the SVG elements on the page will change. I've modified output SVGs from figma/illustrator to reference a variable rather than a hardcoded fill i.e. <path fill="red"> becomes <path fill="var(--base)"> That's a simple example, you can go further to change relative saturation and lightness as well, which I also do with CSS calc(). It's fun!

[0] www.holysnacks.us

i like the sun rays!!

I do love the mix of css vars into SVG. it makes a lot of sense to me too.

Wow I never thought of doing animations that way. Great stuff!

> You don't edit raw png values either

However, for when you want that there is SNG¹. It can be a surprisingly fun way to perform minor corrections or filters to an image.

¹ http://sng.sourceforge.net/

> SVGs are meant to be created and used like any image file.

Then why bother with the XML? And why use the embedded DSLs in strings instead of the more verbose XML-way.

Also, don't forget the inconsistency of being able to use units like `px`, `ex`, ie: `<circle cx="10ex" cy="10ex" r="2ex" fill="red"/>`, but it would be invalid in `path`. The unit in path is exclusively `px` only.

I think it would be nice to have a design language:

  def port 0,0 100,100:
    L 10,10 90,0 90,70 70,70 70,90 20,90 20,70 10,70 10,10
  def bank 0,0 400,100:
    port 0,0 100,100
    port 100,0 200,100
    port 200,0 300,100
    port 300,0 400,100

  def router 0,0 1100,200:
    port 50,50 150,150
    bank 200,50 600,150
    bank 650,50 1050,150
  router 0,0 1100,200
I was thinking it would be cool to have an "about" page in openwrt showing your router with all the ports labeled in svg. Should be simple, but I couldn't figure out luci.

Those things are not equivalent.

The circle has unordered properties.

The path has ordered commands. I suppose those commands could be separated and numbered, but isn't that a lot more verbose and less readable?

Agree a vector graphics format isn't the use case for markup languages. SVG's saving grace, though, is that's designed to be embedded in HTML.

SVG provides elements for things you're going to individually address with XPath or JavaScript. Points are less likely to be manipulated that way, so it's OK to stop using XML to mark up the structure here. Many other data types, such as time, HTTP or email addresses also have structure, but you normally don't explicitly mark it up because they're trivial to parse.

> <path d="M 10 10 H 90 V 90 H 10 L 10 10"/>

And that can be optimised further (by svgo) to:

    <path d="M10 10h80v80H10V10"/>
They can get almost hilariously dense and obfuscated.

I do not see what is wrong with the path string, which btw. is the same in HTML Canvas. I am using SVG on a daily basis and encountered many issues that annoyed me, but path data was never one of them.

I don't think it's wrong per-se, it's actually probably the best solution given the set of constraints. It was more about bashing XML's impracticality than SVG really.

The idea to stuff paths into attribute strings instead of using elements came from Microsoft's VML (one of the competing vector graphics standards that influenced SVG).


Pragmatically it was a brilliant practical compromise in response to one of XML's horrible flaws as a serialization format (it's way too fluffy), saving enormous amounts of memory and fragmentation by using one string per path, instead of creating thousands of DOM objects with tens of thousands of attributes and text nodes. But you're right, that's the "original sin" of XML that SVG is doomed to suffer with.

PDF is basically just the PostScript imaging model without the Turing-complete stack based programming language.

SVG is just the latest expression of PostScript graphics model (if you ignore all the stuff about fonts), which is based on the Stencil/Paint imaging model with Porter Duff Compositing, and descendent from Interpress and Jam).

The canvas 2d api is pretty much just immediate mode SVG / PostScript graphics, with a few new features added.

JSON's a much better format for structured graphics in some ways, but has its own set of flaws and limitation, like not having comments, and being terrible for binary data. But at least JSON arrays are a bit more (but not much) memory efficient than XML elements, and JavaScript itself has typed binary arrays, although standard JSON doesn't support them (using base 64 strings sucks). So representing paths as flat strings like SVG, instead of JSON arrays of numbers, is probably still a win for JSON if you're mainly drawing static paths, but not if you want to read, process or edit those paths a lot.

Now, instead of using SVG, it's usually easier and more efficient to just use your own (or some standard) JSON format for structured graphics, and draw it with the canvas api. But there will never be one universal JSON graphics format, just many special purpose ones. For example, d3 has a lot of different JSON formats (domain specific languages) for representing different kinds of graphics and data.

More on PostScript and its history:


>Brian Reid wrote about page independence, comparing Interpress' and PostScript's different approaches. Adobe's later voluntary Document Structuring Conventions actually used PostScript comments to make declarations and delimit different parts of the file -- it wasn't actually a part of the PostScript language, while Interpress defined pages as independent so they couldn't possibly affect each other:


There's nothing wrong with xml or other SGML based markups. They are meant to be written by a computer, not by hand.....

Maybe holds for XML, but not SGML. Its features such as SHORTREF and tag inference for eg parsing Wiki and other custom syntax into canonical angle-bracket markup (aka XML) are pretty much designed to be typed ergonomically and minimalistic, as popular as ever with markdown, etc.

XML is not an ideal format for computers.

Oddly sometimes.. XML syntax can be a bit more readable than JSON

W3C is defining SVG Native [1], which is a subset of the full SVG spec. The plan is to use it in font files and it should be a nice format for native apps. It removes support for CSS, the style attribute and lots of extra syntax. Even the XML parsing is made simpler by not requiring support for XML entities. Compression with gzip should create fairly small files.

By reusing the SVG format, it is still compatible with existing tools, such as Adobe Illustrator and Inkscape (meaning that they can open SVG Native files).

Adobe even has an open source renderer for SVG Native [2].

[1] https://svgwg.org/specs/svg-native/

[2] https://github.com/adobe/svg-native-viewer

They have also defined SVG Tiny, which is basically SVG without CSS and scripting support. Which seems to be more or less what OP is calling for in the blog post. Why the need to reinvent the wheel? For once, we have massive industry-wide momentum behind a unified vector graphics format. It can be very hard to swim against that current.

> W3C is defining SVG Native [1], which is a subset of the full SVG spec.

Cool, that's only the third time they do that (after Tiny and Basic).

It's even less than Tiny (= no CSS). I wrote some SVG manually recently and in my opinion SVG is quite fine for that purpose.

> Maybe JSON-based, definitely not XML-based


Strong schemas are _why_ it's supported across a multitude of platforms. JSON because "it's got JSON, what plants crave" is an absolutely dumb argument. And the see article "parsing JSON is a minefield". I can't think of a way to make the standard worse than re-implementing in JSON.

There are some legit missing features from SVG as other commenters have pointed out. To me, it sounds like the tooling is actually what's lacking. The equivalent of minifying or even the option to render xml to a binary representation is probably what is actually lacking.

I have worked with XML since it was a wee laddie. I generally prefer using JSON, but all my SDKs emit BOTH XML and JSON (and, occasionally, CSV).

XML Schema is the main reason I use XML. I hate Schema. Hates HAAATESSSS NASSSTY SSSSCHEMA..., but it is ironclad. If it is described in Schema, then it is guaranteed (or not; in which case Schema also accounts for that).

JSON Schema is a non-starter. No one ever seems to use it, and I don't think it ever made it out of committee. It pretty much goes against why JSON is popular.

If anyone wants REAL pain, then we should go back to BNF: https://en.wikipedia.org/wiki/Backus–Naur_form

I worked with a BNF compiler, and I still wake up screaming.

> JSON Schema is a non-starter. No one ever seems to use it, and I don't think it ever made it out of committee. It pretty much goes against why JSON is popular.

My company heavily uses JSON schema.

The OpenAPI project uses JSON Schemas, and AWS also allows for their usage in places.

And finally, there are a couple good projects that automatically generate JSON Schemas from Typescript definitions, which is my preferred way to go. :)

It's been "draft" for years.

Hasn't stopped tooling from being built around it.

Whenever I encounter JSON schema, It makes me aware that the important difference between JSON and XML is not the syntax (my IDE handles that fine), nor the features. But the difference in rigidity. JSON when agility is needed. XML when rigidity is needed.

I fail to see any benefit of a rigid, typed, schema'd JSON that XML does not offer more naturally.

Lots of APIs pop out JSON.

JSON schema let's you make that a bit safer.

My point is that if they need this "safer", why not pop out XML instead.

The largest benefit of JSON is that is not XML. That it doesn't get bogged down in schema's, strong typing, interfaces, contracts and so on. You loose all that by turning JSON into XML-written-in-a-different-syntax.

BNF is just a notation for describing a formal language. Although there are many slight variations of BNF in use, BNF is generally used to describe very precisely the exact syntactically legal sentences (that is, sequences symbols) that belong to a formal language.

Some languages are simple, for example the language that is any sequence of one or more 'A'.

A, AA, AAA, AAAA and so forth are all valid sentences in this language. This is a particularly simple language, but it could be described in BNF:

    <S> ::= A | <S> A
This language could also be specified as { A^n | n >= 1 } using a set notation or as a regular expression like A+

A slightly more complex language is the language of all sentences made up of a sequence of A and B in any order followed by a sequence of C exactly twice as long as the A's and B's together:

    <S> ::= <X>CC | <X><S>CC
    <X> ::= A | B
Legal sentences look like: ACC, AACCCC, ABCCCC, BABCCCCCC, etc. Such a language can't be described by classical regular expressions, but can be described by the context-free grammar expressed in BNF above.

There are alternatives and generalizations of BNF notations. Wirth used railroad diagrams to describe the syntax of PASCAL in the Pascal Report describing his language. This are more visual, but not more powerful.

BNF might be a pain, but there is generally no simple way to express complex syntax requirements for programming languages. BNF isn't used to solve the same problem being addressed by XML or JSON which are methods to encode data.

BNF is an archetype of declarative language.

But I used to work on an X.400 system, and we would have to map out data structures in BNF, pass it through a BNF/X.409 compiler that always hashed things up (often our bad, but that was back in the "big iron" days, when we would have to arm-wrestle for compiler passes), then, once we fixed the X.409, we'd need to pass it into a X.409/C compiler.

And fix it again...

I think, when developers don't like working in XML, it's because the tool forces them to do the job properly.

That's work for whoever is producing the document, but wonderful for all the consumers.

> because the tool forces them to do the job properly

I'd argue the same restrictions on "setting handwave to maximum" and "XHTML doc has one missing brace, no web page at all now" are two extremes that have their parallels in the 'dynamic vs static typing', 'immutable pure vs mutable impure functions', 'XML vs JSON (oh wait!)', and 'web app vs native program' arguments that we HN readers love to debate.

The trick is finding the happy medium between both extremes. Training some 'slackers' to "do the job properly" and convincing some 'purists' to be more pragmatic to the limitations of the world around them.

After all, we need something to occupy us during this Eternal September.

It's a trap. You only need to find the happy medium if you accept the constraints that generate the trade-off in the first place.

And in at least three of the four antagonisms you list, it comes down to the DX of the tooling. Static typing isn't so much of a pain if your type errors are helpful and descriptive. The missing brace in the XHTML doc is easily found when using proper and easy to use XML linters. And I don't see why writing native apps shouldn't be as simple as writing web apps. At least there are attempts that seem to get some mileage out of the idea (e.g. Revery, Flutter).

The trick is to make the toolset more approachable.

> I think, when developers don't like working in XML, it's because the tool forces them to do the job properly.

The flip side is that you will never find a JSON with the structure "{ "zoom": "startZoomMarkup" }5{ "zoom": "endZoomMarkUp" }".

> If anyone wants REAL pain, then we should go back to BNF...

Ironically, if one wants to implement a SVG reader they have to use the BNFs provided in the spec (for paths and whatnot).

Though the SVG 1.1 DTD is pretty nice to work with, I've built a SVG DOMish generator for both c++ and python (which takes forever to compile) so one, err...me, doesn't have to deal with all the underlying XML craziness. One of these days I'll get around to finishing the path parser, color parser, transform parser, &etc...

Hedge grammars have really nice features, which can be parsed by a class of pushdown automata. However, my experience is that not many people understood and valued those features in the XML ecosystem (see SVG but also Xpath). Would be nice to see actually a schema first language that has a good binary and human readable representation. IMHO we can do better than zipped JSON even if is hard.

what's wrong with BNF? as a language descriptor it's simple and concise, isn't it?

Context free grammars are insidious to use in general. The natural way to use them is to either generate all/random legal strings or check if a string matches the grammar.

Often what you want is instead to generate an AST, in that case you will run into ambiguosness problems.

It's a great data description language, but was NOT fun to work with, semantically.

JSON is a really poor format for anything but simple data.

XML may be verbose and not readable, but it is an excellent format for describing and storing data.

One alternative for SVG could be an SQL table like datastore, similar to sqlite. I would love yo have the ability to query data, rather than parse through XML. I do understand that transferring such data blobs over networks is an issue.

The biggest issue I have with XML is the ambiguity between attributes and child elements. The distinction makes sense in an abstract perspective, but real-world implementations rarely use them in a consistent manner.

One's a dictionary (unordered, simple unique keys), and one's a list (ordered, arbitrary contents, no uniqueness constraints). Schemas may enforce more, but those are the intrinsic qualities.

I agree that use varies widely, but the difference is fairly clear. The existence of nonsense doesn't mean one can't make good decisions.

Is it more logical to have a point tag which has the attributes x and y or have x and y as their own tags and values? Its not clear to me which makes more sense and it seems the spec writes using xml didn't know either.

since x and y are simple names, have simple values, and are unique pairs that apply only once to a point: attributes.

to use anything else means relying on an arbitrarily-complex custom schema rather than the much-simpler-and-far-more-standard schema of the language itself. similar to how we use datatypes in programming languages rather than just strings everywhere. both work! one is clearly giving up a lot, and gaining little.

Obviously, if you just reimplement SVG in JSON it's not going to get better, there would be far more to it. And I'm a big fan of strong schemas, it's the best part of XML.

While JSON is far from perfect it is a lingua franca; humans and computers all over the world are very familiar with it. I think this is one of reasons for the growing popularity of the glTF format for 3D models, which also has a binary variant.

SVG is another chapter in the long and storied history of engineers attempting to the question, "How hard can 2D graphics be?" And if you look at the industry standard answers (from PostScript to AutoLisp to Gerber to SVG) the answer is, "pretty damn hard."

I don't know if you can slim down vector graphics successfully. Every SVG renderer in existence slims down SVG to some degree. The ones that do it the most are used the least because they can't sufficiently express the intent of the designer.

I have to wonder if the author is not understanding the hidden complexity of rendering graphics. They make the claim that svg would take over a month to implement which sounds accurate, but then they claim that it could be replaced with a new format which could be implemented in a few days.

Surely SVG does not include months of work which is entirely useless. What features are we giving up for this simplicity?

2D vector graphics look easy at the beginning. There are some shapes, some paths, some affince transforms. But if you start to caclulate the length of a cubic bezier or try to find intersections between two cubic bezier curves, things start to get interesting. Then try to implement a solid and fast algorithm for boolean path operations. Next level of difficulty is to offset an arbitrary path, maybe with parametric offset for extra challenge. I have done all of these, and boy, I did not expect the rabbit hole to be that deep.

Even JSON is going to be "bloated". This cries out for a well-done, well-thought out binary format. While binary formats have certain disadvantages that never go away, a lot of the worst ones that we associate with them are the result of older standards that failed to contain enough extensibility. But there's a lot of good prior art to look at now. Heck, nowadays you could probably just define something as Protobuf (or your choice of similar standard, don't want to go too far into the weeds on the exact choice here) and be 95% of the way towards done.

Even just a linearization of most of SVG into the obvious layout, simply dropping any problematic features (script, XLink, namespace extensions) would probably be a pretty good start that you could churn out in a week as a prototype. You'd get an efficient binary format, an obvious mechanism for translating existing SVG into it (with equally obvious mechanisms for warning users about the existence of untranslated features in the output; also an easy mechanism for scanning sample SVGs and getting a statistical idea of how many fit into your new scheme), an obvious mechanism for translating your format back into SVG, and serialization support as cross-platform as your choice of serialization mechanism right out of the box. If this is your goal, this has a pretty hard to beat bang-for-the-buck.

There are tools for shrinking SVG that do some of what you say. One advantage of the text format is that you can reduce precision of the path data to a couple of significant figures. That would be hard to do with a binary format. You'd have to decide up front on 8 bytes or 16 bytes per coordinate pair.

Binary formats need not use fixed-length fields. You could use a format that stores small integers in 8 bits, yet allows for larger ones. See for example https://developers.google.com/protocol-buffers/docs/encoding....

You don’t even have to use byte-sized fields, but doing that makes encoding and decoding harder, and the overhead of also storing the actual lengths in bits of variable sized fields may be too much to make it worth that.

I think you missed my point. SVG coordinates are effectively arbitrary precision. 3.5 bits per byte of arbitrary precision, but arbitrary precision nonetheless. There are no small integers, only scalar or vector values.

varint style encoding is also arbitrary precision (although protobuf doesn't support arbitrary precision) It is trivial to get 7 bits per byte and you can do even better for large values by encoding the length upfront (this also makes decoding faster).

There's existing variable-length binary number formats [1] that already exist. SVG already has so many variable-length things in it that the downsides would probably be insignificant.

I don't know if any of the existing Protobuf-like things have these built in, though. I know some of them have variable integers in them but I don't know about variable floats.

This is kind of what I was getting at in that we have a lot of prior art now. Someone putting variable ints or floats into SVG no longer has to create their own bespoke format, and proceed to fall into the various traps themselves and accidentally write it forever into the spec; there's a lot more of these sorts of pieces that you can pick up off the shelf than there used to be.

[1] https://github.com/regexident/var_float

I don't see how var_float lets you detect the length of a number field from the input. It seems to be designed to take arbitrary input from another function (which has already decided how big the data is out-of-band).

Am I missing something, or can I not read 2 bytes from a file and detect if that's the end of the number or I need to read the next 2 bytes?

I dunno if that specific library has that feature, but it is certainly something that can be implemented. It's just a matter of programming.

yes, that is half of how utf8 works as an encoding: the first byte of a unit is either 0xxxxxxx or 11xxxxxx, in the first it is a single ascii byte and in the second case all the following bytes that start with 10xxxxxx are part of the same unit.

for this purpose it would be enough to revert the order of the stream.

> that failed to contain enough extensibility

Or too much abstraction and extensibility leading to excessive complexity!

> Even JSON is going to be "bloated". This cries out for a well-done, well-thought out binary format

Well unless it doesn't. I've recently read more than one blog post that claimed JSON was actually borderline faster—sometimes more than borderline—than some popular binary formats like protobufs. I won't link those benchmarks here because none were well enough conducted or presented to warrant a link; I myself treat those reports as plausible but anecdotal hints.

It's not like saying "binary format" makes all your troubles go poof. You still have to parse it. Yes, you can control it better when you create it, but when you've created it and it sees a lot of adoption, then updating it will be just as troublesome as updating any popular format, meaning many clients won't support some of the new features for at least some time.

Numbers of course are central in any actual SVG, and it turns out using a textual format to send numbers is not as stupid as it sounds, space-wise: `1` is just one byte, but it's 8 bytes (I think) of RAM when turned into a JS IEEE754 number. You can represent arbitrary precision or restrict yourself to integers on a whim when using text, something probably not true of most binary formats.

One of my qualms with SVG are that XML itself is a needlessly complex format. As sort-of-proof for that claim I present you the fact that the [namespace on the `href` attribute has been elided from the standard](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use). This of course is just the tip of the iceberg of XML complexity.

The other big Qualm is that for some reason the authors of SVG felt it necessary to open the doors for a lot of variation on how to write things like e.g. the `<path>` element's `d` attribute, like you can add commas or leave them out, you don't need whitespace in `"45-67"` because that can be parsed as `(45,-67)` and so on. Not useless stuff, but in the end more than minimal complexity.

I find text-based formats so much better in many regards. Just look at the rich appearance of web pages today, almost all of that has been done using text-based formats. They're really powerful, and where needed, may be compressed using a generic algorithm.

> Decide whether a language is for humans or for machines and do one of those things. And do the one thing well instead of both, but badly.

The thing is all these languages (ASM, C, XML, JSON, Python, etc) are fundamentally about communication between a human and a machine. We make tradeoffs between making them easy to parse (for the machine) or easy to read and write (for the human) but they all must address both needs. And when you have a problem domain as large as "2D Vector Graphics" or worse, "The Web", complexity is unavoidable.

I'm not saying we can't do better than SVG. I agree with many of the author's points and would love to see a minimal subset of SVG that is easy to write by hand. The tradeoffs are engineering decisions and important. But don't pretend that you can pick a goal such as, "easy for humans" and ignore all the other dimensions of the language design problem.

You're absolutely right, it is always a trade-off. I've added a paragraph at the end of my article focused on that particular problem to address that: https://www.eisfunke.com/article/language-design-machine-or-...

> fundamentally about communication between a human and a machine.

True! And we should not postulate who is at both sides of the communication - machine or human. It's like postulating that a hammer is a tool which must be held by a human hand, which then precludes robot-operated hammers.

Article mentions svg supports <script> tag... Coolest use of it: https://www.xul.fr/svgtetris.svg

FlameGraph [1] renders profiling results into svg. Profile is essentially hierarchical; a user can zoom into subtree by clicking an element. Probably not an inspiring use of script in svg; but boy, how handy this feature is!


[1] http://www.brendangregg.com/flamegraphs.html

Here's a full-on dice roller / Virtual Tabletop that takes advantage of this: https://github.com/sjbrown/togetherness

Tetris in an SVG?!? I am in awe.

I'm feeling equal parts: "this is beautiful", "this is perverse", and "I want to do this too"

It seems like the French have a passion for dynamic SVGs.

Space Invaders! Amazing!

Is that an example of SVG including a script tag or just manipulating the SVG DOM through javascript? I think that's 2 separate concerns. Browsers already understand both, I think the article puts it under "The Bad" category because if you're building a renderer from scratch, you'd need to also handle javascript and DOM stuff.

Wow. I'm unsure whether I should be impressed or horrified. I've added the link to the article, thank you.

I'm both

Less impressively, a clock: https://www.nayuki.io/res/full-screen-clock-javascript/full-... (50 lines of code)

I liked this one, hiding on wikipedia:


A morphing digital clock

Oh man. Way back in the long long ago I worked at Adobe. I was a test engineer on the SVG <script> tag, mostly making sure that the DOM methods all worked properly. Lots and lots of interesting micro-projects there.

The one I was proudest of was a 3d chemical viewer where you could grab the molecule and spin it. SVG was only used because it was convenient to do the visualization. All of the 3d transforms were done in Javascript. But to have Javascript that could fluidly spin a 3d model was pretty amazing in 2000.

Cool, thanks for sharing!

FYI, the OP posted an update with a reply to you:

> This article was posted on Hacker News... > In the comments there somebody mentioned an interesting use of the <script> tag in SVG. I’m unsure though whether I should be impressed or horrified :D

Wow this is super amazing (and little horrifying). Never knew SVG can contain Javascript. Always thought of it as just a little safe vector graphics markup.

I wanted to just write a page of screaming sounds but I figured that wouldn't go over well here.

"Why am I still struggling with browsers having different SVG implementations 18 years after the initial implementation?" is something I had to ask my self two days ago when the comma in our logo magically shifted to the left only on Firefox.

It looks like the spec here is partially to blame because 800 pages is something that even the most meticulous team of devs would have a hard time implementing without some divergence from other implementations.

I decided to switch to a high quality PNG and call it a day since we had other more important things to be focusing on.

It's not just specs. In my experience you need a comprehensive test suite that implementations can use to test they cover the edge cases.

I have been interested in the "low code" problem, in particular the kind of advanced parsers that were used in the 1990s to attempt things like "edit the UML diagram in a GUI and change the Ada source code the way a professional programmer would".

Dreamweaver used to do this for HTML, sometime before it got bought by Adobe. Today Dreamweaver seems like it would be usable on a 90 THz computer but I can do 10 push ups waiting for the UI to settle down after typing "Hello World".

A split-screen SVG editor would be particularly good, since so much of editing an SVG file is getting the numbers right. You'd face many interesting problems, such as exposing decimal math to the user (whatever iffy floating point is used, your git commits are going to be awful unless you "snap to grid" in factors of 1/2 and 1/5.)

What I'd particularly like to do is have control of the structure of the document so I can group elements with the discipline of a programmer.

A tool like that still might not be satisfying because Bézier curves were made to make people feel like they were bad at computer graphics and took over instead of better alternatives that were patented at the time. I was shocked to find that my favorite character designers don't know how to draw anime characters with Bézier curves.

Is this what you mean by groups?

"The <g> SVG element is a container used to group other SVG elements.

Transformations applied to the <g> element are performed on its child elements, and its attributes are inherited by its children. It can also group multiple elements to be referenced later with the <use> element."



That is the most prominent tool one would use to apply "programming" or "architectural" discipline to SVG.

For instance you could make a <g> that looks like a cat paw and then <use> it to make a track of cat paws. That's more disciplined then say, "cut-n-paste" a cat paw you drew 10 times which a real artist might do, or I might do because I can always figure out how to do it with a drawing program.

Related to that is the use of CSS, which can range from beautiful code which is easy to understand towards a complete mess.

Author here, for editing SVGs by hand I use VSCode (or VS Codium to be precise) with the SVG Viewer add-on in split-screen: https://marketplace.visualstudio.com/items?itemName=cssho.vs...

Works pretty well as split screen editor. The preview refreshes on save with ctrl-S.

SVG was actually one of the first topics I'd planned to tackle once https://concise-encoding.org/ and the reference implementation is finished.

You definitely don't want to solve SVG's bloat problem by moving to another text-based format.

Do you still plan on tackling it?

Yup! It's just that CE spec has taken much longer than I'd anticipated ;-)

The CE spec is for all intents and purposes done (I don't anticipate any more changes), and the reference implementation is in the final stages. After that comes the schema format, then the official V1 release, and then I can move on to technologies built upon it.

From some back-of-the-envelope calculations I made recently, I should be able to represent the same vector graphics in the same basic structure (such that you could convert between them), but in about 1/3 the space (not including the crazy stuff like CSS and JS).

I came here to share my all-time favorite resource on SVG:


Sarah Drasner is awesome, and even though the preso is 4 years old(!) it's still relevant and inspiring.

Here's the talk that the slides accompanied: https://www.youtube.com/watch?v=dv2TvTXQ4FQ (36min)

The real ugly with SVG is how frequently we request SVGs from designers or companies and they hand us an SVG file that contains nothing but a base64 encoded PNG image.

Lot of vector editing programs just cheat when things get difficult. I have seen drop shadows as bitmaps, path intersections that become polylines with zillion line segments, elements that are just missing, you name it. Doing vector graphics is hard beyond basic shapes, and I have the feeling that some developers and companies underestimate what they are trying to do at the beginning and then have to rely on workarounds for some features.

The last time I needed an SVG I gave up and just typed it out in Vim.

My two gripes with SVG I bumped into (although the second one is more to browser implementations).

1. It doesn't support premultiplied alpha interpolation mode. If you ever import partially transparent rasterized images then it can cause visible artifacts at the edges of opaque regions.

2. Last time I checked no implementation supported interpolation in linear colorspace (linearRGB [1]).

So even though it's bloated it still misses features. And even though browsers are good fit for supporting it, they still don't bother implementing the full spec. And they implement PDF with vastly more gradient elements and color interpolation modes.

[1] https://www.w3.org/TR/SVG11/painting.html#ColorInterpolation...

Other stuff that is missing:

- Relative coordinates. You can hack around this by using other SVG documents inside an SVG document, but this is really just a hack.

- Conic gradients. Even CSS has them.

Also, there are still a few implementation bugs for SVG. The Chromiums and Firefox teams have done an outstanding job at fixing bugs over the last few years, but if you do advanceed stuff, you will inevitable bounce into one of them. Also, Safari is not really good at SVG, but honestly, who cares.

> Relative coordinates. You can hack around this by using other SVG documents inside an SVG document, but this is really just a hack.

You can also use <def/> to achieve something like that.

If you're looking for a machine-readable vector graphics format that has an SVG-like imaging model, there is such a format already: AI4

AI4 stands for Adobe Illustrator 4.0. Gnuplot and Mathematica can produce AI4 files. Most vector graphics programs can open AI4 files too.

Here's the documentation: http://www.idea2ic.com/File_Formats/Adobe%20Illustrator%20Fi...

SVG is preceded by and informed by postscript and PDF.

The postscript language reference manual is 912 pages.


The PDF reference is 978 pages.


SVG, if it's less than either is actually doing well...

IMO these three technologies and the accompanying docs are masterpieces, despite bloat. Digging in to those reference docs can almost be fun

The author's idea of SlimSVG sounds interesting, but I think focusing on the file format isn't enough -- one powerful feature of SVG is that it's part of the DOM. Can there be a better system than the DOM+JS for allowing a dynamic document?

EG, document object model in JSON (maybe with JSON schema) and allow updates with JSON patch, with a client/server model for updates. (There's more to DOM)

Personally I think XML is well suited to this task, and am glad to have learned of SVG Native from this thread

One thing I wish this mentioned in the "Ugly" section is how allowing Javascript, and to some extent using XML, creates security issues, such as potential XSS (because of javscript), XXE (because of XML), etc. You can avoid vulnerabilities if you're careful. But you have to be careful, and know what to look out for.

> Instead you compile it into an PDF (which is also a horrible format and badly bloated, but well)

Yeah... PDF might actually be worse in some ways (and it can have javascript too). With SVG, it isn't too hard to be able to use a subset of SVG to generate images. With PDF though, just making a valid, useful PDF is pretty complicated and requires a decent understanding of the spec (which is big). Being able to properly render any valid PDF is probably even worse.

> Maybe JSON-based, definitely not XML-based.

If we're going to start over, let's create a new syntax that's purpose-built from the ground up. JSON doesn't replicate all of the drawbacks of XML for this kind of purpose, but it replicates a lot of them. Like, all the forces that lead major XML formats to embed their own little mini-DSLs inside of strings are present in JSON as well.

There's this tradition in our profession, perhaps born of a reaction to the "not invented here" syndrome of the '90s, to habitually hack things together out of bits and pieces that already exist. Seemingly for no reason other than because they already exist, and they can be hacked. I've recently started calling it "Wallace and Gromit engineering."

I love SVG. I use it to make neat interactive genealogy charts (clickable URLs):


and Fan charts:


For writing your own graphics in text format, I think that PostScript is good; you could then make the output in whatever wanted format (which can be raster or vector formats), if you have a driver to do so. But if you want storage of vector graphics as the result, different formats will be needed, and I think that PDF and SVG aren't very good, and neither is PostScript (which is a programming language, not a vector graphics format, although it is a programming language for vector graphics).

Ghostscript does not have a SVG output driver, although you could first output to PDF, and then use another program to convert PDF to SVG. If they make SlimSVG or other vector formats, then hopefully a Ghostscript driver for that format could be provided, in order that it would be possible to produce it from PostScript programs.

You could then produce SlimSVG or whatever other format using whatever programming languages you wanted, whether PostScript, Haskell, or something else.

This doesn’t read as very well-argued. This post, and the human-versus-machine-readability one which precedes it, makes a number of general claims without pointing at any examples. I don’t feel like it will convince anyone who isn’t already familiar with the relevant issues.

Which is a shame, because I actually agree with a lot of it.

Web "standards" are majorily screwed up. We can't build tools like interactive charts, such as an ERD editor, because the charting and drawing tools are separate from the data entry tools (INPUT tags etc.). And they still don't directly support rich GUI's. Thus, a lot of common UI idioms have to be reinvented via bloated buggy slow JavaScript libraries.

I propose web standards be refactored and split into 3 categories: A) Art, media, & entertainment. B) Documents and brochures, and C) CRUD, GUI, Data, productivity

They would overlap as much as practically possible, but could also specialize in their respective niche better.

I recently had to decide between using Canvas or SVG on a project involving animation in the browser. I wanted to use a reactive framework (VueJS to be specific) and went with SVG for that reason. Pieces of the overall image are stored as Vue components. Animations become as simple as vue bindings in an element. A comparative Canvas build out would have been considerably more complex making it more difficult to manage. The trade off was performance loss. You can only manipulate so many pieces of an SVG before you get a drop in framerate. But, for my project, the reduction in code complexity seemed worth it.

Good, bad, or ugly, I'm happy I can embed SVG directly in html files and then manipulate it with Javascript. Life is easier when you're teaching and you put everything in one file that students can open in a browser.

I see nothing wrong with the XML. At least in its basic form. I use it extensively (often manual editing with the help of notepad++ / notepadqq) with no problem. I am not a dedicated web developer either.

I really appreciated this article. It would be great to see a smaller svg graphics standard. I think SlimSVG is a bad name because it implies its still SVG. It should set its self apart. Just my 2 cents.

In my opinion, what makes SVG bloated is not the fact that it's for humans or machines, this is mostly irrelevant compared to the ability to have filters, CSS animation, interactivity, advanced rendering options on different contexts...

Concerning the simple use of standard shapes, you could restrict yourself to simple shapes within SVG : thus youd already have myriads of existing implementations and tooling, it would be mostly understandable by humans, short and writable by hand/simple scripts.

You could even call them mobile SVG Tiny and Basic : it exists since 2009. https://www.w3.org/TR/2003/REC-SVGMobile-20030114/ . That would be a good start.

I've recently done a "deep dive"(ok just lots of thinking and trial and error) on using SVG or CSS for my to be released card game - (Think Monopoly Deal).

Man oh man what a rabbit hole. I went back and forth on implementing mostly the GUI with CSS to mostly the GUI with SVG and now BACK to having mostly CSS as opposed to SVG's.

Biggest problem is the blurriness ! "Scaling a playing card with text down (transform:scale|scale3d etc... ) - just ends up looking blurry. These are vanilla html-based-svg I 'coded' by hand.

> A good idea would be to develop a simple vector graphics exchange format that is desigend to be easily processed by machines. As minimal in features as possible. Maybe JSON-based, definitely not XML-based.

Just for the note, there is such format already and it is quite popular actually, see: https://lottiefiles.com/

Lottie files are JSONs produced by Bodymovin plugin for Adobe After Effects.

These are primarily for short vector animations but lotties work OK for static images too.

SVG is my favoriate web language. It's good, and so close to being great. Honestly I think if it was almost anything other than XML that would push it over the top.

I think this article totally misses out on the UI/UX benefits of an SVG. For example, I've been able to implement amazing animations that require little effort from me and allow designers to really show off their talents.

SVGs may not be perfect, but the pros definitely outweigh the cons. When I work on the frontend, I think there are very few use cases where I have to worry about the readability of an SVG. The author also kind of lost me at JSON-based graphics.

One person's bloat is another person's feature. Most of the "bloat" and inconsistent support issues in SVG are in SVG text, filters, animation and DOM interfaces. You don't run into those if you're doing the basic drawing that the OP wants to create. Basic SVG drawing is very straightforward and honestly, quite compact with lots of shortcuts and sensible defaults. (except for markers - which are craptastic).

There is already ivg https://github.com/reactivego/ivg

Yeah, that's a renderer for the IconVG file format. As I've said previously:

IconVG is a compact, binary format for simple vector graphics: icons, logos, glyphs and emoji.

IconVG is similar in concept to SVG (Scalable Vector Graphics) but much simpler. Compared to "SVG Tiny", it does not have features for text, multimedia, interactivity, linking, scripting, animation, XSLT, DOM, combination with raster graphics such as JPEG formatted textures, etc.

The announcement is at https://groups.google.com/forum/#!topic/golang-nuts/LciLeI5p... and quoting from that:

"The SVG spec prints as 400 pages, not including the XML, CSS or XSLT specifications. [The IconVG godoc.org page, which includes the file format specification, prints as 26 pages]...

The Material Design icon set... consists of 961 vector icons. As SVG files, this totals 312,887 bytes. As 24 * 24 pixel PNGs, 190,840 bytes. As 48 * 48 pixel PNGs, 318,219 bytes. As IconVGs, 122,012 bytes."

I thought about migrating Radial Menu [1] to SVG once, after 1 hour fiddling with the code I kinda gave up. What a mess. I remember reading somewhere "if you are coming from canvas programming, you might find drawing a circle counter intuitive" - yeah, I did.

1 - https://github.com/victorqribeiro/radialMenu

>like to write it by hand

I'm honestly horrified that someone out there is writing SVG by hand.

I did it to create templates (svg with jinja2) that I then parsed to generate unique images as svg.

Inkscape made a nice initial template, but lacked finesse and precision with naming, scaling, text-wrapping and nesting. Inkscape came up with a rather messy blurp of XML. No clear IDS, rounding errors, arbitrary nesting through groups, arbitrary ordering, etc.

Being able to open a file to quickly change the fill color of a figure for example is nice.

I first did it with inscape and the file size of the simple logo I was editing went up by 6x due to the inscape metadata so I did it manually.

I have done it, but only for some very simple stuff like a logo constructed from a small handful of coloured circles. I certainly would not recommend it for more complicated work.

It's actually not that hard...

But yeah, I did. Quite a few times. I even did a SVG path to G code converter once.

Wasn't XML developed for documents, i.e., text that is mostly words, like technical manuals? Isn't that why an xml file is called an XML document. Seems to me anyone that uses it to store data is using the wrong tool.

These are all things I’ve been thinking about, as I am currently writing an svg-like language specifically for UI designers. What he said about languages for humans vs machines is so true; it’s a difficult question to answer.

Recently switched from SVGs to PNGs because the toolset the designers are using means every SVG has the same HTML ID attribute value. So when rendering >1 SVG on a page, they all render the same as the last one in the dom.

Take a look at SVG Injection. This may solve your problems, as the injector will add a unique id to your SVG:


Magnifying the SVG as part of the workflow, svgo for instance, is a life-saver for all these edge-cases.

Especially considering the svg that a design tool produces is often gigantic. FWIW I have found svgcleaner to be better than svgo. svgo seems to have more bugs and chokes on svgs more often in my experience.

Noted, thanks.

I use this for most SVGs: https://jakearchibald.github.io/svgomg/

"SVGO's Missing GUI". Give it to the designers and they can make sure to give you the smallest possible file that makes sense. I find that some files look great at "0" precision, some require "1" or "2".

Just use img tags pointing to SVG's?

JavaScript based manipulation of the SVG’s nodes doesn’t work then.

But the parent said they switched to PNGs, same issue right?

I decided to switch from SVG with build time manipulation of attributes (scale, colours, rotation, etc) to an image optimisation library (and soon probably a saas like imgix).

I'd prefer to have stuck with SVG had it not been for the I'd collision thing, so with one of these tools in our chain we just might do that.

IMG tags pointing to SVG's don't have ID collsions since the SVG is in a isolated context, it's opaque to the referencing page because it's treated like any other img reference.

We use some server side code to recolor svg's on the fly with caching headers so they aren't requested all the time, mostly through img tags since we moved from PNG to SVG, its just works.

It's a no-go for this use case. Simply because we cannot manipulate the SVG's attributes (at least not as easily) when using them within img tags. Can when they are "inlined". We reluctantly adopted PNGs and convinced designers to provided assets for a whole spread of sizes and colours which doubled or even trippled their workload, just because we were stalling and trying to find alternatives (we have begun building an automation chain for PNG colour conversion etc). Moving forward, I'm going to experiment with one/some of the SVG optimisers and try going back to build/run-time SVG attribute manipulation. It's what SVGs were built for.

Using inline SVGs also reduces our caching complexity _dramatically_. I'm now "just" caching markup with no binary asset caching.

Moving forward I'm going to experiment with

Yeah sorry just not getting it, you can't use SVG's with image tags due to not being able to manipulate them however you then go to PNG's which are even harder to manipulate and are img tags right?

At least SVG as images can be resized so you only need one asset regardless of size, color manipulation then is the issue, but since SVG is just xml it pretty easy to do server side and again the browser will handle caching just like any other image.

shrug The switch to PNG was in haste after we suddenly saw our icons etc all using whatever the last loaded SVG looks like. We already have a PNG "solution" (more like a hack.. someone remembered how to use imagemagick to setup up some build time manipulation of the PNGs -- we didn't even check if we could do this for SVGs we just wanted it fixed asap) plus the designers offered to export the bulk of variants as PNGs for us without much discussion at all, and the rest we made up with the imagemagick hack.

So we jumped to PNGs (like 2 weeks ago, fyi). Now that we (know about, and) can use one of the svg cleaners, we'll switch to that and go back to inline SVGs.

PNGs were always seen as inferior. We don't want extra requests to load them - our app is very sensitive to the number of requests we make - we're importing them as datastrings even.

Anyway, the choice was made. Now we're 90% likely to revert to inlining SVGs with some kind of cleaner in the pipeline. Please don't lose any sleep over it. We'll be just fine.

Unrelated. But why does this site need a sticky header? Such a waste of space on a small monitor. Stop designing for 30" screens people!

> A good idea would be to develop a simple vector graphics exchange format

Ah yes, good ol' https://xkcd.com/927/

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact