You don't need to dig into $variables['element']
. In a block preprocess function, the content of the block is available in $variables['content']
, so you could use the following code.
$variables['content']['site_logo']['#attributes']['class'][] = 'svg';
Edit:
Altough this is generally valid for blocks, it doesn't work for the system branding block. The branding block overrides the block template with block--system-branding-block.html.twig, where the output of {{ content }}
is removed, which breaks the normal rendering of the block. Instead the template contains the html markup for the <img>
tag directly:
{% extends "block.html.twig" %}
{#
/**
* @file
* Theme override for a branding block.
*
* Each branding element variable (logo, name, slogan) is only available if
* enabled in the block configuration.
*
* Available variables:
* - site_logo: Logo for site as defined in Appearance or theme settings.
* - site_name: Name for site as defined in Site information settings.
* - site_slogan: Slogan for site as defined in Site information settings.
*/
#}
{% block content %}
{% if site_logo %}
<a href="{{ path('<front>') }}" title="{{ 'Home'|t }}" rel="home">
<img src="{{ site_logo }}" alt="{{ 'Home'|t }}" />
</a>
{% endif %}
{% if site_name %}
<a href="{{ path('<front>') }}" title="{{ 'Home'|t }}" rel="home">{{ site_name }}</a>
{% endif %}
{{ site_slogan }}
{% endblock %}
To reinstate the correct behavior you could override block--system-branding-block.html.twig in your theme and replace the <img>
markup with the render array:
{{ content.site_logo }}
Then the changes made in preprocess are effective again.
Or simply go along with the template as it is now and add the attributes to the html markup of the template.