Skip to content
Sean Smith edited this page Mar 5, 2020 · 11 revisions

Stylesheet format

InterfaCSS does not try to impose some artificial mapping layer between the stylesheet format and iOS - the names of stylesheet properties are the same as the actual UI object properties they set (except that case is not important and you may insert dashes anywhere you fancy).

The format of the stylesheet files used by InterfaCSS is in structure essentially the same as standard CSS used for the web - what differs is basically the properties you can use and the supported selectors (although you can actually use most of the standard W3C CSS selectors).

Selectors

  • Type (e.g. UILabel), style class (e.g. .myStyleClass), element id (e.g. #myElement), and wildcard (*) selectors are supported.
  • Multiple style classes can be chained, e.g. .class1.class2 (version 1.5).
  • The default set of supported type selectors are the UIKit classes mentioned in the stylesheet reference, such as UIView, UILabel, UIButton etc (case insensitive, 'UI' is optional).
  • Custom classes are also supported as type selectors (type selector must match existing class name exactly).
  • View controller classes may also be used as type selectors.

Selector chains - match declarations against particular hierarchy of elements

  • InterfaCSS supports descendant (whitespace), child (>), adjacent sibling (+) and general sibling (~) selector combinators.
  • Multiple selectors / selector chains may be specified for each declaration block (separated by comma).
  • Nested declarations can be used as a convenient way to create descendant selector chains.
UIButton UILabel { /* Matches any UILabel that has a UIButton as an ancestor (i.e. superview, superview's superview etc) */
}

UIButton {
    UILabel { /* Example of a nested declaration, which results in the same descendant selector chain as above */
    }
}

UIButton > UILabel { /* Matches any UILabel that has a UIButton as a superview */
}

UITableViewCell > * > UILabel { /* Matches any UILabel that is the grandchild of a UITableViewCell */
}

#someElement .someClass UILabel { 
/* Matches any UILabel that has an ancestor element with the style class 'someClass', and which in turn has an 
ancestor element with the element ID 'someElement' */
}

Pseudo classes

  • InterfaCSS supports these types of pseudo classes:
    • Interface orientation: landscape, landscapeLeft, landscapeRight, portrait, portraitUpright, portraitUpSideDown
    • Device type: pad, phone, tv
    • Size classes: regularWidth, compactWidth, regularHeight, compactHeight
    • OS version and device model: minosversion, maxosversion, devicemodel
    • Screen dimensions: screenwidth, screenwidthlessthan, screenwidthgreaterthan, screenheight, screenheightlessthan, screenheightgreaterthan
    • Element state: enabled, disabled, selected, highlighted (for UIControl and others)
    • Structural pseudo classes, such as root (matches if element is the root view of a view controller), firstChild, lastOfType etc

  • Multiple pseudo classes can be chained (e.g. .style:pad:landscape).

Order of multiple matching declarations

  • If multiple declarations match, the last one wins. This rule also applies to stylesheets, i.e the stylesheet added last may override declarations in previously added stylesheets.

  • You can also optionally enable use of W3C style selector specificity, by setting the flag useSelectorSpecificity to YES. Doing so will ensure that the specificity rules will apply regardless of in which stylesheet the a declaration was found.

Wide range of supported properties

  • A wide range of common UIKit properties can be set - for a complete reference, see the Stylesheet Property Reference.

  • Support for expressing a range of different value types, such as font, colors, images, transform, insets, offsets, rects, enums, attributed strings etc.

  • Support properties that are bound to a certain UIControlState (for instance): titleColor(highlighted): red; - read more here.

  • Setting nested properties on certain nested views, i.e. for instance titleLabel.font. These are the nested views that are supported at the moment: imageView, contentView, backgroundView, selectedBackgroundView, multipleSelectionBackgroundView, titleLabel, textLabel, detailTextLabel, inputView, inputAccessoryView, tableHeaderView and tableFooterView.

  • Support for locking a property to its current value (through the current keyword / value). This can for instance be helpful to ensure that values set in code are retained even when styles are re-applied.

  • Custom properties (and nested properties) can be registered using ISSPropertyRegistry. You can also override and extend already registered properties.

Variables

  • Variables (mostly used as constants really, but they can actually be modified at runtime...) can be used to express property values that need to be the same in multiple places.

  • When a variable has been defined by a stylesheet, it will be available to any stylesheets loaded thereafter.

@stdFont1: GillSans-Bold 14;

UILabel {
    font: @stdFont1;
}

Extending existing declarations (version 1.5)

Using the @extend keyword, you can reuse the styles in another declaration. This is particularly useful when the application uses multiple stylesheets, and you don't want to keep adding more selectors to a base declaration.

.rounded {
    clipsToBounds: true;
    cornerRadius: 4;
}

.roundedRed {
    @extend .rounded;
    backgroundColor: red;
}

The @extend declaration will throw a warning if it is not declared as the first line following the {.

Example of an invalid declaration of the @extend keyword:

.roundedRed {
    /* This is rounded but with a red background color. */
    @extend .rounded;
    backgroundColor: red;
}

Will produce the warning message:

InterfaCSS: <ISSDefaultStyleSheetParser: 0x600003bccd10> - Warning! Unrecognized property line: '@extend .rounded;' - in declaration: .roundedRed

Comments

Comments can either be expressed on the standard CSS form /* comment */, but also using the // prefix.

// Comment
/* Another comment */