How to target Dataview queries for CSS styling

This thread will show some of the options available for styling the result of your Dataview queries by providing you with CSS selectors which targets the outer elements of the query results. The specific styling within each is left up to the reader. After first covering the basics, I’ll show a nifty hack using #tags to single out specific queries.

The basic options for styling

The three most common options to target every query of the various query types are:

  • TABLE queries and dv.table(): table.dataview
  • LIST queries and dv.list(): ul.list-view-ul
  • TASK queries and dv.taskList(): ul.contains-task-list

However these would target the result in the entire vault, so we would need some extra qualifiers to narrow the scope down. Using the cssclasses property we can limit the ordinary queries down to a single file, and for dataviewjs queries we can use dv.container.className += " clsname" to limit to that specific query.

So one way to hide the table header using cssclasses: hide_header could then become:

.hide_header table.dataview thead {
  display: none;
}

This should work in both live preview and reading mode as is.

Targeting specific tables, rows or cells using tags

As already said, there are generally no unique ID’s given to a specific query result, with the exception of using dv.container.className in dataviewjs, but I’ve found one trick which is usable in the more recent version of Obsidian since we now have got access to the :has() CSS selector, and the fact that tags are rendered as <a> tags within tables in both live preview and reading mode.

In the following text I’ll use nested tags starting with #_/..., but you’re free to use whatever tag names you’d like. I’ve chosen that prefix for my vault to denote that these tags are used for this purpose only, and this allows me to globally hide these tags using:

[href=^"#_"] {
  display: none;
}

This particular rule matches all links having the href attribute starting with the text #_. This now allow me to target a unique table, i.e. tagged with #_/uniqueTableId, using the following CSS:

table:has([href="#_/uniqueTableId"] {
  /* Whatever styling I'd like applied to this table  */
  & thead > tr  {
    background-color: blue;
  }
}

Note that here I’ve skipped the more specific table.dataview, so this would also color any ordinary markdown table tagged with that tag in the same style. If that’s not wanted, change it into table.dataview:has([href="#_/uniqueTableId"]) { ... } . In addition note the nesting of CSS selectors where we due to the first line are within the context of tables tagged with our tag, and then we can use & ... to further specify a selector to target rows or cells or whatever we’d like to target within that given table. This is shown in the example to color the rows in the header blue.

This can also be combined using cssclasses or dv.container.className if one chooses to do so. And you can re-use the tags if you want to have a specific type of styling for a given type of tables various places in your vault.

What about lists and task lists?

The above was specific to tables, and would apply to both live preview and reading mode, but what about ordinary lists and task lists? Due to how live preview renders stuff slightly different, it’s not as easy to target them using simple selectors as above.

In reading mode you could use the variant below for a list, and the corresponding ul.contains-task-list alternative for tasks:

ul.list-view-ul:has([href="#_/myListId"]) {
  /* Style the list */
}

However in live preview each list item is its own <div> placed on the same level (and not within a given container). This means that you need to tag the specific item(s) you’d want to style, and it’s not as elegant as the solution above.

But then again, the tag can be hidden from view, so maybe you don’t care that much due to the possibilities it offers. So to target a task or list item tagged #_ you could use:

.is-live-preview .HyperMD-task-line:has(.cm-tag-_),
.is-live-preview .HyperMD-list-line:has(.cm-tag-_)  {
    background-color: blue;
}

Note that if you remove the .is-live-preview it’ll also apply to source mode for better or worse. And if you add li:has([href="#_"]) it’ll also apply to the reading mode (with a little caveat that the boxes are slightly different around the elements in reading mode).

These last examples are not specific to the Dataview queries, but do apply to all task or list items tagged accordingly. But if you want you could precede either of these selectors with the basic selectors used to target dataview queries as given in first section.

A last note on the tags in live preview and that is to hide them you need to extend the first example of hiding tags using something like:

.is-live-preview .cm-tag-_,
[href^="#_"] {
  display: none;
}

Or variations like [class^="cm-tag-_"] or similar.


In summary, this should give you a good start on how to target the various elements of both dataview queries, and table, task and list items in general.

There are a few last minute references I would like to point your attention to:

5 Likes

@CawlinTeffid , here is that share and showcase post you requested. It took me some time to write, so that thread got closed down. :smiley:

Nice! It hasn’t been so long, threads close quickly once they’re marked solved. I’ll share your findings with the CSS wizards on Discord.

1 Like

Might be a noob question but how do i add a tag to a section. Preferably to a callout.

> [!NOTE]+ Abilities 
> #_/uniqueTableId
> ```dataviewjs
> await forceLoadCustomJS();
> const {CreatureSheet} = customJS
> CreatureSheet.spell_table(app, dv)
> ```

I basically copied your example css.

table.dataview:has([href="#_/uniqueTableId"]) {
    display: none !important;
    visibility: hidden !important;
}

[href^="#_"] {
    display: none;
}

The tag disappears, but the table doesn’t.

To make my examples work you need to have the tag within the output from dataview, aka somewhere inside the dataview codeblock, not on the outside. In addition, when you’re using dataviewjs you can (and most likely is should) use the dv.container.className += " clsname".

If you added that within either the outer codeblock, or within the CreatureSheet.spell_table(), you could use something like: table.dataview:has( .clsname) to target your table.

If on the other hand you really want to target the callout div, you could try with something like:


div.callout:has([href="#_/uniqueTableId"]) {
   & .dataview {
     display: none;
   }
}
1 Like