Skip to main content

APEX UI Lessons

There's something to be said for corporate standards for browsers. Sure, it's almost always some flavor of IE, but at least you're only charged with making sure that your application runs and looks good on one browser on a single OS.

 However, when designing a product, you simply don't have that luxury anymore. Your application must now not only run but look good on all popular versions of popular browsers: MSIE, Chrome, Firefox and maybe even Safari. And if you think that these browsers behave exactly the same on different operating systems, you're completely wrong.

As we put the final touches on sumnevaSERT v2.0, I wanted to share some of the experiences that I went through over the past few months with regards to user interface - mostly so that you can learn from my mistakes and plan accordingly.

Design and stick with a Design Pattern

This is the most important step. If you skip it, or do it poorly, it will flow throughout your entire project and come back to haunt you on a daily basis.

Simply put, a design pattern is how different components will be laid out on the page. It's OK and quite often that you have two or three variations of this (one-level tab vs. two-level tab, sidebar vs. no sidebar, etc.).

Once a design pattern is defined, do all that you can to not stray from it. If you designed the HTML & CSS to work with 2 columns of reports, then stick to that. APEX templates are flexible to a point. Once you cross that point, not only do your applications start to look "busted", but issues with usability will start to arise on at least one of the browsers.

It helps tremendously to use a tool such as Balsamic Mockups to come up with a design pattern for your site.

Design and test the Templates first

Once you have a design pattern, it's time to convert that to APEX templates. While this is also one of the most important pieces of advice, it's also the one that you will undoubtedly fail on. It's 100% impossible to get this all done up front, so set your expectations accordingly. However, if you can get some portions of the templates done before you start adding content, that will go a long way later on. 

While designing your templates, keep the HTML as clean as possible - do not use any inline styles or other tags that could be interpreted differently by different browsers.

Also, I usually start with a clean Theme, and only use the APEX provided templates as a guide. There is no application out there that needs all 75+ templates that the APEX themes provide. Thus, I typically start with a brand new theme and build that up as needed.

Another trick that I have used forever is how I name my templates. APEX template names are too specific - "Form" region, "Report" region, and "Chart" region all look the same to me - and they should! Thus, I create a single region called "Content Region", and use that for all content - Forms, reports, charts, trees, etc. If I need a second region, it's likely going to be called something like "Content Region - Narrow" - and as the name implies, will be narrow. This small change will go a long way in keeping the templates as usable and compact as possible.

Start your cross-browser testing NOW

Don't wait until you more than a few days into development to start testing on different browsers. In fact, delegate a different browser for each day of the week for both development and testing to ensure that your application works well in all of them.

My advice: make Friday "IE day", as happy hour will never be happier.

Two (or more) CSS files

Critical when supporting most browsers and IE, you'll need to have at least two CSS files. I can't imagine putting all CSS classes into a single one and having all browsers play nice with it. You can start out with a single one, and when you hit a point where you'll have to clone it, at least you'll have a good solid base.

If you use a STYLE tag, you will pay

Don't use a STYLE tag. Can't emphasize this enough. It will come back to haunt you, as one browser will be OK with it, and others (i.e. IE) won't. At that point, you'll have to retro-fit your HTML to use classes, add them to both files, and re-test.

You'll be most likely tempted to do this when rendering HTML from PL/SQL, as if you use a STYLE tag, you don't have to open up another application to add the class, etc. Don't be lazy.

Images and CSS Files

We chose to store all images in the database, as it makes for a much easier installation. Unfortunately, even if you store the CSS file in the database as well, you can't reference the location of the images in the file, as APEX has to include some internal IDs in the link. Thus, we had to create a region on page 0 that augments the class definitions that have images. If you use a simple HTML region for this, you can include the tag #APP_IMAGES# or #WORKSPACE_IMAGES#, and they will resolve correctly.

Conclusion: Keep It Simple and Consistent

Never stray from this. EVER. The more complex you make your UI, the less your users will like it and the harder it will be to maintain. Sacrifice complexity for simplicity and consistency. Think of the web sites that you use on a daily basis and then look at their design and how simple and easy to use it is, and try to imitate that.


Nice post Scott !

But i don't agree with IE approach you're proposing.

In my design i strongly focus on standards and try to make everything strict as i go trough the design. Most of modern browsers will accept that and the difference between them is not important as long as the application works. Also in IE the problem starts if you need to make it work in IE7 and less. These are the most annoying browsers. Fortunately the percentage of them is low in these days. So low that i assume that no one is using them and omit them in process of building the Theme. Of course there are clients that are committed to this browser (I know big corporations that still have IE6 on deck), and i have to design theme for them but I do this after designing the "core".

One more thing. I've noticed that in most of templates APEX uses browser specific css (ex. -moz-border-radius). For me, Opera user :D, it's a mistake that need to be fixed. basically Don't build for browser build with standard and check in browsers if something goes wrong usually there is some simple solution. Also reed about Progressive enhancement approach witch is the way what these days web design gurus are going.

Best regards
piotr from
Scott said…

Unfortunately, I had to provide support for IE7, so the standards approach was not an option.

I do agree with you; make things as standard as possible, so that modern browsers will all "play nice" with the HTML & CSS.

I also didn't think that the Opera issue would come up so soon, either! :) You're not going to like my opinion here, but I'll share it anyways: forget Opera.

It's a numbers things, not a standards thing. If you're looking for the most compliant browser, then sure, Opera is almost always the winner. But if you're designing software that you're trying to either use at or sell to organizations, the chances that any of them "support" Opera are almost zero.

Thus, in most cases, the investment up front is almost never worth the return. Also, if you stick to standards throughout, Opera should have few, if any issues with rendering properly.

In writing this, I now have 2-3 more "rules" that I think should have been included - time for a second post!


- Scott -
Cees van Oosten said…

Can I find any more information on how to implement the page 0 solution to incluse workspace_images in the css-file?

Thanks in advance

Cees van Oosten
Scott said…

It's quite simple. Just create a PL/SQL region that uses htp.prn to "print" the CSS. When referring to images, use v('WORKSPACE_IMAGES') or v('APP_IMAGES') for the path before the image name instead of the static path.

Hope this helps.

- Scott -

Popular posts from this blog

Logging APEX Report Downloads

A customer recently asked how APEX could track who clicked “download” from an Interactive Grid.  After some quick searching of the logs, I realized that APEX simply does not record this type of activity, aside from a simple page view type of “AJAX” entry.  This was not specific enough, and of course, led to the next question - can we prevent users from downloading data from a grid entirely?

I knew that any Javascript-based solution would fall short of their security requirements, since it is trivial to reconstruct the URL pattern required to initiate a download, even if the Javascript had removed the option from the menu.  Thus, I had to consider a PL/SQL-based approach - one that could not be bypassed by a malicious end user.

To solve this problem, I turned to APEX’s Initialization PL/SQL Code parameter.  Any PL/SQL code entered in this region will be executed before any other APEX-related process.  Thus, it is literally the first place that a developer can interact with an APEX page…

Custom Export to CSV

It's been a while since I've updated my blog. I've been quite busy lately, and just have not had the time that I used to. We're expecting our 1st child in just a few short weeks now, so most of my free time has been spent learning Lamaze breathing, making the weekly run to Babies R Us, and relocating my office from the larger room upstairs to the smaller one downstairs - which I do happen to like MUCH more than I had anticipated. I have everything I need within a short walk - a bathroom, beer fridge, and 52" HD TV. I only need to go upstairs to eat and sleep now, but alas, this will all change soon...

Recently, I was asked if you could change the way Export to CSV in ApEx works. The short answer is, of course, no. But it's not too difficult to "roll your own" CSV export procedure.

Why would you want to do this? Well, the customer's requirement was to manipulate some data when the Export link was clicked, and then export it to CSV in a format…

Refreshing PL/SQL Regions in APEX

If you've been using APEX long enough, you've probably used a PL/SQL Region to render some sort of HTML that the APEX built-in components simply can't handle. Perhaps a complex chart or region that has a lot of custom content and/or layout. While best practices may be to use an APEX component, or if not, build a plugin, we all know that sometimes reality doesn't give us that kind of time or flexibility.While the PL/SQL Region is quite powerful, it still lacks a key feature: the ability to be refreshed by a Dynamic Action. This is true even in APEX 5. Fortunately, there's a simple workaround that only requires a small change to your code: change your procedure to a function and call it from a Classic Report region.In changing your procedure to a function, you'll likely only need to make one type of change: converting and htp.prn calls to instead populate and return a variable at the end of the function. Most, if not all of the rest of the code can remain un…