Manipulate SVG with CSS and JavaScript DOM APIs

Scalable Vector Graphics (SVG) are XML-based text files representing two-dimensional vectors, which means their internal elements exist directly within the Document Object Model (DOM). Because they are standard DOM nodes, developers can dynamically alter SVG styles, attributes, and structural elements using standard CSS stylesheets and JavaScript DOM APIs. This guide outlines how to embed SVGs for DOM access, apply dynamic styling with CSS, and modify vector properties and structures programmatically using JavaScript.

Embedding SVG for DOM Access

To manipulate an SVG via CSS and JavaScript, the SVG code should ideally be embedded directly inline within the HTML document. While SVGs loaded via <img> tags are isolated for security reasons, inline <svg> elements reside in the same DOM tree as your HTML.

<svg id="vector-graphic" viewBox="0 0 100 100" width="100" height="100">
  <circle id="dynamic-circle" cx="50" cy="50" r="40" />
</svg>

Alternatively, if loading an external SVG via an <object> tag, you must access its internal document using the contentDocument property in JavaScript before manipulation.

Styling SVGs Dynamically with CSS

SVG elements support styling through external, internal, or inline CSS. Unlike standard HTML elements that use properties like background-color or border, SVG elements use vector-specific properties.

Common SVG CSS Properties

Example: CSS Transitions and Hover States

#dynamic-circle {
  fill: #3498db;
  stroke: #2980b9;
  stroke-width: 4px;
  transition: fill 0.3s ease, transform 0.3s ease;
  transform-origin: center;
}

#dynamic-circle:hover {
  fill: #e74c3c;
  transform: scale(1.1);
}

Manipulating SVGs with JavaScript DOM APIs

JavaScript can interact with SVG nodes using the standard DOM methods available for regular HTML elements, along with specialized SVG DOM interfaces.

1. Selecting and Modifying Attributes

You can select SVG elements using document.getElementById(), document.querySelector(), or similar methods. Use setAttribute() to modify vector attributes such as coordinates, dimensions, or paths.

const circle = document.getElementById('dynamic-circle');

// Change geometric attributes
circle.setAttribute('r', '25');
circle.setAttribute('cx', '60');

// Modify inline styles
circle.style.fill = '#2ecc71';

2. Creating New SVG Elements Dynamically

When creating new SVG elements via JavaScript, standard document.createElement() will not work properly because SVGs require a specific XML namespace. Use document.createElementNS() instead.

const svgNamespace = "http://www.w3.org/2000/svg";
const svg = document.getElementById('vector-graphic');

// Create a new rectangle element
const rect = document.createElementNS(svgNamespace, 'rect');
rect.setAttribute('x', '10');
rect.setAttribute('y', '10');
rect.setAttribute('width', '30');
rect.setAttribute('height', '30');
rect.setAttribute('fill', '#f1c40f');

// Append to the SVG container
svg.appendChild(rect);

3. Path Manipulation and SVG-Specific Methods

SVG elements implement specialized interfaces such as SVGPathElement or SVGGeometryElement, providing built-in methods for complex geometry calculations:

const path = document.querySelector('path');
const pathLength = path.getTotalLength();

// Set up a stroke-drawing animation via JavaScript
path.style.strokeDasharray = pathLength;
path.style.strokeDashoffset = pathLength;

// Animate stroke drawing
path.animate([
  { strokeDashoffset: pathLength },
  { strokeDashoffset: 0 }
], {
  duration: 2000,
  fill: 'forwards'
});

4. Handling User Interactivity

SVG elements can dispatch standard DOM events such as click, pointerdown, mouseover, and touchstart.

const circle = document.getElementById('dynamic-circle');

circle.addEventListener('click', (event) => {
  const currentRadius = parseFloat(circle.getAttribute('r'));
  circle.setAttribute('r', currentRadius + 5);
});