Working with Assets¶
Table of Contents¶
SVG Graphics¶
SVG (Scalable Vector Graphics) are ideal for icons, logos, and graphics that need to scale without losing quality.
Why Use SVG?¶
- Scalable: Looks sharp at any size
- Small file size: Especially for simple graphics
- Manipulatable: Can be styled with CSS
- Accessible: Can include semantic markup
- Animatable: CSS and JavaScript animations work seamlessly
Using SVG in WordPress Themes¶
Method 1: Inline SVG (Recommended)¶
Inline SVGs give you the most control and allow CSS styling:
<svg class="icon icon--arrow" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 12h14M12 5l7 7-7 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Advantages:
- Can be styled with CSS (color, size, etc.)
- No additional HTTP request
- Inherits text color with currentColor
Best practices:
- Use currentColor for stroke/fill to inherit text color
- Add appropriate class names for styling
- Include aria-label or aria-hidden="true" for accessibility
- Optimize SVGs before inline use (remove unnecessary attributes)
Method 2: SVG as Image¶
<img src="<?php echo get_template_directory_uri(); ?>/dist/images/logo.svg" alt="Company Logo" class="logo">
Use when: - You don't need to style the SVG with CSS - The SVG is complex and would clutter the HTML - You want browser caching
Method 3: SVG Sprite¶
For multiple icons used throughout the site:
- Create an SVG sprite file (
sprite.svg):
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="icon-arrow" viewBox="0 0 24 24">
<path d="M5 12h14M12 5l7 7-7 7"/>
</symbol>
<symbol id="icon-close" viewBox="0 0 24 24">
<path d="M18 6L6 18M6 6l12 12"/>
</symbol>
</svg>
- Include it in your theme (footer or inline in header):
- Use icons with
<use>:
SVG Optimization¶
Always optimize SVGs before adding them to your theme:
Using SVGO (CLI tool):
Using online tools: - SVGOMG - Web interface for SVGO
What optimization does: - Removes editor metadata - Removes unnecessary attributes - Simplifies paths - Reduces file size by 30-70%
Example: Icon Component¶
Create a reusable icon component in your theme:
template-parts/icon.php:
<?php
/**
* Icon component
*
* @param string $icon Icon name
* @param string $class Additional CSS classes
* @param int $size Icon size in pixels
*/
$icon = $args['icon'] ?? 'arrow';
$class = $args['class'] ?? '';
$size = $args['size'] ?? 24;
?>
<svg class="icon icon--<?php echo esc_attr($icon); ?> <?php echo esc_attr($class); ?>"
width="<?php echo esc_attr($size); ?>"
height="<?php echo esc_attr($size); ?>"
aria-hidden="true">
<use xlink:href="#icon-<?php echo esc_attr($icon); ?>"></use>
</svg>
Usage:
CSS Styling for SVG¶
.icon {
display: inline-block;
vertical-align: middle;
fill: currentColor;
stroke: currentColor;
&--arrow {
fill: none;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
&--large {
width: 48px;
height: 48px;
}
}
// SVG hover effects
.button {
.icon {
transition: transform 0.2s ease;
}
&:hover .icon {
transform: translateX(4px);
}
}

Images and Media¶
Image Formats¶
Choose the right format for your use case:
| Format | Best For | Pros | Cons |
|---|---|---|---|
| JPG | Photos, complex images | Small file size, good compression | No transparency, lossy |
| PNG | Graphics with transparency, logos | Lossless, supports transparency | Larger file size |
| WebP | Modern web images | Smaller than JPG/PNG, supports transparency | Limited older browser support |
| SVG | Icons, logos, simple graphics | Infinitely scalable, tiny file size | Not suitable for photos |
| GIF | Simple animations | Universal support | Limited colors, large file size |
WordPress Image Sizes¶
WordPress automatically creates multiple image sizes when you upload. Define custom sizes in functions.php:
// Add custom image sizes
add_theme_support('post-thumbnails');
add_image_size('thumbnail-small', 150, 150, true); // Hard crop
add_image_size('featured-large', 1200, 600, false); // Soft crop
add_image_size('hero', 1920, 1080, true);
Use them in templates:
<?php
the_post_thumbnail('featured-large', [
'class' => 'featured-image',
'alt' => get_the_title(),
]);
?>
Responsive Images¶
WordPress automatically generates responsive images with srcset:
Output:
<img src="image-1024x768.jpg"
srcset="image-300x225.jpg 300w,
image-768x576.jpg 768w,
image-1024x768.jpg 1024w"
sizes="(max-width: 1024px) 100vw, 1024px"
alt="Example">
Manual responsive images:
<?php
$image_id = get_post_thumbnail_id();
echo wp_get_attachment_image($image_id, 'large', false, [
'class' => 'hero__image',
'loading' => 'lazy',
]);
?>
Lazy Loading¶
WordPress 5.5+ includes native lazy loading:
For older WordPress versions or custom implementation:
Image Optimization¶
1. Optimize before upload: - Use tools like ImageOptim (Mac) or TinyPNG - Aim for JPG quality 80-85% - Compress PNGs with tools like pngquant
2. WordPress plugins: - Imagify - Automatic compression - ShortPixel - Compression with WebP support - EWWW Image Optimizer - Local compression
3. Serve next-gen formats:
<picture>
<source srcset="image.webp" type="image/webp">
<source srcset="image.jpg" type="image/jpeg">
<img src="image.jpg" alt="Fallback">
</picture>
Getting Image Data in ACF¶
When using Advanced Custom Fields:
<?php
$image = get_field('hero_image');
if ($image) {
// Image array contains:
// $image['id']
// $image['url']
// $image['alt']
// $image['title']
// $image['sizes']['thumbnail']
// etc.
echo wp_get_attachment_image($image['id'], 'large', false, [
'class' => 'hero__image',
'alt' => $image['alt'],
]);
}
?>
Get specific size:
<?php
$image = get_field('hero_image');
if ($image) {
echo '<img src="' . esc_url($image['sizes']['large']) . '" alt="' . esc_attr($image['alt']) . '">';
}
?>
Background Images¶
For CSS background images with responsive images:
<?php
$image_id = get_post_thumbnail_id();
$image_url = wp_get_attachment_image_url($image_id, 'full');
?>
<div class="hero" style="background-image: url('<?php echo esc_url($image_url); ?>')">
<!-- Content -->
</div>
Better approach with CSS:
// Set background images from data attributes
document.querySelectorAll('[data-bg]').forEach(el => {
el.style.backgroundImage = `url(${el.dataset.bg})`;
});
Image Accessibility¶
Always include proper alt attributes:
<?php
// Good: Descriptive alt text
echo wp_get_attachment_image($image_id, 'large', false, [
'alt' => 'Team meeting at Lemone office in Amsterdam'
]);
// Decorative images: empty alt
echo wp_get_attachment_image($image_id, 'large', false, [
'alt' => '',
'role' => 'presentation'
]);
?>
Alt text best practices:
- Be descriptive but concise
- Don't start with "Image of..." or "Picture of..."
- For decorative images, use empty alt (alt="")
- For complex images (charts, diagrams), provide longer description
Performance Tips¶
- Use appropriate sizes: Don't load 4K images for thumbnails
- Lazy load off-screen images: Improves initial page load
- Use CDN: Serve images from CDN for faster delivery
- Limit image dimensions: Max 1920px width for full-width images
- Compress aggressively: 80-85% JPG quality is usually sufficient
- Use WebP: Smaller file sizes with same quality
- Preload critical images: For above-the-fold hero images
See Also¶
- CSS/SCSS Guidelines - Styling assets and components
- WordPress Development - WordPress theme development
- Linting Setup - Code quality tools