Customize the taskbar with themes contributed by others or create your own.
Also check out the Windows 11 Start Menu Styler, Windows 11 Notification Center Styler mods.
Themes are collections of styles. The following themes are integrated into the mod and can be selected in the settings:
More themes can be found in the Themes section of The Windows 11 taskbar styling guide. Contributions of new themes are welcome!
Aside from themes, the settings have two sections: control styles and resource variables. Control styles allow to override styles, such as size and color, for the target elements. Resource variables allow to override predefined variables. For a more detailed explanation and examples, refer to the sections below.
The taskbar's XAML resources can help find out which elements and resource variables can be customized. To the best of my knowledge, there are no public tools that are able to decode the resource files of recent Windows versions, but here are XAML resources which were obtained via other means for your convenience: TaskbarResources.xbf and SystemTrayResources.xbf.
The UWPSpy tool can be used to inspect the taskbar's control elements in real time, and experiment with various styles.
For a collection of commonly requested taskbar styling customizations, check out The Windows 11 taskbar styling guide.
Each entry has a target control and a list of styles.
The target control is written as Class or Class#Name, i.e. the target
control class name (the tag name in XAML resource files), such as
Taskbar.TaskListButton or Rectangle, optionally followed by # and the
target control's name (x:Name attribute in XAML resource files). The target
control can also include:
Class#Name[2] will only match the relevant
control that's also the second child among all of its parent's child controls.Class#Name[Property1=Value1][Property2=Value2].>, for example: ParentClass#ParentName > Class#Name.* between two > separators to match any number of intermediate parent
controls, for example: ParentClass > * > Class#Name matches Class#Name
when ParentClass is any of its ancestors (with zero or more controls in
between). * must be in the middle of the target (not the leftmost or
rightmost part), and consecutive * are not allowed.:root as the leftmost target part to require that the next part has no
parent, i.e., it's a root element. For example: :root > Class#Name matches
Class#Name only when it has no parent control. :root must be followed by a
non-* target part.Class#Name@VisualStateGroupName. It
can be specified for the target control or for a parent control, but can be
specified only once per target. The visual state group can be used in styles
as specified below.Several target controls can be specified for the same styles by separating them
with commas, for example: ParentClass > Class#Name1, ParentClass > Class#Name2. Commas inside [...] are part of the property value and don't
separate targets, for example: Class[Margin=0,0,0,1] is a single target.
Note: The target is evaluated only once. If, for example, the index or the properties of a control change, the target conditions aren't evaluated again.
Each style is written as Style=Value, for example: Height=5. The := syntax
can be used to use XAML syntax, for example: Fill:=<SolidColorBrush Color="Red"/>. Specifying an empty value with the XAML syntax will clear the
property value, for example: Fill:=. In addition, a visual state can be
specified as following: Style@VisualState=Value, in which case the style will
only apply when the visual state group specified in the target matches the
specified visual state.
For the XAML syntax, in addition to the built-in taskbar objects, the mod
provides a built-in blur brush via the WindhawkBlur object, which supports the
BlurAmount, TintColor, TintOpacity, TintLuminosityOpacity,
TintSaturation, NoiseOpacity, NoiseDensity, and FallbackColor
properties. For example: Fill:=<WindhawkBlur BlurAmount="10" TintColor="#80FF00FF"/>. Theme resources are also supported for TintColor and
FallbackColor, for example: Fill:=<WindhawkBlur BlurAmount="18" TintColor="{ThemeResource SystemAccentColorDark1}" TintOpacity="0.5"/>. The
FallbackColor is used in place of the blur effect when battery saver is on or
when transparency effects are disabled in the system settings.
Targets and styles starting with two slashes (//) are ignored. This can be
useful for temporarily disabling a target or style.
A couple of practical examples:

Taskbar.TaskListButtonCornerRadius=0
Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Rectangle#RunningIndicatorFill=#FFED7014Height=2Width=12Fill@ActiveRunningIndicator=RedWidth@ActiveRunningIndicator=20
Taskbar.TaskListButtonPanel > Border#BackgroundElementTaskbar.TaskListLabeledButtonPanel > Border#BackgroundElementBackground:=<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"><GradientStop Offset="0" Color="DodgerBlue"/><GradientStop Offset="1" Color="Yellow"/></LinearGradientBrush>Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton]Visibility=CollapsedSystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter[1] > SystemTray.IconView > Grid > GridVisibility=CollapsedNote: To hide the volume notification icon instead, use [2] instead of
[1].
Beyond literal values, XAML values, and style constants, styles can reference
live property values via style variables. A capture rule of the form
Property=>VarName observes a control's property and publishes its value as
VarName; other styles then substitute it with {{VarName}}. Whenever the
captured value changes or the variable becomes undefined, every dependent style
is recomputed and reapplied.
Capture rules cannot be combined with := or with the per-rule @VisualState
qualifier.
For example, these two styles on the same target keep it square, with the height tracking the width:
ActualWidth=>width1
Height={{width1}}
A capture rule may match several controls at once. A style reading {{VarName}}
gets the value from whichever capturing control is closest to it in the control
tree, i.e. the one it shares the deepest common parent with; between equally
close controls, the one that appeared last wins. The variable only becomes
undefined once the last capturing control is gone.
A substitution can appear anywhere in a value, including alongside literal text:
Margin=0,{{x1}},0,{{x2 + 10}}
Inside {{ ... }}, the supported expression syntax is:
42, 3.14).`Auto`, `*`), where a
doubled backtick encodes one literal backtick. Backtick is used rather than a
quote so literals don't clash with YAML or XAML quoting.VarName).+, -, *, / with standard precedence, and unary +, -.<, <=, ==, >=, >, !=, evaluating to 1 or 0. The
relational operators require numbers; == and != compare two numbers or two
strings by value and treat a number-versus-string mismatch as unequal.cond ? a : b: a when cond is non-zero, otherwise b.
The condition must be numeric, but each branch may be a number or a string,
e.g. {{width > 0 ? `*` : `Auto`}} selects a GridLength keyword.min(a, b) and max(a, b).skip(): leaves the style unapplied, so the property keeps (or returns to)
its original value, e.g. {{width > 0 ? width : skip()}} applies only once
width is positive.{{min(a, b + 1) * 2}}.Arithmetic, the unary sign, the relational comparisons, and min / max
require numeric operands. A string can only be produced by a literal or a
string-typed variable, compared with == / !=, and selected by the
conditional.
Brace pairs match innermost-first, so {{{x}}} is parsed as a literal {, the
substitution {{x}}, and a literal }, producing {<value-of-x>}.
A bare substitution {{VarName}} (with no operators) inserts the variable's
captured value verbatim. This works only for primitive captured types (numeric,
boolean, string); other types (brushes, thicknesses, etc.) are unsupported, and
substituting one skips the style, as does a bare reference to an undefined
variable.
Inside an expression, an undefined variable instead evaluates to the empty
string, letting a style supply its own default via the conditional, e.g. {{width == `` ? 80 : width}} yields 80 until width is captured. The
numeric operators above then fail on such a variable, skipping the style rather
than treating it as 0.
Some variables, such as size and padding for various controls, colors, and brushes, are defined as resource variables. You can override existing resources or define new theme-aware resources.
Use key=value to override an existing resource, for example:
TaskbarContextMenuMargin=4: The margin between the taskbar and the start
button context menu.
ContextMenuMargin=8: The margin between the taskbar and the tray area
context menu.
MediumTaskbarButtonExtent=48: The width of the taskbar buttons.
Use Key@Dark=value and Key@Light=value to define new resources with
different values for dark and light themes. These can then be referenced in
styles using {ThemeResource key}.
For example, to define a custom accent color that automatically adjusts based on the system theme:
AutoAccent@Dark={ThemeResource SystemAccentColorDark1}
AutoAccent@Light={ThemeResource SystemAccentColorLight2}
Then use it in a style:
Background:=<SolidColorBrush Color="{ThemeResource AutoAccent}" />
The value will automatically update when the system accent color changes.
The := syntax can be used to set a XAML value as a resource, for example:
MyBrush:=<SolidColorBrush Color="Red"/>. This can be combined with theme
variants: MyBrush@Dark:=<SolidColorBrush Color="#FF202020"/>. Specifying an
empty value with the XAML syntax will clear the resource value, for example:
MyBrush:=.
Style constants allow defining a value once and referencing it in multiple
styles. Each entry contains a name and value, separated by =, for example:
mainColor=#fafad2
The constant can then be used in style definitions by prepending $, for
example:
Fill=$mainColor
Background:=<AcrylicBrush TintColor="$mainColor" TintOpacity="0.3" />
Some themes use style constants to allow easy customization. Refer to the theme page for details on which constants are available.
This mod uses XAML diagnostics to inspect and customize the taskbar. However, there can only be one XAML diagnostics consumer at a time. If another program (such as ExplorerBlurMica or TranslucentTB) tries to use XAML diagnostics while this mod is running, there will be a conflict.
The XAML diagnostics consumer handling setting controls how this mod handles such conflicts:
The VisualTreeWatcher implementation is based on the ExplorerTAP code from the TranslucentTB project.
The WindhawkBlur brush object implementation is based on
XamlBlurBrush
from the TranslucentTB project.