Oracle APEX: Apply Conditional Styling to Reports Using CSS only #JoelKallmanDay

Oracle APEX Developer (Insum) from Paris Contributor of Flows for APEX Passionate about APEX and web development.
Introduction
One year without blogging 😳, that’s what I realized when I started writing this blog post for Joel Kallman Day… It has been another incredible year. I started speaking at Oracle conferences, co-launched a French-speaking podcast with my colleague Luc: A la base de la donnée, and also worked a lot to organize the very first Oracle APEX Day in Paris last month.
Being part of the Oracle community might have been the best professional decision I made a few years ago. It has helped me grow professionally and meet many incredibly talented people, some of whom are now becoming friends. The Joel Kallman Day makes you feel part of this community by having the same goal on the same day: making some noise with Oracle-related content!
This year I'm going to show you how simple it is in 2025 to apply conditional styling to Oracle APEX reports thanks to the :has() pseudo-class.
The :has() CSS pseudo-class
Here is the MDN definition of a pseudo-class:
A CSS pseudo-class is a keyword added to a selector that lets you style a specific state of the selected element(s).
- MDN website
You have probably already used some of the pseudo-class like :hover or :checked but in 2023 a new functional pseudo-class has become widely supported across all major browsers: :has() meaning that we can now use it safely while building Oracle APEX applications

You will probably think, why should I be interested in that? The reason is that, it let’s you select a parent element based on the existence of a child selector passed as an argument.
Here is a very simple example:
div.card:has(img) {
background-color: red;
}
This CSS snippet will change the background color of a div element with a card class only if this div has a child element that is an img element. Not convince, let see how it can be used to style reports conditionally?
The problem requirement
A common requirement is to style report cells of classic reports, interactive reports, and interactive grids based on the column data. Of course, this problem has been solved for years, and you can find many blog posts explaining how to do that. For example, Plamen and Moritz wrote about this in 2022 with Styling APEX Report cells conditionally and in 2016 with Coloring Cells in an Interactive Report. The solutions explained are still valid and fully functional, but in 2025, it is actually possible to achieve the same with less code. Isn’t that the purpose of low code originally?
The “old” solutions always involved a small part of JavaScript since, it is not possible to directly apply a class to the <td> element. The trick is to have a class in the content of the cell by using an HTML expression for instance and then on the After Refresh event, add a class to the cell itself.
In other terms, you want to apply a style to a parent element based on the existence of a child. Now, if you haven’t skipped the CSS introduction above and read the entire blog, you are following me: :has() does exactly that!

The solution in 2025
Here is what we want to achieve, we have a report showing a list of tasks and we want to have a specific cell background and text color based on the status column

Here is the SQL query
select
row_key,
id,
name,
status,
project,
updated,
updated_by
from tasks;
In the report, we are defining an HTML expression using a template directives to apply a specific class to a <span> element within the cell.

Here is the actual HTML expression
<span class="{case STATUS/}
{when Closed/}
lm-task--closed
{when Open/}
lm-task--open
{when Pending/}
lm-task--pending
{when On-Hold/}
lm-task--on-hold
{endcase/}">#STATUS#</span>
From this, the report is generated and each status cell contains a span element with a class linked to the actual status.

But as you can see the report is still missing the coloring and this is where we will see the full power of :has(). To apply the style we need to target the td element based on the child class like this
td:has(.lm-task--open) {
background: var(--a-palette-success);
color: var(--a-palette-success-contrast);
}
td:has(.lm-task--closed) {
background: var(--u-color-14);
color: var(--u-color-14-contrast);
}
td:has(.lm-task--pending) {
background: var(--ut-palette-warning);
color: var(--ut-palette-warning-contrast);
}
td:has(.lm-task--on-hold) {
background: var(--ut-palette-danger);
color: var(--ut-palette-danger-contrast);
}
Et voila 🤓
Conclusion
Thanks to the :has() selector, it’s now possible to apply conditional styling to Oracle APEX cell reports using only CSS. This simple example illustrates how powerful CSS is nowadays and how learning web standards in 2025 can help you reduce the amount of code in your Oracle APEX application! You can check it out here and see that it also works for Interactive Reports and Interactive Grids: https://oracleapex.com/ords/r/louis/examples/cell-background-color
Fun fact: As I publish this article, I'm on my way to HrOUG 2025 in Rovinj, Croatia, to give two presentations. To get there, I took a taxi, a plane, a bus, and finally a boat—all to learn and share with my peers. That's what community is all about 🤓



