Search code examples
javascriptsvgappendchildcreateelement

createElement() failing to work on basic path element


First, below is the desired result without any JavaScript added

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
html, body {
  height: 100%;
}
body {
  display: flex;
  justify-content: center;
  align-items: center;
}
svg {
  transform: scale( 2 );
  border-radius: 0.25rem;
  width: 100px;
  height: 100px;
  background-color: rgba( 95%,95%,95%,0.5 );
  fill: #444;
}
<svg>
  <path 
    d=
      "
       M10 50
       C20 30, 40 30, 50 50
       C60 70, 80 70, 90 50
      "
   ></path>
</svg>

Notice the svg and path elements and the values of the d attribute. Everything works perfectly in the snippet above.

In the snippet below, however, we don't have the path element yet created so we're trying to insert it with JavaScript. In the completed program the d attribute will be filled with dynamic values.

Why doesn't the path element show up?

const svg = document.querySelector( `svg` ),
      path = document.createElement( `path` );

path.setAttribute(
  `d`,
  `
   M10 50
   C20 30, 40 30, 50 50
   C60 70, 80 70, 90 50  
  `
)

svg.appendChild( path );
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
html, body {
  height: 100%;
}
body {
  display: flex;
  justify-content: center;
  align-items: center;
}
svg {
  transform: scale( 2 );
  border-radius: 0.25rem;
  width: 100px;
  height: 100px;
  background-color: rgba( 95%,95%,95%,0.5 );
  fill: #444;
}
<svg></svg>

What's more confusing is upon inspection we can see the browser appears to have correctly added the element:

enter image description here

How do we get the path element to correctly appear in the page using JavaScript?


Solution

  • Use createElementNS with the SVG namespace http://www.w3.org/2000/svg:

    const svg = document.querySelector( `svg` ),
          path = document.createElementNS('http://www.w3.org/2000/svg', `path` );
    
    path.setAttribute(
      `d`,
      `
       M10 50
       C20 30, 40 30, 50 50
       C60 70, 80 70, 90 50  
      `
    )
    
    svg.appendChild( path );
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    html, body {
      height: 100%;
    }
    body {
      display: flex;
      justify-content: center;
      align-items: center;
    }
    svg {
      transform: scale( 2 );
      border-radius: 0.25rem;
      width: 100px;
      height: 100px;
      background-color: rgba( 95%,95%,95%,0.5 );
      fill: #444;
    }
    <svg></svg>