React: Missing SVG tags and attributes

Created on 8 Jun 2014  ·  107Comments  ·  Source: facebook/react

Note from maintainers: Starting with React 15, we should have a complete support of the subset of SVG specifications that is actually implemented by browsers.

If you find a missing attribute, or if a tag does not work correctly, please write a comment below. Note that React.DOM.* factory functions might not provide all tags, but you should be able to use React.createFactory or React.createElement() directly for the missing ones. Or you can just use JSX which translates to React.createElement() and supports all tags inherently.

SVG

Most helpful comment

I noticed that there seems to be quite a lot of confusion about the xlink:href attribute. It _is_ currently supported but you would need to write it in a different way:

<use xlinkHref="#shape" x="50" y="50" />

React will correctly turn that into xlink:href, even in 0.14.x. See this fiddle for an example.

All 107 comments

Anybody working on this? I'd be keen to implement the filter tag.

preserveAspectRatio also seems to be missing: http://jsfiddle.net/jonase/kb3gN/3025/

Should I create a PR for this or do you prefer to collect all the missing attributes/tags first and later create a single patch?

[edit] preserveAspectRatio was added in commit https://github.com/facebook/react/commit/0f0328f0930d7fcf0b92cde40b1d6966cd747054

Hi.

marker* attributes have been added thanks to @cassus in #1738 as stated above.

What about adding the related <marker> SVG element?
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/marker

I just realized I need this too. Here's a good overview of it: http://tutorials.jenkov.com/svg/marker-element.html

This "add a random element and attribute here and there as 1 person needs it" approach has gotten out of hand. So we either need to support everything or nothing (or alternatively add a reasonable set of things now and then freeze there).

I scraped http://www.w3.org/TR/2003/REC-SVG11-20030114/attindex.html for _almost_ everything (not counting namespaced attributes) and came up with this: https://github.com/zpao/react/compare/fuck-svg.

However that adds ~2kb to our minified build (though it would crush well with closure compiler) and I don't want to take that size increase right now. We've talked about doing a separate SVG build. Or shipping that separately as an addon.

@zpao you're right. Full SVG support could be an addon. To do so a depreciation warning will need to be set to inform for example than React.DOM.circle will become React.SVG.circle

+1 for React.SVG.circle

@zpao
A full SVG add-on sounds like a good approach. Many projects don't need any SVG, so we shouldn't weigh down the code for them. Other projects need and it doesn't make sense to only go halfway on support.

+1

2069 requests support for image.

+1 for image support

+1 for image support as well

+1 for <use> support. We are using that for our svg icon set. We are trying to dangerouslySetHTML to make it work, however, the event bubbling doesn't work with it.

Missing strokeDashoffset. I want to use it for a progress bar, like this: http://codepen.io/JMChristensen/pen/Ablch

+1 for strokeDashoffset

also want to use it for a progress bar .

I am missing alignment-baseline when working with <text>

Perhaps someone has the will-power to trawl through http://www.w3.org/TR/SVG/Overview.html and get all the attributes and properties? (There might be a better URL for this purpose, not sure...)

Another help would be to know where to change this in the source-code and the tests so that it is easyer to make a commit to react.

FWIW, most attributes can still be applied using the style attribute.

<path style={{strokeDashoffset: 100}} />

@syranide I did that (mostly automated because that would be madness to do manually) - https://github.com/zpao/react/compare/fuck-svg. See my previous comment about why that's not just merged in already.

@ThomasDeutsch See most any of the previous SVG related pull requests. That said, I'd rather figure out a plan than add them one by one (I'll direct you to my previous comment too).

+1 for textPath - I need it for a project I'm currently working on, and right now I'm hacking a nasty solution. I'd be happy to contribute an implementation to a React SVG plugin pack

:+1: for a full SVG add-on. Any estimates on when that would ship?

+1 for foreignObject

+1 for foreignObject

The attribute xlink:href in order to use svg sprites.

+1 for <use> support

Currently using https://www.npmjs.org/package/react-inlinesvg as a work around for this.

Attributes: maskUnits & maskContentUnits (#2056)

mask attribute #2535

patternTransform

text attribute text-anchor

+1 for textPath

+1 for <use> for svg icon handling.

+1 for an SVG add-on. I currently only need <clipPath> for a project, but who knows what I'll need in the future. A comprehensive add-on would be very helpful.

+1 for an add-on.

We are planning to make extensive use of SVG with React, so a complete SVG add-on for projects like ours seems like a great idea.

+1 for textPath and more complete svg support in general.

Until SVG is fully supported, a decent workaround is to tell React which svg attributes it should pass through to render and declare the elements you need explicitly. For example, <use> can be accessed like this:

var DOMProperty = require('react/lib/DOMProperty');

// xlink:href is not a standardly-supported svg attribute, but you can tell
// React that it is ok.
DOMProperty.injection.injectDOMPropertyConfig({
  isCustomAttribute: function (attributeName) {
    return (attributeName === 'xlink:href');
  }
});

var SvgButton = React.createClass({
  render: function render() {
    var use = React.createElement('use', {
      'xlink:href': '#' + this.props.icon
    });
    return (
      <button>
        <svg>
          { use }
        </svg>
        <div>{ this.props.label }</div>
      </button>
    );
 });

@jeffkole Be careful when doing that – React will still call setAttribute (not setAttributeNS) if the attribute changes, and the update probably won't work properly.

@spicyj I don't see any namespace support in React (ie, there is no call to setAttributeNS in the codebase). Any suggestion on a proper way to set an attribute with a namespace?

We haven't figured out how namespaced attributes will work and don't support it right now, sorry.

vector-effect would be nice. Is there another way to keep fixed width strokes without it that can be used in the meantime?

+1 for foreignObject

Just referencing my PR for text baseline attributes: #2697

oh shit I need use tag :disappointed:

I've resigned myself to using a custom component that has a render function that returns

<svg dangerouslySetInnerHTML={{ __html: '<use xlink:href="#' + this.props.icon + '"/>' }} />

It is ugly, but it works.

:+1: on this

+1 on for full svg support in addons

:+1:

@zpao @spicyj is there a supported way of adding these individual SVG elements to React without monkey-patching ReactDOM and SVGDOMPropertyConfig?

Sorry, no.

+1 for image and foreignObject

+1 for foreignObject

animate does not work and possibly some of its attributes: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animate

What is the status on supporting SVG in addons? Just ran into this today :-(

cc @xymostech @MichelleTodd

+1 for namespaced attributes.

+1 on for full svg support in addons

+1000 for SVG attribute support :-)

+1 for supporting attributes

Request for adding attribute "fill-rule", maybe as "fillRule"

Would also like to see an SVG addon :+1:

React core team, is there any behind-the-scenes movement / discussion on this?

Not on this specifically, but #3718, #3763 are both SVG things being worked on and #3067 is also related to this attributes change.

+1 for full SVG support. Before it happens I will need a way to create custom tags and attributes. Can anyone please help me with that?

The marker element is also missing (https://developer.mozilla.org/en/docs/Web/SVG/Element/marker)

@ersagunkuruca try https://gist.github.com/akre54/80eaa63762ea499029f0 in the meantime

3945 These tags are not supported in React SVG for marker: refx, refy,orient

:+1: for Markers!

+1 for SVG all the things.

:+1

how about support for animateTransform properties

<path
    d="M120 60c0-31.13-26.86-60-60-60">
    <animateTransform
          attributeName="transform"
          type="rotate"
          from="0 60 60"
          to="360 60 60"
          dur="1.5s"
          repeatCount="indefinite" />
</path>

currently just ends up with

<path d="M120 60c0-31.13-26.86-60-60-60" data-reactid=".0.0.0.1.6.0.0.$0.0.0.2">
    <animateTransform type="rotate" data-reactid=".0.0.0.1.6.0.0.$0.0.0.2.0"></animateTransform>
</path>

+1 for image

+All SVG supported

+1 for filter

+1 for use support!

+1 for namespaced attributes

+1 for use and filter attributes support

+1 for <image> support. I need React to render an inline SVG that has an image inside a clipping path, and it's getting hung on the xmlns:xlink="http://www.w3.org/1999/xlink" attr in the <svg> tag.

+1 for filter

Considering @zpao's comment, should this issue be locked? Or at least, can we update the OP with that information? I'm subscribed to the thread for updates but @zpao's comment is buried (along with the fact that work has already been done) and it's kinda confusing for anybody who hasn't read the entire thread.

@zpao's comment explains the decision on why it is not currently built into react, but is there a better explanation on why an addon doesn't exist?
Is this something that can still be explored?

+1 for marker: refx, refy,orient

+1 for attributes of text : rotate, dominant-baseline

http://www.w3.org/TR/SVG/text.html#TextElementRotateAttribute

+1 addon

+1 addon

Actually React is in the process of being split into the core 'react' and the dom 'react-dom', and I'm guessing that's where 'react-svg' will finally come in

+1 for filter.

vector-effect attribute please

I think people requesting SVG tags/attributes when they happen to need them is a very poor model for React. It's silly that I have to use dangerouslySetInnerHTML just to render a working SVG on the page. That being said, here's some of the stuff missing:

_Tags:_

  • feMorphology
  • feOffset
  • feColorMatrix
  • feMerge
  • feMergeNode

_Attributes:_

  • filterUnits
  • stdDeviation
  • values
  • in
  • operator

and probably lots more in both categories. Those are just some from the specific SVG code I'm working with.

+1 for vector-effect

+1 for stdDeviation

+1 for a separate and complete React.SVG. I'm loving working with SVG in React so far, but the incompleteness of the support makes it a no go for any semi-complex application.

@spicyj has a plan to eliminate the need for a separate config we need to keep updating. Hopefully that will be complete soon. In the mean time, please hold tight.

+1 for animateTransform

+1 for dominate-baseline (#3199.)

Like @zpao said, we're going to fix this for good soon so any attributes can be used.

Locking this issue until then.

5714 was reverted in #6243, and thus we still require an attribute whitelist. The good news, however, is that #6243 contains attributes scraped for MDN so we expect it to cover 95% of the use cases. I read through this whole issue and linked issues and PRs and manually added two missing properties (focusable and vector-effect) in #6267. I expect these changes to land in v15.

Interestingly, I’m not sure whether the _tag_ whitelist is relevant anymore. So far I have been able to use <marker>, <textPath>, <feGaussianBlur> and other tags requested in this issue and in linked PRs without trouble on master. I see that fbjs still maintains an SVG tag whitelist and I don’t know the codebase well enough to say why tags missing from it worked for me today, so hopefully @zpao or @spicyj can clarify this, and whether we need to also add the missing tags there, to complement #6243.

I am unlocking this issue because the attribute whitelist is still relevant, but hopefully we will see a lot less requests now that most of the attributes that are both in the spec and are implemented by the browsers, are supported. If something still isn’t supported in the final v15, please let us know here.

This note does not apply to v15 RC1 which passes all SVG attributes through. We reverted this behavior in #6243 so please use the upcoming RC2, the master, or the final v15 to tell whether the attributes you are interested in are currently supported.

I noticed that there seems to be quite a lot of confusion about the xlink:href attribute. It _is_ currently supported but you would need to write it in a different way:

<use xlinkHref="#shape" x="50" y="50" />

React will correctly turn that into xlink:href, even in 0.14.x. See this fiddle for an example.

For my use case I needed React to recognize some filter elements like feFuncR, specifically their attributes (slope, intercept, etc). It appears to be fine in 15.0-rc2, but for 0.14.x I worked around it by adding these attributes to the dictionary exported by react/lib/SVGDOMPropertyConfig before first importing react / react-dom itself. Eg:

// Needed to set correct xmlns on <svg> and to preserve attributes on feFunc*.
// Required for 0.14.x. May become unnecessary with 15.x

var SVGDOMPropertyConfig = require("react/lib/SVGDOMPropertyConfig");

var DOMProperty = require("react/lib/DOMProperty");
var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;

SVGDOMPropertyConfig.Properties.in = MUST_USE_ATTRIBUTE;
SVGDOMPropertyConfig.Properties.intercept = MUST_USE_ATTRIBUTE;
SVGDOMPropertyConfig.Properties.slope = MUST_USE_ATTRIBUTE;
SVGDOMPropertyConfig.Properties.xmlns = MUST_USE_ATTRIBUTE;

var React = require("react");
var render = require("react-dom").render;

This is obviously a hack but I find it preferable to dangerouslySetInnerHTML

While this works it’s not an officially exposed API and may break in any minor or patch release. You can use it but on your own risk. If something is still missing please work with us so we add it. I’m glad to hear you don’t have issues with 15 RC2.

Yep, absolutely. I'm only using that until 15 comes out of RC status.

Pretty happy for the (almost) full SVG support in v15.0 but I'm realising that some namespaced attributes like xmlns and xmlnsXlink couldn't apply when render, and this is ok when showing the svg in the browser.

In case you want to create an .svg image those attributes are necessary.

ReactDOMServer.renderToStaticMarkup(<MyCustomSVG />)

So doing the code above, wont'n work.

Probably is related on the fact that:

...thanks to using document.createElement, we no longer need to maintain a list of SVG tags, so any SVG tags that were previously unsupported should work just fine in React 15

and not document.createElementNS.

and not document.createElementNS.

The blog post is a little too simplified, but createElementNS is used when we’re under an <svg> tag. If this doesn’t happen can you please file a separate issue describing the problem, with a JSFiddle that reproduces it? Thanks!

Thank you @gaearon. I think it does happen when render the svg in browser through ReactDOM. Probably the issue is related with ReactDOMServer.

Here is a pen that shows the rendered SVG and the code generated through renderToStaticMarkup() where is missing at least xmlNSand xmlnsXlink attrs.

If is the case I could file this issue separately.

Yea, xmlns and xmlns:Xlink are missing. https://github.com/facebook/react/pull/6471 has some in progress work to add it.

I still do not see <animate> and <animateTransform> in the list of supported tags. Is there a reason you chose not to support it?

@shilpan

All tags are supported now. The list only tells which tags are supported as React.DOM.* factory functions:

The following SVG elements are supported in React.DOM.*:

(emphasis mine)

If you use JSX, you don’t need to worry about this at all—writing <animate> and <animateTransform> will just work because JSX does not rely on React.DOM.* factories.

Even if you don’t use JSX, you can use React.createElement('animate', ...) which will work just fine, or create your own factory function: var animate = React.createFactory('animate").

+1 for adding support for xmlns.... In the mean time if anyone is interested in a workaround (which I needed to be able to support IE9-11) this is what I came up with:

// explicitly build the SVG to be rendered here so we don't lose the NS
const stringifiedSvg = `<svg xmlns="http://www.w3.org/2000/svg" class="svgClass">
                               <use xlink:href="#linkToSymbolId"></use>
                        <svg/>`

return <div dangerouslySetInnerHTML={{__html: stringifiedSvg}}/>
Was this page helpful?
0 / 5 - 0 ratings