Module: Sass::Script::Functions

Included in:
EvaluationContext
Defined in:
lib/sass/script/functions.rb

Overview

Methods in this module are accessible from the SassScript context. For example, you can write

!color = hsl(120, 100%, 50%)

and it will call #hsl.

The following functions are provided:

#hsl : Converts an hsl(hue, saturation, lightness) triplet into a color.

#hsla : Converts an hsla(hue, saturation, lightness, alpha) quadruplet into a color.

#rgb : Converts an rgb(red, green, blue) triplet into a color.

#rgba : Converts an rgb(red, green, blue, alpha) triplet into a color.

#red : Gets the red component of a color.

#green : Gets the green component of a color.

#blue : Gets the blue component of a color.

#alpha / #opacity : Gets the alpha component (opacity) of a color.

#opacify / #fade-in : Makes a color more opaque.

#transparentize / #fade-out : Makes a color more transparent.

#percentage : Converts a unitless number to a percentage.

#round : Rounds a number to the nearest whole number.

#ceil : Rounds a number up to the nearest whole number.

#floor : Rounds a number down to the nearest whole number.

#abs : Returns the absolute value of a number.

These functions are described in more detail below.

Adding Custom Functions

New Sass functions can be added by adding Ruby methods to this module. For example:

module Sass::Script::Functions
  def reverse(string)
    assert_type string, :String
    Sass::Script::String.new(string.value.reverse)
  end
end

There are a few things to keep in mind when modifying this module. First of all, the arguments passed are Literal objects. Literal objects are also expected to be returned. This means that Ruby values must be unwrapped and wrapped.

Most Literal objects support the value accessor for getting their Ruby values. Color objects, though, must be accessed using rgb, red, green, or blue.

Second, making Ruby functions accessible from Sass introduces the temptation to do things like database access within stylesheets. This temptation must be resisted. Keep in mind that Sass stylesheets are only compiled once at a somewhat indeterminate time and then left as static CSS files. Any dynamic CSS should be left in <style> tags in the HTML.

Within one of the functions in this module, methods of EvaluationContext can be used.

Defined Under Namespace

Classes: EvaluationContext

Instance Method Summary collapse

Instance Method Details

#abs(value) ⇒ Number

Finds the absolute value of a number. For example:

abs(10px) => 10px
abs(-10px) => 10px

Parameters:

  • value (Number)

    The number

Returns:

  • (Number)

    The absolute value

Raises:



381
382
383
# File 'lib/sass/script/functions.rb', line 381

def abs(value)
  numeric_transformation(value) {|n| n.abs}
end

#alpha(color) ⇒ Number Also known as: opacity

Returns the alpha component (opacity) of a color. This is 1 unless otherwise specified.

Parameters:

Returns:

Raises:

  • (ArgumentError)

    If color isn't a color



262
263
264
265
# File 'lib/sass/script/functions.rb', line 262

def alpha(color)
  assert_type color, :Color
  Sass::Script::Number.new(color.alpha)
end

#blue(color) ⇒ Number

Returns the blue component of a color.

Parameters:

Returns:

Raises:

  • (ArgumentError)

    If color isn't a color



251
252
253
254
# File 'lib/sass/script/functions.rb', line 251

def blue(color)
  assert_type color, :Color
  Sass::Script::Number.new(color.blue)
end

#ceil(value) ⇒ Number

Rounds a number up to the nearest whole number. For example:

ciel(10.4px) => 11px
ciel(10.6px) => 11px

Parameters:

  • value (Number)

    The number

Returns:

  • (Number)

    The rounded number

Raises:



355
356
357
# File 'lib/sass/script/functions.rb', line 355

def ceil(value)
  numeric_transformation(value) {|n| n.ceil}
end

#floor(value) ⇒ Number

Rounds down to the nearest whole number. For example:

floor(10.4px) => 10px
floor(10.6px) => 10px

Parameters:

  • value (Number)

    The number

Returns:

  • (Number)

    The rounded number

Raises:



368
369
370
# File 'lib/sass/script/functions.rb', line 368

def floor(value)
  numeric_transformation(value) {|n| n.floor}
end

#green(color) ⇒ Number

Returns the green component of a color.

Parameters:

Returns:

Raises:

  • (ArgumentError)

    If color isn't a color



241
242
243
244
# File 'lib/sass/script/functions.rb', line 241

def green(color)
  assert_type color, :Color
  Sass::Script::Number.new(color.green)
end

#hsl(hue, saturation, lightness) ⇒ Color

Creates a Color object from hue, saturation, and lightness. Uses the algorithm from the CSS3 spec.

Parameters:

  • hue (Number)

    The hue of the color. Should be between 0 and 360 degrees, inclusive

  • saturation (Number)

    The saturation of the color. Must be between 0% and 100%, inclusive

  • lightness (Number)

    The lightness of the color. Must be between 0% and 100%, inclusive

Returns:

  • (Color)

    The resulting color

Raises:

  • (ArgumentError)

    if saturation or lightness are out of bounds



178
179
180
# File 'lib/sass/script/functions.rb', line 178

def hsl(hue, saturation, lightness)
  hsla(hue, saturation, lightness, Number.new(1))
end

#hsla(hue, saturation, lightness, alpha) ⇒ Color

Creates a Color object from hue, saturation, and lightness, as well as an alpha channel indicating opacity. Uses the algorithm from the CSS3 spec.

Parameters:

  • hue (Number)

    The hue of the color. Should be between 0 and 360 degrees, inclusive

  • saturation (Number)

    The saturation of the color. Must be between 0% and 100%, inclusive

  • lightness (Number)

    The lightness of the color. Must be between 0% and 100%, inclusive

  • alpha (Number)

    The opacity of the color. Must be between 0 and 1, inclusive

Returns:

  • (Color)

    The resulting color

Raises:

  • (ArgumentError)

    if saturation, lightness, or alpha are out of bounds



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/sass/script/functions.rb', line 196

def hsla(hue, saturation, lightness, alpha)
  assert_type hue, :Number
  assert_type saturation, :Number
  assert_type lightness, :Number
  assert_type alpha, :Number

  unless (0..1).include?(alpha.value)
    raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1")
  end

  original_s = saturation
  original_l = lightness
  # This algorithm is from http://www.w3.org/TR/css3-color#hsl-color
  h, s, l = [hue, saturation, lightness].map { |a| a.value }
  raise ArgumentError.new("Saturation #{s} must be between 0% and 100%") unless (0..100).include?(s)
  raise ArgumentError.new("Lightness #{l} must be between 0% and 100%") unless (0..100).include?(l)

  h = (h % 360) / 360.0
  s /= 100.0
  l /= 100.0

  m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s
  m1 = l * 2 - m2
  Color.new(
    [hue_to_rgb(m1, m2, h + 1.0/3),
      hue_to_rgb(m1, m2, h),
      hue_to_rgb(m1, m2, h - 1.0/3)].map { |c| (c * 0xff).round } +
    [alpha.value])
end

#opacify(color, amount) ⇒ Object Also known as: fade_in

Makes a color more opaque. Takes a color and an amount between 0% and 100% and returns a color that's that much closer to opaque.

For example, 50% will make the color twice as opaque:

opacify(rgba(0, 0, 0, 0.5), 50%) => rgba(0, 0, 0, 0.75)
opacify(rgba(0, 0, 0, 0.8), 50%) => rgba(0, 0, 0, 0.9)
opacify(rgba(0, 0, 0, 0.2), 50%) => rgba(0, 0, 0, 0.8)

Specifically, opacify(color, n%) will make the color n% closer to fully opaque.



280
281
282
283
284
285
286
287
288
289
290
# File 'lib/sass/script/functions.rb', line 280

def opacify(color, amount)
  assert_type color, :Color
  assert_type amount, :Number
  unless (0..100).include?(amount.value)
    raise ArgumentError.new("Amount #{amount} must be between 0% and 100%")
  end

  color = color.dup
  color.alpha += (1 - color.alpha) * (amount.value / 100.0)
  color
end

#percentage(value) ⇒ Number

Converts a decimal number to a percentage. For example:

percentage(100px / 50px) => 200%

Parameters:

  • value (Number)

    The decimal number to convert to a percentage

Returns:

Raises:

  • (ArgumentError)

    If value isn't a unitless number



326
327
328
329
330
331
# File 'lib/sass/script/functions.rb', line 326

def percentage(value)
  unless value.is_a?(Sass::Script::Number) && value.unitless?
    raise ArgumentError.new("#{value.inspect} is not a unitless number")
  end
  Sass::Script::Number.new(value.value * 100, ['%'])
end

#red(color) ⇒ Number

Returns the red component of a color.

Parameters:

Returns:

Raises:

  • (ArgumentError)

    If color isn't a color



231
232
233
234
# File 'lib/sass/script/functions.rb', line 231

def red(color)
  assert_type color, :Color
  Sass::Script::Number.new(color.red)
end

#rgb(red, green, blue) ⇒ Object

Creates a Color object from red, green, and blue values.

Parameters:

  • red

    A number between 0 and 255 inclusive

  • green

    A number between 0 and 255 inclusive

  • blue

    A number between 0 and 255 inclusive



134
135
136
# File 'lib/sass/script/functions.rb', line 134

def rgb(red, green, blue)
  rgba(red, green, blue, Number.new(1))
end

#rgba(red, green, blue, alpha) ⇒ Object

Creates a Color object from red, green, and blue values, as well as an alpha channel indicating opacity.

Parameters:

  • red

    A number between 0 and 255 inclusive

  • green

    A number between 0 and 255 inclusive

  • blue

    A number between 0 and 255 inclusive

  • alpha

    A number between 0 and 1



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/sass/script/functions.rb', line 149

def rgba(red, green, blue, alpha)
  assert_type red, :Number
  assert_type green, :Number
  assert_type blue, :Number
  assert_type alpha, :Number

  [red.value, green.value, blue.value].each do |v|
    next if (0..255).include?(v)
    raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive")
  end

  unless (0..1).include?(alpha.value)
    raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1 inclusive")
  end

  Color.new([red.value, green.value, blue.value, alpha.value])
end

#round(value) ⇒ Number

Rounds a number to the nearest whole number. For example:

round(10.4px) => 10px
round(10.6px) => 11px

Parameters:

  • value (Number)

    The number

Returns:

  • (Number)

    The rounded number

Raises:



342
343
344
# File 'lib/sass/script/functions.rb', line 342

def round(value)
  numeric_transformation(value) {|n| n.round}
end

#transparentize(color, amount) ⇒ Object Also known as: fade_out

Makes a color more transparent. Takes a color and an amount between 0% and 100% and returns a color that's that much closer to transparent.

For example, 50% will make the color twice as transparent:

opacify(rgba(0, 0, 0, 0.5), 50%) => rgba(0, 0, 0, 0.25)
opacify(rgba(0, 0, 0, 0.8), 50%) => rgba(0, 0, 0, 0.4)
opacify(rgba(0, 0, 0, 0.2), 50%) => rgba(0, 0, 0, 0.1)

Specifically, transparentize(color, n%) will make the color n% closer to fully transparent.



305
306
307
308
309
310
311
312
313
314
315
# File 'lib/sass/script/functions.rb', line 305

def transparentize(color, amount)
  assert_type color, :Color
  assert_type amount, :Number
  unless (0..100).include?(amount.value)
    raise ArgumentError.new("Amount #{amount} must be between 0% and 100%")
  end

  color = color.dup
  color.alpha *= 1 - (amount.value / 100.0)
  color
end