2025.12 Markdown changes, and how to mitigate

in 2025.12 several changes have been implemented that cause my markdown tables and indents (block quotes) to change their appearance.

the block quotes are or, instead of an indent I now get this vertical line:

which is not too bad… Id rather not have it, but apparently now the card follows specifications it previously didnt :wink:

the tables however now show borders around all of the cells (which they now appear to be, like an excel sheet) and I really dislike that.

before:

now

my original wa using the --|--|-- syntax with this template

        content: >
          {%- set ns = namespace(nodes=[]) %}
          {%- for dev_id in integration_entities('zwave_js')|map('device_id')|unique %}
          {%- set node_id = (device_attr(dev_id,'identifiers')|first|last).split('-')[1] %}
          {%- set ns.nodes = ns.nodes + [(node_id|int,dev_id)] %}
          {%- endfor %}

          ID | Manufacturer | Product | Product code | Name by user | Location / Area | FW | Status

          :-|:-|:-|:-|:-|:-|:-|:-

          {%- for node_id,dev_id in ns.nodes|sort(attribute='0') %}

          {{ ['[**%01d**](/config/devices/device/%s)'|format(node_id,dev_id),
              device_attr(dev_id,'manufacturer'),
              device_attr(dev_id,'name'),
              device_attr(dev_id,'model'),
              device_attr(dev_id,'name_by_user') or '',
              area_name(dev_id) or '',
              device_attr(dev_id,'sw_version'),
              device_entities(dev_id)|select('search','status')|map('states')|join]|join('|') }}
          {%- endfor %}

and I was told to use html and style the table, so I tried that with

          {%- set ns = namespace(nodes=[]) %}
          {%- for dev_id in integration_entities('zwave_js')|map('device_id')|unique %}
            {%- set node_id = (device_attr(dev_id,'identifiers')|first|last).split('-')[1] %}
            {%- set ns.nodes = ns.nodes + [(node_id|int,dev_id)] %}
          {%- endfor %}

          <table style="border-collapse: collapse; width: 100%; font-size: 0.9rem;">
            <thead>
              <tr>
                <th style="border: none; text-align: left;">ID</th>
                <th style="border: none; text-align: center;">Manufacturer</th>
                <th style="border: none; text-align: left;">Product</th>
                <th style="border: none; text-align: left;">Product&nbsp;code</th>
                <th style="border: none; text-align: left;">Name by user</th>
                <th style="border: none; text-align: left;">Location / Area</th>
                <th style="border: none; text-align: left;">FW</th>
                <th style="border: none; text-align: left;">Status</th>
              </tr>
            </thead>
            <tbody>
            {%- for node_id,dev_id in ns.nodes|sort(attribute='0') %}
              <tr>
                <td style="border: none;">
                  <a href="/config/devices/device/{{ dev_id }}"><b>{{ "%01d"|format(node_id) }}</b></a>
                </td>
                <td style="border: none;">{{ device_attr(dev_id,'manufacturer') }}</td>
                <td style="border: none;">{{ device_attr(dev_id,'name') }}</td>
                <td style="border: none;">{{ device_attr(dev_id,'model') }}</td>
                <td style="border: none;">{{ device_attr(dev_id,'name_by_user') or '' }}</td>
                <td style="border: none;">{{ area_name(dev_id) or '' }}</td>
                <td style="border: none;">{{ device_attr(dev_id,'sw_version') }}</td>
                <td style="border: none;">
                  {{ device_entities(dev_id)
                      |select('search','status')
                      |map('states')
                      |join }}
                </td>
              </tr>
            {%- endfor %}
            </tbody>
          </table>

but the result is identical somehow…

would anyone be able to spot where I go wrong?
thanks

1 Like

I’ve been using html tables in Markdown cards for a while, and have never been able to successfully style them within the html code itself.

So I’ve always had to resort to card_mod, which has been 100% reliable until the 2025.12.0 betas.

The required Dom paths seem to have changed, and I think I’ve got that sorted, but now often the styling isn’t shown on first load, but needs a refresh from the dashboard menu.

I’ve tried using the advised card_mod tricks - line breaking the Dom path on each shadow-root, using prepend: true, but without it making a difference.

I’m also finding that styles aren’t applied on Markdown cards within a closed expander card on first open. Works on second open though.

Here’s a semi-working code sample:

type: markdown
card_mod:
  prepend: true
  style:
    ha-markdown $:
      ha-markdown-element: |
        table {
          width: 100%;
        }
        td {
          border: none;
          padding: 0px;
          vertical-align: middle;
        }

just learned that we can set

markdown-table-border-color: transparent

in our themes, or use ā€˜ā€“markdown-table-border-color: transparent’ in a card-mod styling and the borders are gone. Well, transparent…

As Petro said in the beta Discord channel, the border setting is likely better set at td (cell) level anyway, rather than table level EDIT: for html tables. The theme variable likely works for markdown code.

My posted code does work, just not reliably on first load.

I just confirmed in the beta channel that setting

#     markdown-table-border-color: transparent
    markdown-table-border-width: 0px

in the generic theme settings (so not card-mod theming, nor card_mod) effectively removes the borders in both the markdown style and table html style

the styling in the html markdown is effectively ignored, so I changed that to

        content: >
          {%- set ns = namespace(nodes=[]) %}
          {%- for dev_id in integration_entities('zwave_js')|map('device_id')|unique %}
            {%- set node_id = (device_attr(dev_id,'identifiers')|first|last).split('-')[1] %}
            {%- set ns.nodes = ns.nodes + [(node_id|int,dev_id)] %}
          {%- endfor %}

          <table>
            <thead>
              <tr>
                <th>ID</th>
                <th>Manufacturer</th>
                <th>Product</th>
                <th>Product&nbsp;code</th>
                <th>Name by user</th>
                <th>Location / Area</th>
                <th>FW</th>
                <th>Status</th>
              </tr>
            </thead>
            <tbody>
            {%- for node_id,dev_id in ns.nodes|sort(attribute='0') %}
              <tr>
                <td style="border: none;">
                  <a href="/config/devices/device/{{ dev_id }}"><b>{{ "%01d"|format(node_id) }}</b></a>
                </td>
                <td>{{ device_attr(dev_id,'manufacturer') }}</td>
                <td>{{ device_attr(dev_id,'name') }}</td>
                <td>{{ device_attr(dev_id,'model') }}</td>
                <td>{{ device_attr(dev_id,'name_by_user') or '' }}</td>
                <td>{{ area_name(dev_id) or '' }}</td>
                <td>{{ device_attr(dev_id,'sw_version') }}</td>
                <td>
                  {{ device_entities(dev_id)
                      |select('search','status')
                      |map('states')
                      |join }}
                </td>
              </tr>
            {%- endfor %}
            </tbody>
          </table>

Id almost clicked the solved tick box here, but maybe other markdown changes will be found, so leaving open for a bit

you can easily test the power of these theme vars.
set

markdown-table-border-color: red

and next, add

markdown-table-border-width: 0px

set to width 0px, the red borders no longer exist :wink:

4 Likes

Hi @Mariusthvdb ,
Is it possible to modify the default theme this way? I’ve never tried it before, and I’m still on the default theme. Thanks!

Well no.
Default theme is No theme :wink:

But you can make a new theme , add only that line, and load that.
Then you will have all default settings and hide the table borders

Hi there, just to be sure I understand it correct: so far, with 2025.12, there is no reliable way to remove borders other than changing the general theme settings, right?

Or you could use card_mod.

Just be aware that there’s a frontend fix going through that will also address the issue that some of us are seeing with card_mod styles not consistently being applied to Markdown cards on first load of a dashboard view, or when in Editor view.

I assume this fix will appear in the 2025.12.1 patch release on Friday.

1 Like

I am also seeing an issue with padding on tables, this has been added as a new style to table td and th cells.

padding: 0.25em 0.5em;

And no way to create a new theme without, For my dashboards, which I cast, it means the tables no longer fit on screen and render very messy.

How more reliable do you want it?

only now do I discover this huuuge icon in Markdown…

  - type: markdown
    content: >
      <img src='/local/images/mowas.png' width='35'> [Live Warnmeldungen übersicht](https://warnung.bund.de/meldungen)

1 Like

Thx for questioning me, Marius. First I was reluctant because I do not have many if any experience in changing the themes. But then I remembered, that I’ve done some mini modifications and simply added the both code lines to my theme in configuration.yaml. It works, thx a lot!

1 Like

Yes no straightforward way to fix it

A PR was merged that is supposed to fix these flukes.

lets keep an eye out for that in 12.1 and hope for the best

2 Likes

the proper fix would be to get rid of all these hacky work arounds (card-mod, etc) and have a proper HTML + CSS native card. Dashboards are just layers upon layers of hacks and workarounds – many of which ā€˜step on’ each other constantly.

if the devs would spend less time making ā€˜default’ dashboards and more time fixing the brokenness that it is, we’d all be 1000x better off. Its clear it can be done, Ultra Card puts the native dashboard building to shame

I agree, a native HA Markdown Card should have all editing and formatting functions baked in. Even though us users are probably using markdown far beyond its original design.

Where I can I try not to use card-mod (due to the perceived lag of loading experienced by the family)

I disagree, the ā€˜Markdown Card’ should be only markdown… they need a card that can properly handle formatting and is made to do so…

Worst Case is full scale HTML + CSS. (because it would still be a ton of manual coding - most do not have the skills but at least the AIs could do it better than they can find their way around the mess we have today)

Best Case would be an expansion of Ultra Card into a complete editor for HA and 99% of the manual coding and hacks like Card-Mod become unnecessary.

Sounds like a custom card you can develop, especially if you know how to use AI.

I have seen ultra-card and dashable both subscription based. I have only watched You Tube clips on them and both seem to have very extensive options and customisability.
I think I would near get lost in the endless clicking through menus rather than just editing YAML or creating a card in *.js that suits my needs from scratch.

The modified version of this card suited me for years until the recent change, where I can’t adjust the size of the image in my markdown card.

I will wait and see what happens with the updates.

same issue here