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
fill: Sets the interior color of shapes and text.stroke: Sets the outline color.stroke-width: Controls the thickness of the outline.stroke-dasharrayandstroke-dashoffset: Used for creating dashed lines and path-drawing animations.transform: Scales, rotates, translates, or skews vector shapes.
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:
getTotalLength(): Returns the total length of a<path>in user units.getPointAtLength(distance): Returns the(x, y)coordinate at a specific distance along a path.
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);
});