Freeze Column & Headers Plugin

I recently had this requirement for freezing the column and header on a Classic Report, just the way you can with Excel. The report had too many columns and once you scroll horizontally or vertically you would loose track of the information you’re seeing.

It turns out freezing the header is pretty straight forward and it’s even out of the box functionality on the Interactive Reports, but not for Classic Reports.
If you only need to freeze the headers, just head over to Marko Gorički’s blog “How to make any table header sticky” and be done with it.

However, freezing columns is a completely different technique from freezing a header, or it requires special markup. Ideally, I didn’t want to create a Custom Template (even though, you know, I’m a big fan).

After some discussions and good advice from my buddy Vincent Morneau, I began scouring the interwebs for a suitable solution.

This JSFiddle seemed very promising and easy to adapt to Oracle APEX Universal Theme markup.

It seemed to me that I had to adjust selectors. So table became table.t-Report-report, thead became table.t-Report-report thead, and so on. You get the idea.

Then, after a working prototype, I saw the opportunity to bundle everything in a nifty easy to use APEX Plugin. You can find the plugin in and Github Maybe you will find it useful.

View Demo

Using it is dead simple:

  1. Create an “After Refresh” Dynamic Action on the Classic Report you want to “freeze”.
  2. For the True Action select “Insum Freeze Headers & Column”
  3. Make sure “Fire on Initialization” is Yes.
  4. Don’t specify an affected element; the plugin uses this.triggeringElement

Hi, I'm Jorge Rimblas. Father, husband, photographer, Oraclenerd, Oracle APEX expert, Oracle ACE, coffee lover, car guy, gadget addict, etc... I'm an APEX Tech Lead DRW. I have worked with Oracle since 1995 and done eBusiness Suite implementations and customizations. Nowadays I specialize almost exclusively in Oracle APEX.

24 Comments on “Freeze Column & Headers Plugin

    • Sorry, that’s going to be pretty complex, and it’s not something I have time to work on at the moment. The complexity, of course, is to not break the built-in functionality of an IR.

  1. Hey Jorge,

    Nice little plugin! Agree would be great to be able to freeze more than one column, especially if the first column is being used as a checkbox.

    Would it be much effort to implement?


  2. Hi Jorge,

    Is this feature I can implement in Interactive report as well.
    If Yes then please let me know the steps.

    I am using Apex version.

  3. hi, The plugin ” Freeze Column & Headers Plugin” was Greate, I want 3 columns need to be freezed. what i need to do

    Thanks in advance

  4. Demo in 20.1 doesn’t seem to work correct, or was it always like this. First column background becomes fuzzy after scroll

  5. useful plugin. it is a pity that when you remove “Escape special characters”, the vertical scrolling breaks

  6. Hi Jorge,
    Great plug-in!

    On APEX 22.1 I noticed the horizontal scrolling for the frozen column no longer keeps the background as a solid color, seems like the background is not opaque anymore, now its transparent. Note: This is true for those rows that have no background color defined.

    I fixed it by explicitly defining the background color e.g:

    .customAlternatingRow .a-IRR-table tr:nth-child(odd) td {
    background-color: white;

    Thanks for all your great work!

    • Good catch! I know someone will find this useful.
      You know… now, with dark theme and other color schemes, I was actually thinking that it would be helpful to anchor those colors to a variable.

      .jsInsumFreezeColHead .t-Report--altRowsDefault .t-Report-report tr:nth-child(even) .t-Report-cell {
      background-color: var(--a-cv-background-color);

      I’ve added this to the demo app for now

      .jsInsumFreezeColHead .t-Report--altRowsDefault .t-Report-report tr:nth-child(even) .t-Report-cell {
      background-color: var(--a-cv-background-color);
      .jsInsumFreezeColHead .t-Report--altRowsDefault .t-Report-report tr:nth-child(odd) .t-Report-cell {
      background-color: #ddd;

I love comments, write me a line