Fork us on GitHub

Rounded Corners, Gradients, and Shadows with CSS

The new Codename One CSS library enables you to create entire...
Post Image

Rounded Corners, Gradients, and Shadows with CSS

Codename One provides you with the tools to craft a visually stunning and unique user interface via its pluggable look and feel. For simple use cases, you can define styles entirely by setting style properties either in code or the resource editor. However, to achieve best results (for anything more complicated than a solid background color with a rectangular border), you will often want to use image borders and backgrounds. The usual process for styling elements in Codename One is:

  1. Find or create an image that encapsulates the background and border of the element.

  2. Import the image into your theme as a multi-image.

  3. Slice the image into a 9-piece border if you want the element to be able to adapt to different sizes.

This process is described in great detail in this blog post.

This process is extremely flexible, since you can use it to convert pretty much any design into an app. However, for many common use cases such as rounded borders, I would prefer to be able to automatically generate these image borders and backgrounds without having to create an image, import it, and slice it.

The new Codename One CSS library allows you to do just that. The library enables you to create entire themes using only CSS, but in this post, I’m going to focus on its ability to automatically generate image backgrounds and borders for your apps.

Rounded Corners

The following a CSS definition for a minimal rounded button.

Round1 {
    width: 40pt;
    height: 40pt;
    border-radius: 20pt;
    border: 1pt solid black;
    text-align: center;
}

The result will be a button that looks like this:

bf41a490 7329 11e5 9fdf 973404d20f65

How it works:

At compile-time, the CSS library compiles the CSS file into a codename one resource file. Each element selector (in the example above this is "Round1") is converted into a UIID/Style that can be referenced from your codename one application. If the CSS styles specified can be expressed completely by Codename One style properties (e.g. padding, margin, font, simple borders, etc…​), then the resulting UIID will be more or less a direct conversion of the CSS properties. If, however, the CSS styles mandate a background or border that Codename One cannot express using its regular styles (e.g. rounded corners, shadows, gradients), then an appropriate image border or background will be generated and saved in the resource file as a multi-image.

In the above example, we specify that the "Round1" UIID should include rounded corners with a radius of 20pt. Since Codename One doesn’t support rounded corners natively, the CSS module will (at compile time) generate a an image with the appropriate rounded border and use this in an image border for the "Round1" UIID.

Inner Shadows

Let’s spice up our button a bit more by adding shadows into the mix. Add this CSS snippet:

Round1InnerShadow {
    cn1-derive: Round1;
    box-shadow: inset 0px 0px 21pt 10pt rgba(61,59,61,0.48);
    border: 1pt solid transparent;
}

This defines a new UIID named "Round1InnerShadow" that derives from the "Round1" UIID (i.e. inherits all of its properties), but changes to a transparent border, and adds an inner shadow.

And the result is

f2317810 732b 11e5 82b4 e6ea31fc1e6b

Outer Shadows

Let’s shift gears a bit and make a button that is a little less round, but has a subtle drop-shadow.

Round1OuterShadow {
    cn1-derive: Round1;
    box-shadow: 5pt 5pt 10pt 0px rgba(61,59,61,0.48);
    border-radius: 5pt;
    border: 1pt solid #ccc;
    padding-bottom: 2mm;
    padding-top: 1mm;
}

In this case we reduce the border radius to 5 dips, and we have removed the inset marker from the box-shadow property so that the shadow will be outside the button. After some experimentation I also found that a little bit of padding helps for the look of the button in this case.

The result:

e5185556 7333 11e5 9706 c44eb9eea001

Gradients

I could go on and on with different cool CSS effects that you can generate, but I’ll stop at this one last one: Gradients.

Codename One has been capable of generating gradient backgrounds at runtime for quite some time, but we are told not to use them because they are "slow". Instead we are instructed to create an image with the gradient that we want, and then use it as a background image.

Using CSS and the linear-gradient or radial-gradient property, you can have your cake and eat it too since it will generate the gradients as images at compile-time, then use them as image backgrounds (or image borders) in your theme.

Round1Gradient {
    cn1-derive: Round1OuterShadow;
    background: linear-gradient(to bottom,
        rgba(242,246,248,1) 0%,
        rgba(216,225,231,1) 50%,
        rgba(181,198,208,1) 51%,
        rgba(224,239,249,1) 100%
    );
}

The result:

d5131086 7335 11e5 8fc5 c8183f1b1ecb

Generating the CSS

For those of you who don’t speak CSS fluently yet, you will be happy to learn that the 'net is filled with online tools for generating CSS borders, shadows, and gradients for you. One such tool is this CSSMatic tool. You just enter the values that you want for color, border-radius, etc.., and it spits out some shiny CSS for you to just paste into your stylesheet.

However You will probably want to modify the CSS that it generates just a little bit:

  1. Change all px units to pt. This will cause the coordinate to be scaled appropriate for the device density.

  2. Only include the standard CSS properties, not the browser-specific ones. Browser specific property names will be prefixed by one of -moz-, -webkit, or some other prefix beginning with "-". E.g. The tool output the following CSS for a rounded border:

    border-radius: 10px 10px 10px 10px;
    -moz-border-radius: 10px 10px 10px 10px;
    -webkit-border-radius: 10px 10px 10px 10px;
    border: 0px solid #000000;

    We would change this to

    border-radius: 10pt 10pt 10pt 10pt;
    border: 0px solid #000000;

Where Do I Put My CSS File?

"This CSS looks really nice, but where to I put it, and how to I set up the CSS module?", you say. I’m glad you asked. The CSS compiler will look for .css files inside your project’s "css" directory (which you’ll need to create). It will compiles these CSS files into corresponding .res files which will be placed into your project’s src directory. You can then load this theme in your app just as you would load any other theme file.

Codename One CSS flow chart

E.g.

Suppose you add a CSS file into your project css/theme.css. When you compile your project, it will generate the file src/theme.css.res. Then you can load this file in your app as follows:

Resources css = Resources.openLayered("/theme.css");
UIManager.getInstance().addThemeProps(css.getTheme(css.getThemeResourceNames()[0]));

You can download the Codename One CSS library and read the installation instructions in the CN1-CSS Repository on GitHub.

Share this Post:

Posted by Steve Hannah

Steve writes software for Codename One. He is an open source enthusiast who loves to tinker with new technologies.