Using Classy to Create Stylesheets for Native iOS Apps

Share this article

Classy is an intriguing project hoping to bridge some gaps between designers more used to web or front end projects and app developers. Classy allows for the use of ‘CSS-esque’ stylesheets to style native iOS app interface components.

Getting Started

Create a basic project in Xcode for our Classy experiments, for now we need to stick to Objective-C, there is no Swift support yet.

Install Classy with CocoaPods, you can find installation, setup and usage instructions here and I will assume you have read and followed them. To install Classy specifically, add it as a dependency to your Podfile and run the install command.

pod 'Classy'
pod install

As is typical with a CocoaPods enabled project, close the current XCode project and instead open the resulting .xcworkspace file.

Making your Interface Classy

Classy by default looks for a stylesheet in your project bundle called stylesheet.cas but this can be overridden :

Stylesheet File

Let’s try something simple and set the background of a button to blue:

UIButton {
    background-color #0000ff
}

Blue Button

Selectors

Classy handles selectors in a nicely CSS-esque way and can be acheived with either Objective-C UIKit classes, view hierarchy (where an elements sits in relation to other elements) and a user defined style class.

For purposes of these examples I have created a simple interface with a Nav Bar, a button and a slider.

Objective-C UIKit classes

Normal Objective-C inheritance applies when styling UIKit elements with classy, but is ignored by default, so:

UIControl {
  background-color #0000ff
}

Does nothing, but reversing this default behavior with a caret:

^UIControl {
  background-color #0000ff
}

Mostyl Blue

Results in changing the background color of the slider and the button, but not the navigation bar as it does not directly inherit UIControl. If we try:

^UIView {
    background-color #0000ff
}

Then everything is blue!

All Blue

View hierarchy

If you’re used to CSS selectors from elements and their place in the document hierarchy, then Classy works in a similar way. Here I add a second button inside another view, or a superview.

Button in a View

To target that button in a view in particular we need to use a more precise selector as the UIView containing the UIButton is itself inside the main UIView for the Storyboard:

UIView > UIView > UIButton {
    background-color #ff0000
}

One Red Button

The caret symbol in this case matches elements that are direct descendants, not all matching descendants.

Style Class

There are times when you might need more precision in selecting interface elements or when figuring out how to target an element is too confusing, in these cases we can give elements special Classy ‘class’.

Add this property in Interface Builder, where value is equal to the name of the class:

Custom Class in Interface Builder

And it can now be referenced in your Classy Stylesheet:

UIButton.redButton {
    background-color #ff0000
}

Style Grouping

This works the same as with CSS, so to give the same style to both our buttons and add an extra style to just one button:

UIView > UIView > UIButton,
UIButton.redButton {
    background-color #ff0000
}

UIButton.redButton {
    title-color #ff0000
}

So much red

Nesting

Classy supports Less or Sass style nesting for generalizing style declarations, for example:

> UIView {

    background-color #00ff00

    > UIView {
        background-color #ff0000

        UIButton {
            title-color #ffff00
        }
    }
}

Creates the following:

Red and Green

Properties

All the Properties and methods available within standard UIAppearance (plus some others) are supported by Classy and use the same naming conventions. So revisiting our earlier example, changing the background color of a button would typically be:

@property(nonatomic,copy) UIColor *backgroundColor;

So far we have been using kebab case properties in our examples, which is more CSS-like, but you can use the Objective-C propety name directly:

UIButton {
    backgroundColor #0000ff
}

Arguments

There are times when UIAppearance expects parameters, for example setting a background image for a UIToolBar:

- (void)setBackgroundImage:(UIImage *)backgroundImage
        forToolbarPosition:(UIBarPosition)topOrBottom
        barMetrics:(UIBarMetrics)barMetrics;

- (void)setShadowImage:(UIImage *)shadowImage
        forToolbarPosition:(UIBarPosition)topOrBottom;

With Classy these are set with enum style argument pairs, so the above example becomes:

UIToolBar {
  background-image[barMetrics:landscape-phone, toolbarPosition:top] imageFile
  shadow-image[barMetrics:landscape-phone, toolbarPosition:bottom] imageFile
}

Variables and Equations

The last Classy feature I will cover is that of variables to reduce repetition and centralize properties, much like in a CSS pre-processor. So our previous:

> UIView {

    background-color #00ff00

    > UIView {
        background-color #ff0000

        UIButton {
            title-color #ffff00
        }
    }
}

Could instead become:

$example-color = #00ff00

> UIView {

    background-color $example-color

    > UIView {
        background-color $example-color

        UIButton {
            title-color $example-color
        }
    }
}

Classy also allows the use of equations for calculating numerical properties based on more than one value, perfect for styling based on screen sizes or incremental changes.

Nesting

Many interface elements in iOS are nested objects with their own properties and Classy does a great job of making logical segmenting the styling of these. For example:

UIButton {
  title-text-attributes: @{
    foreground-color: #00ff00
  }
}

Like What you See? Get Involved

The creators of Classy have done an excellent job of bringing the best of CSS (and related frameworks) into the iOS world and vice versa, and I have only touched upon the features, potential and flexibility of the project. For app developers with a strong design aesthetic and team, it’s a great way of consolidating design and style assets and making a design team feel more part of the actual app development cycle, when typically they are left out after handing over some interface prototypes.

The sad news is that Classy is actively looking for new project maintainers, so if you like what you see and wish the project a long term future, then I recommend you answer the call and get involved.

I’d love to hear your comments and experiences on using Classy.

Chris WardChris Ward
View Author

Developer Relations, Technical Writing and Editing, (Board) Game Design, Education, Explanation and always more to come. English/Australian living in Berlin, Herzlich Willkommen!

AdvancedCSSapplechriswcocoapodiosObjective-C
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week