--activeButton CSS Variable
Vivaldi has a few general purpose CSS variables that can be used to manipulate the appearance of icons. One of these variables is the --activeButton variable, which is set on each panel toolbar button to indicate if the panel associated with the button is open. When a panel isn't open, --activeButton has a value of 0, and when it is, the value is 1.
Direct usage of the variable
On its own, the variable can be used to control things directly, like with opacity: var(--activeButton); or transform: scale(var(--activeButton)); which can be applied in the style="" attributes of SVG elements like paths, where a value of 0 will make the object disappear and 1 will make it show up again. This can either be an instantaneous change, or you can pair it with a transition to give it an animated appearance. More info on transition here: https://developer.mozilla.org/en-US/docs/Web/CSS/transition
If you use transform: scale(var(--activeButton)); with a transition, you might notice the SVG element scaling up in an odd way that is relative to the top left corner of the icon. This happens because the scale is relative to the origin of the SVG, which is the top left corner by default. Luckily, you can adjust the position of the origin if the default behavior isn't what you are looking for with the property transform-origin. For a centered element, transform-origin: center; can be used, but you can also set specific x and y coordinates if necessary. More info on transform-origin here: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin
Sometimes it can also be necessary to have the opposite behavior of simply putting the --activeButton variable into a CSS property. For example, if you wanted an SVG element to disappear when a panel button is activated, then you couldn't use the variable on its own. In such cases, you can easily invert the variable and set a new variable to hold it like so: --activeButtonInverse: calc(1 - var(--activeButton));. Then using something like opacity: var(--activeButtonInverse); will let you accomplish your goal. If you are going to use the inverted variable for multiple elements, then it makes sense to set the variable definition on a parent group element, <g>, or even on the main <svg> element, so you don't need to repeat the inverted variable definition in the style="" attribute of each element that requires it.
Using the variable with calc() for greater control
CSS has many numerical properties that can be manipulated but have ranges that fall outside of the range between 0 and 1, so for the --activeButton variable to be useful with these properties, you need to use it within calc()s which allows you to use mathematical operators on the contents of the calc().
Say you want to have a part of the icon move from the top of the icon to the bottom when the panel button is activated. To accomplish this, you would use transform: translateY();, but since SVG icons are suggested to fit in a 16x16 pixel area of a 28x28 pixel icon, you won't be able to move the icon element the entire distance without increasing the effect of the --activeButton variable like so: transform: translateY(calc(16px * var(--activeButton)));. So when the panel button isn't active (--activeButton is 0) the calc() will return 0px and not move the element, but once the button is activated and the variable is 1, the element will be moved 16px down in the icon.
Using the calc() also allows you to convert the unitless variable into a pixel value by including the px on the multiplication factor. Depending on the CSS attribute you are manipulating, a unit of measurement or percentage value might be required.
Another way you could use calc() with --activeButton is to provide a slight icon size increase to help indicate that the panel button is active. This could be accomplished with something like this: style="transform-origin: center; transform: scale(calc(0.2 * var(--activeButton) + 1)); transition: transform 0.1s ease-in;". This way, the scale will default to 1 when on an inactive panel button and increase to 1.2 times larger for an active one.
Changing icon color with --activeButton
Vivaldi suggests using the option currentColor for all fills and strokes in SVG icons to better allow the icon set to match the theme it is paired with, but when trying to indicate that a button is active, it can be beneficial to change the color from the normal white or black Foreground color to something more distinctive.
By default, when you activate a panel button, it gets a bar along the side that uses your theme's Highlight color, so you might want to change the icon color to match. You can get the theme Highlight color with the CSS variable var(--colorHighlightBg), but you can't use a calc() alone to toggle between between 2 non-numerical values. That is where color-mix() can be useful. If you use something like this on the top level <svg> tag: style="color: color-mix(in srgb, var(--colorHighlightBg) calc(var(--activeButton) * 100%), currentcolor);", then you can control what ratio of the Highlight color and the Foreground (currentcolor) are mixed together to result in the final used color. By toggling between 0% and 100% of the Highlight color ratio, you can completely swap the color without any mixing. More info on color-mix() here: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-mix
Example: History Panel icon with animated active indicator
Preview:
history-retro.gif
Final SVG:
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="none" viewBox="0 0 28 28"
style="--activeButtonInverse: calc(1 - var(--activeButton));">
<path id="history-icon-blob-1" fill="#b193f0"
style="transform: translateX(calc(-22px * var(--activeButtonInverse))); opacity: var(--activeButton); transition: 0.5s;"
d="M8.83 24.72c9.97.79 14.37-7.1 11.77-13.82C17.2 2.13.32-1.47 2.84 7.3c1.69 5.9-.13 16.94 5.99 17.42Z" />
<path id="history-icon-blob-2" fill="#ffd75a"
style="transform: translateX(calc(26px * var(--activeButtonInverse))); opacity: var(--activeButton); transition: 0.5s;"
d="M12.38 9.66c-18.1 1.38-10.38 8.21.72 12.12 9.26 3.26 11.92-1.24 12.35-7.01C26.68-1.8 20.8 9 12.38 9.66Z" />
<path id="history-icon-star-1" fill="#fff"
style="transform-origin: 20.4px 5.4px; transform: scale(var(--activeButton)); opacity: var(--activeButton); transition: 0.3s; transition-delay: 0.2s;"
d="M20.45 2.2a3.2 3.2 0 0 1-3.2 3.2 3.2 3.2 0 0 1 3.2 3.2 3.2 3.2 0 0 1 3.2-3.2 3.2 3.2 0 0 1-3.2-3.2z" />
<path id="history-icon-star-2" fill="#fff"
style="transform-origin: 8.8px 23.5px; transform: scale(var(--activeButton)); opacity: var(--activeButton); transition: 0.3s; transition-delay: 0.4s;"
d="M8.92 20.32a3.2 3.2 0 0 1-3.2 3.2 3.2 3.2 0 0 1 3.2 3.2 3.2 3.2 0 0 1 3.2-3.2 3.2 3.2 0 0 1-3.2-3.2z" />
<g>
<path fill="#fff" stroke="#fff" stroke-width=".5"
d="m10.006 8.077.991 1.712a6.545 4.55 13.88 0 1 .338-.078l-.913-1.589Zm3.965.35v1.17a6.545 4.55 13.88 0 1 .338.046V8.46Zm3.537.315-.901 1.566a6.545 4.55 13.88 0 1 .304.135l.969-1.667Zm-11.085 1.51-.168.292 1.903 1.104a6.545 4.55 13.88 0 1 .203-.282zm15.433 0-2.839 1.644a6.545 4.55 13.88 0 1 .237.248l2.782-1.6-.169-.293zm-15.68 4.483.022.338h1.803a6.545 4.55 13.88 0 1-.136-.338Zm14.328 0a6.545 4.55 13.88 0 1 0 .338h1.352l.034-.338zM9.837 17.202l-3.312 1.915a1.352 1.352 0 0 0 .169.292l3.447-1.993a6.545 4.55 13.88 0 1-.304-.214Zm9.394.439a6.545 4.55 13.88 0 1-.292.225l2.534 1.465a1.318 1.318 0 0 0 .079-.338zm-7.265.71-.969 1.678h.394l.901-1.566a6.545 4.55 13.88 0 1-.326-.112zm4.63.45a6.545 4.55 13.88 0 1-.35.056l.733 1.285h.394zm-2.614.045v1.24h.338V18.89a6.545 4.55 13.88 0 1-.338-.045z" />
<path stroke="#fd7100" stroke-width="1.126"
d="m6.942 7.807 14.137 1.25a1.25 1.25 0 0 1 1.138 1.352l-.676 8.572a1.318 1.318 0 0 1-1.34 1.217l-12.46-.225a1.352 1.352 0 0 1-1.318-1.262l-.642-9.778a1.059 1.059 0 0 1 1.16-1.126Z" />
<path fill="#f30000" d="m16.834 12.574-.546.14-2.42 1.876-.107 1.066 1.066-.11 1.87-2.425z" />
<path fill="#f30000" d="m10.51 11.82.183.531 3.21 3.23 1.072.02-.196-1.053-3.713-2.636z" />
</g>
</svg>
Design Notes:
(WIP)...