Custom Snippet: Automatically Add Width and Height to SVG Images in Kadence Bloc
-
Hi Kadence community,
Kadence Blocks does a great job handling most image types, but I’ve noticed that when SVG files are inserted (e.g., via the Advanced Image block or other modules), the generated
<img>tags do not includewidthandheightattributes. This can lead to layout shifts (CLS issues) because browsers can’t reserve space for the image until the SVG is loaded and its intrinsic dimensions are known.To solve this, I’ve created a small PHP function that hooks into
the_contentfilter. It detects<img>tags with.svgsources, reads the SVG file’sviewBoxattribute to determine the aspect ratio, calculates appropriate dimensions that fit within a 300×300 px box while preserving the ratio, and adds fixedwidthandheightattributes. If the SVG has noviewBox, the tag is left unchanged.The function is optimized for performance:
- Works only on frontend
- Reads local SVG files directly from disk (no HTTP overhead)
- Caches calculated dimensions using transients (perfect if you have object caching like Redis)
- Strictly limited to local files and includes size safeguards
Here’s the complete code you can add to your child theme’s
functions.php(or a site-specific plugin):function kadence_svg_add_fixed_dimensions( $content ) {
if ( is_admin() ) {
return $content;
}
preg_match_all( '/<img([^>]*)src=[\'"]([^\'"]*\.svg)[\'"]([^>]*)>/i', $content, $matches, PREG_SET_ORDER );
if ( empty( $matches ) ) {
return $content;
}
foreach ( $matches as $match ) {
$full_tag = $match[0];
$before_src = $match[1];
$src = $match[2];
$after_src = $match[3];
// Build full URL
$svg_url = $src;
if ( ! preg_match( '/^https?:\/\//i', $src ) ) {
$svg_url = site_url( $src );
}
// Only local files
if ( strpos( $svg_url, home_url() ) !== 0 ) {
continue;
}
// Convert URL to file path
$upload_dir = wp_get_upload_dir();
$base_url = trailingslashit( $upload_dir['baseurl'] );
$base_dir = trailingslashit( $upload_dir['basedir'] );
if ( strpos( $svg_url, $base_url ) === 0 ) {
$file_path = $base_dir . substr( $svg_url, strlen( $base_url ) );
} else {
$file_path = ABSPATH . ltrim( parse_url( $svg_url, PHP_URL_PATH ), '/' );
}
// Cache key based on file path
$cache_key = 'kadence_svg_dims_' . md5( $file_path );
$dimensions = get_transient( $cache_key );
if ( false === $dimensions && file_exists( $file_path ) ) {
$svg_content = file_get_contents( $file_path );
// Safety: limit file size
if ( strlen( $svg_content ) > 100 * 1024 ) {
continue;
}
if ( preg_match( '/viewBox=[\'"]([^\'"]*)[\'"]/', $svg_content, $vb_match ) ) {
$viewbox = trim( $vb_match[1] );
$parts = preg_split( '/\s+/', $viewbox );
if ( count( $parts ) === 4 ) {
$vb_width = floatval( $parts[2] );
$vb_height = floatval( $parts[3] );
if ( $vb_width > 0 && $vb_height > 0 ) {
$aspect_ratio = $vb_width / $vb_height;
$max = 300;
if ( $aspect_ratio > 1 ) {
$new_width = $max;
$new_height = round( $max / $aspect_ratio );
} elseif ( $aspect_ratio < 1 ) {
$new_height = $max;
$new_width = round( $max * $aspect_ratio );
} else {
$new_width = $new_height = $max;
}
$dimensions = array( $new_width, $new_height );
set_transient( $cache_key, $dimensions, MONTH_IN_SECONDS );
}
}
}
}
if ( ! $dimensions ) {
continue;
}
list( $new_width, $new_height ) = $dimensions;
// Remove any existing width/height attributes
$attributes = $before_src . $after_src;
$attributes = preg_replace( '/\s+width=[\'"][^\'"]*[\'"]/', '', $attributes );
$attributes = preg_replace( '/\s+height=[\'"][^\'"]*[\'"]/', '', $attributes );
// Build new tag
$new_tag = '<img' . $attributes . ' src="' . esc_attr( $src ) . '" width="' . $new_width . '" height="' . $new_height . '">';
$content = str_replace( $full_tag, $new_tag, $content );
}
return $content;
}
add_filter( 'the_content', 'kadence_svg_add_fixed_dimensions', 99 );Feel free to adjust the
$max = 300;value if you want a different maximum size.This has worked perfectly on my private site with Kadence Blocks and eliminates layout shifts for SVGs. Hope it helps someone else too!
If the Kadence team sees this – it would be awesome to have native width/height support for SVGs in a future update. 😊
Thanks!
You must be logged in to reply to this topic.