Home Assistant Dashboard Evolution: Streamlined & Stunning in 2025
Visual Clarity & Performance Boost: A Year of Dashboard Evolution with Streamline Card and Bubble Card

Remember last year when I was all excited about crafting my “perfect” Home Assistant dashboard? Man, time flies! It’s been a year, and like any good smart home setup, mine has evolved quite a bit. My dashboard? Totally different beast now.
If you caught my previous post, “Crafting My Perfect Home Assistant Dashboard,” you know I’m all about a dashboard that’s not just functional, but also looks slick and gives me the info I need at a glance. Well, get ready, because things have gotten even better!
This time around, I want to show you how I’ve really streamlined things (pun intended!), ditching some plugins and focusing on making my dashboard even cleaner and more powerful, all thanks to my own little project: Streamline Card.
Plugin Diet: Slimming Down for Speed and Style
Last year, I was juggling a bunch of plugins to get the look and feel I wanted. It worked, but it felt a bit…clunky. Let’s see what’s changed in my plugin toolbox:
Bubble Card: Still My Ride or Die
The Bubble Card plugin for Home Assistant
Seriously, Bubble Card is still the MVP of my dashboard. It’s just so versatile and customizable, it can handle anything I throw at it. If you’re building a custom dashboard, Bubble Card is still my number one pick, hands down. And honestly, after a year of even more Home Assistant updates and dashboard tinkering, I’m even more convinced!
What makes Bubble Card so incredible? Let’s break it down:
- Unmatched Entity Support: Bubble Card isn’t just limited to a few basic entity types — it handles a massive range of Home Assistant entities. Whether you want to display simple sensor readings, control complex media players, manage climate settings, or visualize data from custom integrations, Bubble Card has you covered. It truly feels like it can display any entity you throw at it, making it the central hub for visualizing your entire smart home.
- Style it Your Way (with JavaScript Power!): Customization is king with Bubble Card. You have granular control over every visual aspect, from fonts and colors to spacing and animations. But what truly elevates the styling is JavaScript integration. You can use JavaScript directly within your card style configuration to dynamically adjust styles based on entity states, variables, or even external conditions. Want a button to change color based on the temperature? JavaScript styling makes it possible to create truly adaptive and visually intelligent cards. This power to combine CSS-like styling with JavaScript logic is what lets you perfectly tailor your cards to your exact aesthetic and functional needs.
- The Genius of Sub-Buttons: Bubble Card truly shines with its incredibly useful sub-button system. Bubble Card’s sub-buttons are enriching your main card with extra information. Instead of cluttering a single card, use sub-buttons to neatly layer in details and controls. Think of a weather card: the main bubble shows temperature, and sub-buttons add rain, wind, and more. This system is damned useful for making cards information-rich and functional, presenting more data cleanly and accessibly. They are perfect for adding context and control without losing visual clarity.
And the best part? It manages to be this powerful without becoming overly complex. The YAML configuration is well-structured and, once you get the hang of it, surprisingly intuitive. Plus, the developer (who, full disclosure, I occasionally help out 😉) is super responsive and constantly adding new features and improvements based on user feedback. It’s a plugin that’s constantly evolving and getting better.
Honestly, for anyone serious about creating a personalized and powerful Home Assistant dashboard, Bubble Card isn’t just a good option — it’s the option. It’s the foundation upon which I’ve built my entire dashboard, and it’s the plugin I recommend to anyone asking how to take their dashboard to the next level.
**Streamline Card: My All-in-One Template Powerhouse (Goodbye Decluttering & Config-Template!)**
The Streamline Card plugin for Home Assistant
Okay, let’s be honest. While I loved decluttering-card
and config-template-card
for what they did, they always felt like…separate pieces of the puzzle. I wanted something more integrated, more powerful, and frankly, faster. That’s the real story behind Streamline Card. It wasn't just about replacing those plugins; it was about building something better that combined their best features and added a whole lot more.
So, what makes Streamline Card my go-to template engine now? Let me break it down:
- Template Reusability (Decluttering-card, Reincarnated!): First and foremost, Streamline Card nails template reusability, just like
decluttering-card
did. Define your card templates once, then reuse them across your entire dashboard, just by changing a few variables. Want to have a consistent look for all your light cards? Battery sensors? Streamline Card makes it a breeze. It takes the core idea ofdecluttering-card
and runs with it, making template management even smoother. - Dynamic Configuration Supercharged (Config-template-card, Evolved!): Remember how
config-template-card
let you make cards change based on conditions? Streamline Card takes that concept and cranks it up to eleven! Its templating engine is incredibly flexible, letting you dynamically control anything within your cards based on entity states, variables, time – you name it. Need a card to look different when it's raining? Want to show different information depending on who's home? Streamline Card’s got you covered, with a templating system that's more intuitive and powerful thanconfig-template-card
ever was. - Section Layouts & Visibility: Dashboard Organization Built-In: While I’m now embracing Home Assistant’s native layout options for the overall dashboard structure, Streamline Card still packs a punch when it comes to internal card organization. It fully supports section layouts and visibility conditions. This means you can create complex card structures with different sections that appear or disappear based on specific criteria. Want to hide advanced controls unless you need them? Need to create collapsible sections within a card to save space? Streamline Card lets you build cards that are not only visually appealing but also intelligently organized.
- JavaScript Expressions: Unleash the Power of Code: This is where Streamline Card really shines. Want to go beyond basic YAML templating? Streamline Card lets you embed raw JavaScript expressions directly into your card configuration! Just add
_javascript
to any YAML key, and Streamline Card will interpret its value as JavaScript code. This unlocks a whole new dimension of customization. You can perform complex calculations, manipulate data, create dynamic styles, and build truly interactive elements, all with the full power of JavaScript at your fingertips. - UI Editor & YAML Flexibility: Your Choice, Your Workflow: Whether you’re a YAML purist or prefer the visual approach of the Home Assistant UI, Streamline Card has you covered. It comes with a built-in UI editor, making it easy to configure your cards directly in the browser. But don’t worry, YAML lovers! Streamline Card is still fully configurable via YAML, giving you the flexibility to choose the workflow that suits you best. Mix and match, use the UI for quick tweaks, YAML for complex setups — it’s all up to you.
- Performance Matters: Faster Updates, Smoother Dashboard: Finally, and this is a big one for me: performance. Streamline Card is designed with performance in mind. It’s smart about updates, only re-rendering parts of the card when necessary. This “cherry-picking” of updates means your dashboard stays snappy and responsive, even with complex cards and dynamic content. Compared to the plugins it replaces, Streamline Card is simply more efficient, leading to a smoother overall dashboard experience.
In short, Streamline Card isn’t just a replacement for decluttering-card
and config-template-card
– it's a significant upgrade. It combines the best aspects of those plugins, adds a ton of new features (like JavaScript expressions and a UI editor), and delivers it all with better performance. For me, it’s become the essential engine driving my entire dashboard's dynamic and templated elements. If you're serious about taking your dashboard customization to the next level, Streamline Card is the plugin you need to check out.
**Bye-bye card-mod: Bubble Card & Streamline Card Do Styling Better (and Faster!)**
Yeah, card-mod
was the king of custom styles for ages, but things changed. First, Bubble Card leveled up its own styling game, offering tons of built-in options for visuals. Most of my styling? Bubble Card handles it directly now. Second, for those extra styling needs, Streamline Card with its JavaScript power can achieve almost any visual trick, often more efficiently. Finally, ditching card-mod
gave my dashboard a noticeable speed boost. It just runs smoother and faster without it. So, card-mod
is gone, but my dashboard looks just as good (or better!) and runs way faster thanks to Bubble Card and Streamline Card doing the styling work. Cleaner setup, better performance, same great looks – a total win!
**Template Time: Visualizing My Smart Home with Streamline Templates**
Alright, let’s dive into the real magic of my updated dashboard: Streamline Templates! These are the heart and soul of my visual setup, and they’re all built as streamline-templates of Bubble Cards. Essentially, they are pre-designed Bubble Card configurations within Streamline Card that make visualizing your smart home info clear, quick to grasp, and even a little bit fun. Let me walk you through some of my most essential templates to show you how they transform my dashboard.
**Battery Template: Your Batteries, Visually Charged!**
Battery template preview
This template gives you a super clear visual representation of your battery-powered devices right on your dashboard. Instead of just a static icon, you get a dynamic Bubble Card that uses colors and a cool circular progress indicator around the icon to show you the battery level at a glance. It’s part of the “streamline-templates” collection and is ready to be used in your Streamline Card setup!
default:
- name: ''
card:
type: 'custom:bubble-card'
card_type: button
button_type: state
entity: '[[entity]]'
name: '[[name]]'
show_state: true
columns: 2
card_layout: large
styles: |
.bubble-button-background {
background-color: ${state < 10 ? 'var(--error-color)' : state < 30 ? 'var(--warning-color)' : ''};
}
.bubble-icon-container {
background-image: conic-gradient(${state < 10 ? 'var(--error-color)' : state < 30 ? 'var(--warning-color)' : 'var(--success-color)'} ${state}%, transparent ${state}%) !important;
position: relative;
}
.bubble-icon-container::before {
background-color: var(--bubble-button-icon-background-color, var(--bubble-icon-background-color, var(--bubble-secondary-background-color, var(--card-background-color, var(--ha-card-background)))));
content: " ";
position: absolute;
top: 2px;
left: 2px;
bottom: 2px;
right: 2px;
}
.bubble-icon {
color: ${state < 10 ? 'var(--error-color)' : state < 30 ? 'var(--warning-color)' : ''} !important;
opacity: 0.6 !important;
}
It features:
- Dynamic CSS Styling: The
styles:
section uses template magic (${...}
) to dynamically change card appearance based on battery level (state
). - Color-Coded Levels: Background and icon colors change to red (critical), yellow (warning), or default (okay) based on battery percentage, using CSS variables for easy customization.
- Conic Gradient Progress Ring: A
conic-gradient
on.bubble-icon-container
creates a circular progress bar effect around the icon, visually filling up as battery level increases. A::before
element cleverly creates a central cutout for the icon.
Essentially, it’s dynamic CSS styling with color coding and a conic gradient trick to make a visually informative battery level indicator!
**Cover Template: See Your Shades’ Position at a Glance!**
Cover template preview
This template is all about making your smart covers (like blinds or shutters) super easy to understand and control visually. It’s a Bubble Card streamline-template that not only lets you open and close your covers, but also gives you a clear visual indication of their current position using a filling effect on the icon. Plus, for Somfy users, it even includes a handy “My” position button!
default:
- name: ''
card:
type: 'custom:bubble-card'
card_type: cover
entity: '[[entity]]'
name: '[[name]]'
icon_open: mdi:window-shutter-open
icon_close: mdi:window-shutter
show_state: true
rows: 1
card_layout: large
sub_button:
- name: My
icon: mdi:star
show_background: true
tap_action:
action: call-service
service: button.press
target:
entity_id:
- '[[my]]'
styles_javascript: |
`
.bubble-cover-card-container {
gap: 8px;
}
.large .bubble-buttons {
gap: 8px;
right: 8px;
}
.bubble-button {
background-color: var(--card-background-color, var(--ha-card-background));
width: 36px;
height: 36px;
}
.bubble-icon {
opacity: 0.6 !important;
}
.large .bubble-sub-button-container {
margin-right: 0!important;
}
.bubble-sub-button {
width: 36px;
height: 36px;
}
.bubble-state::after {
content: " - ${states['[[entity]]'].attributes.current_position}%";
margin-left: 4px;
}
.background-on {
background-color: var(--card-background-color, var(--ha-card-background));
}
.bubble-icon-container {
background-image: linear-gradient(to bottom, var(--state-cover-active-color) ${100-states['[[entity]]'].attributes.current_position}%, transparent ${100-states['[[entity]]'].attributes.current_position}%) !important;
position: relative;
}
`
It features:
[[my]]
Button (Somfy): Includes a "My" button (via[[my]]
variable andsub_button
) for Somfy covers to trigger their preset "My" position.- Linear Gradient Position Fill: Uses a dynamic
linear-gradient
on.bubble-icon-container
(styled with JavaScript) to visually fill the icon based on the cover'scurrent_position
. - Percentage State Display: Appends the cover’s
current_position
percentage to the state text using CSS and JavaScript for numerical feedback.
Essentially, it’s Somfy “My” button integration, dynamic icon filling for position, and a percentage readout for a complete cover visualization and control card!
**Fan Template: Animated Fan Fun!**
Fan template preview
This template brings your smart fans to life right on your dashboard with a fun, animated icon! It’s a Bubble Card streamline-template that not only lets you toggle your fan on/off but also visually shows the fan spinning at different speeds thanks to a cool rotation animation. Plus, it includes sub-buttons for oscillation and speed control, giving you full fan command in a single, dynamic card.
default:
- name: ''
card:
type: 'custom:bubble-card'
card_type: button
button_type: switch
entity: '[[entity]]'
name: '[[name]]'
icon: mdi:fan
show_state: true
columns: 4
card_layout: large
sub_button:
- icon: mdi:arrow-oscillating
show_icon: true
tap_action:
action: call-service
service: fan.oscillate
target:
entity_id: '[[entity]]'
- icon: mdi:fan-minus
show_icon: true
tap_action:
action: call-service
service: fan.decrease_speed
target:
entity_id: '[[entity]]'
- icon: mdi:fan-plus
show_icon: true
tap_action:
action: call-service
service: fan.increase_speed
target:
entity_id: '[[entity]]'
styles: |
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.bubble-icon {
animation: rotate ${50 / hass.states['[[entity]]'].attributes.percentage}s linear infinite;
}
.background-on {
background-color: var(--card-background-color, var(--ha-card-background));
}
.bubble-state::after {
content: " - ${hass.states['[[entity]]'].attributes.percentage}%";
margin-left: 4px;
}
- CSS Animation for Spin: The template uses CSS
@keyframes rotate
to make the fan icon spin. - JavaScript Speed Control: The key is in
.bubble-icon
styles:animation: rotate ${50 / hass.states['[[entity]]'].attributes.percentage}s linear infinite;
This line uses JavaScript to dynamically set the animation speed based on the fan'spercentage
attribute. Higher speed = faster spin! - Sub-buttons for Control: Sub-buttons are included for oscillation and speed control (decrease/increase).
- State Shows Percentage: The state display is tweaked to show the fan speed percentage numerically.
Essentially, it’s CSS animation + JavaScript smarts to visually represent fan speed with a spinning icon, plus handy sub-buttons for control!
**Player Template: Bass-Pumping Visuals for Your Music!**
Player template preview
It has a cool “bass-effect” animation on your media player card! This Bubble Card streamline-template makes your media player thumbnails subtly pulse and “beat” when music is playing, adding a dynamic and engaging visual element to your dashboard’s media controls.
default:
- name: ''
card:
type: 'custom:bubble-card'
card_type: media-player
entity: '[[entity]]'
name: '[[name]]'
icon: '[[icon]]'
columns: 4
card_layout: large
hide:
power_button: true
styles: |
.bubble-icon-container {
animation: ${state === 'playing' ? 'player' : 'none'} 2s infinite;
}
@keyframes player {
from { transform: scale(1); filter: blur(0); }
5% { transform: scale(1); filter: blur(0); }
10% { transform: scale(1.1); filter: blur(1px); }
15% { transform: scale(1); filter: blur(0); }
45% { transform: scale(1); filter: blur(0); }
50% { transform: scale(1.1); filter: blur(1px); }
55% { transform: scale(1); filter: blur(0); }
65% { transform: scale(1); filter: blur(0); }
70% { transform: scale(1.1); filter: blur(1px); }
75% { transform: scale(1); filter: blur(0); }
to { transform: scale(1); filter: blur(0); }
}
It features:
- CSS
player
Animation: Defines a CSS@keyframes player
animation that creates a subtle "pulse" effect by scaling the icon slightly larger and adding a bit of blur at intervals. - Dynamic Animation Toggle: The
.bubble-icon-container
style uses JavaScript template magic:animation: ${state === 'playing' ? 'player' : 'none'} 2s infinite;
. This line dynamically applies theplayer
animation only when the media player'sstate
isplaying
. Otherwise, the animation is set tonone
, keeping the icon static when not playing. - Hidden Power Button:
hide: power_button: true
simply hides the default power button on the Bubble Card media player, focusing the visual attention on the animated thumbnail.
In essence, it’s all about using a CSS animation and JavaScript-based conditional styling to create a fun, subtle “bass-beat” visual effect on your media player card when it’s active!
**Thermostat Template: Instant Temperature Insights with Color Coding!**
Thermostat template preview
This Bubble Card streamline-template provides a clear and immediate understanding of your thermostat’s operation. At a glance, you can see not only the current temperature but also whether your thermostat is actively heating and if it’s still working to reach the set target temperature, all thanks to intuitive color cues.
default:
- name: 'Thermostat'
card:
type: custom:bubble-card
card_type: climate
entity: '[[entity]]'
name: '[[name]]'
show_state: true
columns: 4
card_layout: large
sub_button:
- name: HVAC modes menu
select_attribute: hvac_modes
show_arrow: false
styles: |
.bubble-color-background {
background-color: ${ hass.states['[[entity]]'].state === 'heat' ? hass.states['[[entity]]'].attributes.temperature > hass.states['[[temperature]]'].state ? "var(--warning-color)" : "transparent" : "transparent" } !important;
opacity: 1!important;
}
.bubble-state::after {
content: " - ${hass.states['[[entity]]'].attributes.current_temperature} °C";
margin-left: 4px;
}
.bubble-sub-button.background-on {
background-color: var(--card-background-color, var(--ha-card-background));
}
.bubble-icon {
color: ${ hass.states['[[entity]]'].state === 'off' ? "var(--info-color)" : "" } !important;
}
It features:
- Color Background for Heating:
.bubble-color-background
uses JavaScript to dynamically set the background color tovar(--warning-color)
(e.g., orange/yellow) only when heating and the target temperature is still higher than the current temperature. Otherwise, it's transparent. - State Shows Current Temp:
.bubble-state::after
adds thecurrent_temperature
in °C to the state display. - “Off” State Icon Color:
.bubble-icon
changes the icon tovar(--info-color)
when the thermostat isoff
.
Essentially, it’s dynamic color-coding for heating status, clear temperature display, and a visual cue for the “off” state — all in one concise template!
Weather Template: Your Complete Weather Briefing at a Glance!
Weather template preview
This Bubble Card streamline-template is an all-in-one weather powerhouse! It displays current conditions, along with color-coded high/low temperatures, wind speed, and rain probability, all within a single, compact card.
default:
- name: ''
card:
type: custom:bubble-card
card_type: button
button_type: state
entity: '[[entity]]'
name: '[[name]]'
show_state: true
scrolling_effect: false
card_layout: large-2-rows
sub_button:
- name: Min
icon: mdi:thermometer-low
entity: '[[entity]]'
attribute: forecast[0].templow
show_background: false
show_attribute: true
- name: Wind
icon: mdi:weather-windy
entity: '[[entity]]'
attribute: wind_speed
show_background: false
show_attribute: true
show_icon: true
- name: Max
icon: mdi:thermometer-high
entity: '[[entity]]'
attribute: forecast[0].temperature
show_background: false
show_attribute: true
- name: Rain
icon: mdi:weather-pouring
entity: '[[entity]]'
show_background: false
show_attribute: true
attribute: forecast[0].precipitation
show_icon: true
styles: |
.bubble-icon-container {
box-sizing: border-box;
padding: 8px;
}
.bubble-name-container {
margin: 0 0 0 0;
padding: 0 8px;
}
.bubble-entity-picture {
height: calc(100% - 16px);
width: calc(100% - 16px);
}
.bubble-name {
border-radius: 2px;
background-color: ${
hass.states[entity].attributes.temperature < 10
? 'var(--info-color)'
: hass.states[entity].attributes.temperature > 40
? 'var(--error-color)'
: hass.states[entity].attributes.temperature > 30
? 'var(--warning-color)'
: ''
};
height: 20px;
margin-left: -4px;
padding: 0 4px;
width: fit-content;
z-index: 1;
}
.bubble-name::after {
content: " · ${hass.states[card.getRootNode().host.config.sub_button[0].entity].attributes.temperature}°C";
}
.bubble-state {
height: 20px;
}
.rows-2 .bubble-sub-button-container {
gap: 0 8px!important;
}
.bubble-sub-button {
padding: 0 4px;
}
.bubble-sub-button-1 {
background-color: ${
hass.states[card.getRootNode().host.config.sub_button[0].entity].attributes.temperature < 10
? 'var(--info-color)'
: hass.states[card.getRootNode().host.config.sub_button[0].entity].attributes.temperature > 40
? 'var(--error-color)'
: hass.states[card.getRootNode().host.config.sub_button[0].entity].attributes.temperature > 30
? 'var(--warning-color)'
: ''
};
}
.bubble-sub-button-1::before {
content: "°C";
}
.bubble-sub-button-2 {
background-color: ${
hass.states[card.getRootNode().host.config.sub_button[0].entity].attributes.wind_speed > 50
? 'var(--error-color)'
: hass.states[card.getRootNode().host.config.sub_button[0].entity].attributes.wind_speed > 20
? 'var(--warning-color)'
: ''
};
}
.bubble-sub-button-2::before {
content: "km/h";
margin-left: 2px;
}
.bubble-sub-button-3 {
background-color: ${
hass.states[card.getRootNode().host.config.sub_button[2].entity].attributes.forecast[0].temperature < 10
? 'var(--info-color)'
: hass.states[card.getRootNode().host.config.sub_button[2].entity].attributes.forecast[0].temperature > 40
? 'var(--error-color)'
: hass.states[card.getRootNode().host.config.sub_button[2].entity].attributes.forecast[0].temperature > 30
? 'var(--warning-color)'
: ''
};
}
.bubble-sub-button-3::before {
content: "°C";
}
.bubble-sub-button-4 {
background-color: ${
hass.states[card.getRootNode().host.config.sub_button[2].entity].attributes.forecast[0].precipitation > 0
? 'var(--info-color)'
: ''
};
}
.bubble-sub-button-4::before {
content:" mm";
margin-left: 2px;
}
It features:
- All-in-one Weather Card: Combines current conditions, high/low temps, wind, and rain in one card using sub-buttons.
- Color-Coded Temperatures: Card name and Min/Max sub-buttons use dynamic background colors to indicate temperature ranges (cold, normal, warm, hot).
- Wind & Rain Color Highlights: Wind and Rain sub-buttons use background colors to emphasize windy and rainy conditions.
- Sub-buttons for Forecast Details: Sub-buttons display Min/Max temps, Wind speed, and Rain amount directly on the card.
- Units in CSS: CSS
::before
and::after
pseudo-elements add units (°C, km/h, mm) to displayed values in the card name and sub-buttons.
Essentially, this template packs a wealth of color-coded weather information into a single Bubble Card using clever dynamic styling and sub-button organization!
Conclusion: Level Up Your Dashboard & Stay Tuned!
So there you have it — my Home Assistant dashboard, one year later, now leaner, faster, and even more visually informative thanks to the power of Bubble Card and, especially, Streamline Card! I’ve truly streamlined my setup, and I’m loving the results.
If you’re feeling inspired to revamp your own dashboard, I highly encourage you to dive into Streamline Card and its templates. You can find the full, ever-growing template library (with even more goodies than showcased here!) over on my portfolio’s page for streamline-card. And if you’re curious about the plugin itself or want to contribute, you can find the code and documentation on the Streamline Card GitHub repository.
If you found this update helpful or inspiring, give this article a clap! (or bookmark it for later dashboard tinkering!). And who knows what the next year will bring for my dashboard? New sensors? New automations? Even more Streamline Card templates? You’ll just have to wait until next year’s update to find out! 😉