In CSS each attribute has its own syntax describing its legal value(s). In ScalaCSS most CSS attributes have their value syntaxes encoded, but not all.
You can browse defined attributes in Attrs.scala.
To use an attribute that doesn't have a typed value syntax yet,
use the :=
operator.
Example:
font := "monochrome"
font := "'Times New Roman', Times, serif"
font := ^.auto // The DSL provides ^ as a shortcut for Literal.
That's all there is to it.
Most attributes have their value syntax encoded.
These attributes are objects
that extend TypedAttrBase
.
They have methods that facilitate legal values in a type-safe manner.
To use, simply explore their methods.
Example:
margin.auto
margin.inherit
margin.`0`
margin(12 px)
margin(12 px, auto)
margin(12 px, auto, 16 px, 4 ex)
textDecorationLine.overline
textDecorationLine.underline
textDecorationLine.underline.overline
The following DSL is available for specifying colours.
DSL | Example | Description |
---|---|---|
c"<literal>" |
c"#37b" c"#ffcc99" |
Specify a literal colour and have the compiler verify that it is a valid #RGB , #RRGGBB , or {rgb,hsl}{,a} function with valid arguments. |
<name> |
red black |
A colour literal, specified in the CSS spec. |
rgb(int x 3) |
rgb(0, 128, 0) |
Combines red, green and blue values [0-255]. |
rgb(percentage x 3) |
rgb(0.%%, 50.%%, 0.%%) |
Red, green and blue percentages. |
rgba(int x 3, double) |
rgba(0, 128, 0, 0.5) |
Red, green and blue values [0-255] with an alpha component [0-1]. |
hsl(int, percentage x 2) |
hsl(300, 50.%%, 10.%%) |
Hue [0-360], saturation and lightness. |
hsla(int, percentage x 2, double) |
hsla(300, 50.%%, 10.%%, 0.5) |
Hue [0-360], saturation, lightness and alpha [0-1]. |
grey(int) |
grey(224) |
A greyscale colour [0-255] with the specified amount of red, green and blue. |
<keyword> |
transparent currentColor inherit |
Any other keywords that are legal as, or in place of colours in the CSS spec can be used as is. |
Color("<literal>") |
Color("i break you css!") |
Specify a literal colour without any compiler validation. |
Using the c"<literal>"
syntax, invalid colours will result in compiler errors.
Example:
backgroundColor(red) // ok
backgroundColor(c"#ffcc99") // ok
backgroundColor(c"#ffcc9o") // compiler error: o is not hex
backgroundColor(c"#ffcc9") // compiler error: 5 digits
backgroundColor(c"hsl(200, 20%, 10%)") // ok
backgroundColor(c"rgb(0%, 20%, 10%)") // ok
backgroundColor(c"rgba(0, 0, 0, 0.5)") // ok
backgroundColor(c"rgb(30, 30, 300)") // compiler error: 300 is too large
backgroundColor(c"rbg(32, 128, 32)") // compiler error: typo in rbg
You can bypass type-safety and provide a manual value.
Similar to the untyped attribute syntax of attr := value
,
for typed attributes the syntax is
attr :=! value
You can use :=
but it will generate compiler warnings.
This mechanism means that when an untyped attribute becomes typed in a ScalaCSS
upgrade, you'll be alerted to all the cases where you're accidently bypassing
type-safety.
Example:
margin := "12px auto" // Compile warns there's a type-safe alternative
margin :=! "auto\\9" // The ! means you know what you're doing
If your favourite attribute doesn't have typed values, please patch it and submit a pull request.
Typing all values is a lot of work for one person and automation only gets one so far. Most are done but not all. If different users contribute a small amount of time to get a few attributes done then they'll all be typed in no time.
This is what an untyped attribute looks like:
val alignItems =
Attr.real("align-items", Transform keys CanIUse.flexbox)
This is what a typed attribute looks like:
object alignItems extends TypedAttrBase {
override val attr = Attr.real("align-items", Transform keys CanIUse.flexbox)
def baseline = av(L.baseline)
def center = av(L.center)
def flexEnd = av(L.flexEnd)
def flexStart = av(L.flexStart)
def stretch = av(L.stretch)
}
There are classes that help with common value syntaxes.
This example uses TypedAttrT1[Len]
to get a 1-arg apply()
method accepting
anything that be considered a length (eg. 12 px
), and ZeroLit
to gain a
`0`
method to indicate a length of 0.
object letterSpacing extends TypedAttrT1[Len] with ZeroLit {
override val attr = Attr.real("letter-spacing")
def normal = av(L.normal)
}