Skip to main content

Data Stylers

Data stylers allow applying styles (think of css) to data in the DataFrames.

Row Stylers

Styles can be applied to the entire row. fmt.addRowStyler is the API to add a row styler.

Constant Styler

fmt.const styler can be used to apply the same style for all the rows and is data independent.


Conditional Styler

The stylers can be conditional on data and the same API used to filter data (for WHERE clause) is used to specify the condition. fmt.cond is used to create a conditional styler. It has a condition, if-styler and else-styler.


Striped Styler

fmt.stripe takes two are more styles and repeatedly applies them to the rows.

avoid inheriting striped stylers

Stylers are inherited from parent DataFrames (see below). Inherited striped stylers can cause unexpected results. Hence, avoid inheriting these stylers either by not specifying them on the parent DataFrames or explicitly specifying a styler (including striped styler) on the DataFrame so it doesn't inherit.

Value Mapping Styler

Sometimes the data already contains a value that can be directly mapped to a css property. This is most common for colors.



When a df has no row styling of its own, it inherits styling from the dependent DataFrames as per the following rules.

  1. udf, idf, edf - from the underlying dfs that make up the udf.
  2. pdf, fdf - from their parent df.
  3. hdf from the parent only for the leaf level rows.

Notice how the udf below inherits the styles from the two dfs that created the union.


See Advanced Reporting where this feature is made use of to create complex reporting layouts with formatting.

Field Stylers

Styling can be applied to individual fields instead of the entire row. fmt.addFieldStyler is the API to add field level stylers.

Constant Styler


Conditional Styler



Similar to inheritance in row styling, field styling also has a limited form of inheritance as per the following rules.

  1. udf fields inherit style from their underlying dfs.
  2. vdf value cells inherit from both row and field styles from the parent (and follow css merging rules between tr and td).

The row style inheritance preserves styling while transposing the data


Bar Styler

Base partitions only is a field level styler for numeric data that presents data as bar chart within the table.

SQL Frames supports ROLLUP and CUBE constructs which result in multiple levels of details. It is possible to limit applying the stylers only to base partitions, that is the lowest level of detail. This is done using the condition isbp().


All partitions

This plugin is aware of SQL Frames capabilities and hence the styler can be applied to all partitions. It is smart enough to compute the bar widths correctly based on the level of detail a row belongs to.


Heatmap Styler

fmt.heatmap styler allows changing the color intensity based on the value in a row and the corresponding min/max values possible for that field.

Heatmap for a non-pivot field


Heatmap for a pivot field

Each cell within a pivot table belongs to a specific level of detail. Same row or column can have multiple levels of detail. The color intensity varies based on the level of detail a cell belongs to which is a metadata information readily available from SQL Frames.


Header Stylers

Styles can be applied to the field headers as well. Stylers can be applied to the header cell using fmt.addFieldHeaderStyler to control some styles like the background color. Stylers can be applied to the header cell content using fmt.addFieldHeaderContentStyler to control for example the orientation of the header text.


Two separate stylers one for the header cell and another for the cell content are required because css transformation is applicable only to the content of the cell and not the cell itself while background color is for the cell and not just the content.

Multiple Stylers

It is possible to specify multiple row and/or field stylers either calling df.fmt.addRowStyler() (and df.fmt.addFieldStyler() for fields) API multiple times or by simply using df.fmt.addRowStylers() (and df.fmt.addFieldStylers() for fields) and passing multiple stylers.

Order Matters

All the stylers are first evaluated in the order added and merged and the css is generated based on the final merged style object. Hence, the styles added later can overwrite the properties set by the styles added earlier.


Pivot Column Stylers

Pivot column stylers use the same existing API.

Column Header Styler


Column Data Styler

Even though the pivoted column values act as column headers for the pivot table, they are styled as if they are regular data.


When the pivot is transposed, the pivot columns becomes pivot rows and their data styling is applied at the row level and vice-versa.

Art in a DataFrame!

The following example is based on Outlandish Recursive Query Examples.

SQL Generation

The above generated SQL will not directly work on any database as it uses some javascript code. SQL Frames allows using logic that is not strictly SQL. Manual tweaking will be required to make it run on a database. Most common use cases of logic will be made available within SQL Frames framework so that more and more auto generated SQL can be directly executed within the database.

Rendering Performance

Some css styling options are very expensive. opacity is a good example. Avoid using such css options to ensure smooth rendering and scrolling of the table.

A word of caution

Not all css properties will work as not all are allowed on every element such as table, th and td. Hence, you should experiment and perhaps even try out on different browsers to make sure your desired styling works correctly on the target browsers. This is no different than the regular web app development. This is especially important when sharing the visuals with others.

Dark Mode

The right way to provide dark mode support is by using CSS variables for the custom styling rather than hard-coded values as shown above and then changing the varible values based on the dark or light mode.