Module: Sass::Script::Functions
- 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(120deg, 100%, 50%)
and it will call #hsl.
The following functions are provided:
RGB Functions
#rgb
: Converts an rgb(red, green, blue)
triplet into a color.
#rgba
: Converts an rgba(red, green, blue, alpha)
quadruplet 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.
#mix : Mixes two colors together.
HSL Functions
#hsl
: Converts an hsl(hue, saturation, lightness)
triplet into a color.
#hsla
: Converts an hsla(hue, saturation, lightness, alpha)
quadruplet into a color.
#hue : Gets the hue component of a color.
#saturation : Gets the saturation component of a color.
#lightness : Gets the lightness component of a color.
#adjust-hue : Changes the hue of a color.
#lighten : Makes a color lighter.
#darken : Makes a color darker.
#saturate : Makes a color more saturated.
#desaturate : Makes a color less saturated.
#grayscale : Converts a color to grayscale.
#complement : Returns the complement of a color.
Opacity Functions
#alpha / #opacity : Gets the alpha component (opacity) of a color.
#rgba : Sets the alpha component of a color.
#opacify / #fade-in : Makes a color more opaque.
#transparentize / #fade-out : Makes a color more transparent.
String Functions
#unquote : Removes the quotes from a string.
#quote : Adds quotes to a string.
Number Functions
#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 is generally a bad idea; since Sass files are by default only compiled once, dynamic code is not a great fit.
If you really, really need to compile Sass on each request,
first make sure you have adequate caching set up.
Then you can use Engine to render the code,
using the options
parameter
to pass in data that can be accessed
from your Sass functions.
Within one of the functions in this module, methods of EvaluationContext can be used.
Caveats
When creating new Literal objects within functions, be aware that it's not safe to call #to_s (or other methods that use the string representation) on those objects without first setting the #options attribute.
Defined Under Namespace
Classes: EvaluationContext
Instance Method Summary collapse
-
#abs(value) ⇒ Number
Finds the absolute value of a number.
-
#adjust_hue(color, degrees) ⇒ Color
Changes the hue of a color while retaining the lightness and saturation.
-
#alpha(color) ⇒ Number
Returns the alpha component (opacity) of a color.
-
#blue(color) ⇒ Number
Returns the blue component of a color.
-
#ceil(value) ⇒ Number
Rounds a number up to the nearest whole number.
-
#complement(color) ⇒ Color
Returns the complement of a color.
-
#darken(color, amount) ⇒ Color
Makes a color darker.
-
#desaturate(color, amount) ⇒ Color
Makes a color less saturated.
-
#floor(value) ⇒ Number
Rounds down to the nearest whole number.
-
#grayscale(color) ⇒ Color
Converts a color to grayscale.
-
#green(color) ⇒ Number
Returns the green component of a color.
-
#hsl(hue, saturation, lightness) ⇒ Color
Creates a Color object from hue, saturation, and lightness.
-
#hsla(hue, saturation, lightness, alpha) ⇒ Color
Creates a Color object from hue, saturation, and lightness, as well as an alpha channel indicating opacity.
-
#hue(color) ⇒ Number
Returns the hue component of a color.
-
#lighten(color, amount) ⇒ Color
Makes a color lighter.
-
#lightness(color) ⇒ Number
Returns the hue component of a color.
-
#mix(color1, color2, weight = 50%) ⇒ Color
Mixes together two colors.
-
#opacify(color, amount) ⇒ Color
(also: #fade_in)
Makes a color more opaque.
-
#opacity(color) ⇒ Number
Returns the alpha component (opacity) of a color.
-
#percentage(value) ⇒ Number
Converts a decimal number to a percentage.
-
#quote(str) ⇒ String
Add quotes to a string if the string isn't quoted, or returns the same string if it is.
-
#red(color) ⇒ Number
Returns the red component of a color.
-
#rgb(red, green, blue) ⇒ Color
Creates a Color object from red, green, and blue values.
- #rgba(*args)
-
#round(value) ⇒ Number
Rounds a number to the nearest whole number.
-
#saturate(color, amount) ⇒ Color
Makes a color more saturated.
-
#saturation(color) ⇒ Number
Returns the saturation component of a color.
-
#transparentize(color, amount) ⇒ Color
(also: #fade_out)
Makes a color more transparent.
-
#unquote(value) ⇒ String
Removes quotes from a string if the string is quoted, or returns the same string if it's not.
Instance Method Details
#abs(value) ⇒ Number
Finds the absolute value of a number. For example:
abs(10px) => 10px
abs(-10px) => 10px
735 736 737 |
# File 'lib/sass/script/functions.rb', line 735
def abs(value)
numeric_transformation(value) {|n| n.abs}
end
|
#adjust_hue(color, degrees) ⇒ Color
Changes the hue of a color while retaining the lightness and saturation. Takes a color and a number of degrees (usually between -360deg and 360deg), and returns a color with the hue rotated by that value.
For example:
adjust-hue(hsl(120, 30%, 90%), 60deg) => hsl(180, 30%, 90%)
adjust-hue(hsl(120, 30%, 90%), 060deg) => hsl(60, 30%, 90%)
adjust-hue(#811, 45deg) => #886a11
548 549 550 551 552 |
# File 'lib/sass/script/functions.rb', line 548
def adjust_hue(color, degrees)
assert_type color, :Color
assert_type degrees, :Number
color.with(:hue => color.hue + degrees.value)
end
|
#alpha(color) ⇒ Number
Returns the alpha component (opacity) of a color. This is 1 unless otherwise specified.
This function also supports the proprietary Microsoft
alpha(opacity=20)
syntax.
401 402 403 404 405 406 407 408 409 410 411 |
# File 'lib/sass/script/functions.rb', line 401
def alpha(*args)
if args.all? do |a|
a.is_a?(Sass::Script::String) && a.type == :identifier &&
a.value =~ /^[a-zA-Z]+\s*=/
end
# Support the proprietary MS alpha() function
return Sass::Script::String.new("alpha(#{args.map {|a| a.to_s}.join(", ")})")
end
opacity(*args)
end
|
#blue(color) ⇒ Number
Returns the blue component of a color.
344 345 346 347 |
# File 'lib/sass/script/functions.rb', line 344
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
709 710 711 |
# File 'lib/sass/script/functions.rb', line 709
def ceil(value)
numeric_transformation(value) {|n| n.ceil}
end
|
#complement(color) ⇒ Color
Returns the complement of a color.
This is identical to adjust-hue(color, 180deg)
.
638 639 640 |
# File 'lib/sass/script/functions.rb', line 638
def complement(color)
adjust_hue color, Number.new(180)
end
|
#darken(color, amount) ⇒ Color
Makes a color darker. Takes a color and an amount between 0% and 100%, and returns a color with the lightness decreased by that value.
For example:
darken(hsl(25, 100%, 80%), 30%) => hsl(25, 100%, 50%)
darken(#800, 20%) => #200
494 495 496 |
# File 'lib/sass/script/functions.rb', line 494
def darken(color, amount)
adjust(color, amount, :lightness, 0..100, :-, "%")
end
|
#desaturate(color, amount) ⇒ Color
Makes a color less saturated. Takes a color and an amount between 0% and 100%, and returns a color with the saturation decreased by that value.
For example:
desaturate(hsl(120, 30%, 90%), 20%) => hsl(120, 10%, 90%)
desaturate(#855, 20%) => #726b6b
530 531 532 |
# File 'lib/sass/script/functions.rb', line 530
def desaturate(color, amount)
adjust(color, amount, :saturation, 0..100, :-, "%")
end
|
#floor(value) ⇒ Number
Rounds down to the nearest whole number. For example:
floor(10.4px) => 10px
floor(10.6px) => 10px
722 723 724 |
# File 'lib/sass/script/functions.rb', line 722
def floor(value)
numeric_transformation(value) {|n| n.floor}
end
|
#grayscale(color) ⇒ Color
Converts a color to grayscale.
This is identical to desaturate(color, 100%)
.
627 628 629 |
# File 'lib/sass/script/functions.rb', line 627
def grayscale(color)
desaturate color, Number.new(100)
end
|
#green(color) ⇒ Number
Returns the green component of a color.
334 335 336 337 |
# File 'lib/sass/script/functions.rb', line 334
def green(color)
assert_type color, :Color
Sass::Script::Number.new(color.green)
end
|
#hsl(hue, saturation, lightness) ⇒ Color
281 282 283 |
# File 'lib/sass/script/functions.rb', line 281
def hsl(hue, saturation, lightness)
hsla(hue, saturation, lightness, Number.new(1))
end
|
#hsla(hue, saturation, lightness, alpha) ⇒ Color
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/sass/script/functions.rb', line 299
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)
Color.new(:hue => h, :saturation => s, :lightness => l, :alpha => alpha.value)
end
|
#hue(color) ⇒ Number
Returns the hue component of a color.
See the CSS3 HSL specification.
Calculated from RGB where necessary via this algorithm.
358 359 360 361 |
# File 'lib/sass/script/functions.rb', line 358
def hue(color)
assert_type color, :Color
Sass::Script::Number.new(color.hue, ["deg"])
end
|
#lighten(color, amount) ⇒ Color
Makes a color lighter. Takes a color and an amount between 0% and 100%, and returns a color with the lightness increased by that value.
For example:
lighten(hsl(0, 0%, 0%), 30%) => hsl(0, 0, 30)
lighten(#800, 20%) => #e00
476 477 478 |
# File 'lib/sass/script/functions.rb', line 476
def lighten(color, amount)
adjust(color, amount, :lightness, 0..100, :+, "%")
end
|
#lightness(color) ⇒ Number
Returns the hue component of a color.
See the CSS3 HSL specification.
Calculated from RGB where necessary via this algorithm.
386 387 388 389 |
# File 'lib/sass/script/functions.rb', line 386
def lightness(color)
assert_type color, :Color
Sass::Script::Number.new(color.lightness, ["%"])
end
|
#mix(color1, color2, weight = 50%) ⇒ Color
Mixes together two colors. Specifically, takes the average of each of the RGB components, optionally weighted by the given percentage. The opacity of the colors is also considered when weighting the components.
The weight specifies the amount of the first color that should be included in the returned color. The default, 50%, means that half the first color and half the second color should be used. 25% means that a quarter of the first color and three quarters of the second color should be used.
For example:
mix(#f00, #00f) => #7f007f
mix(#f00, #00f, 25%) => #3f00bf
mix(rgba(255, 0, 0, 0.5), #00f) => rgba(63, 0, 191, 0.75)
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 |
# File 'lib/sass/script/functions.rb', line 579
def mix(color1, color2, weight = Number.new(50))
assert_type color1, :Color
assert_type color2, :Color
assert_type weight, :Number
unless (0..100).include?(weight.value)
raise ArgumentError.new("Weight #{weight} must be between 0% and 100%")
end
# This algorithm factors in both the user-provided weight
# and the difference between the alpha values of the two colors
# to decide how to perform the weighted average of the two RGB values.
#
# It works by first normalizing both parameters to be within [-1, 1],
# where 1 indicates "only use color1", -1 indicates "only use color 0",
# and all values in between indicated a proportionately weighted average.
#
# Once we have the normalized variables w and a,
# we apply the formula (w + a)/(1 + w*a)
# to get the combined weight (in [-1, 1]) of color1.
# This formula has two especially nice properties:
#
# * When either w or a are -1 or 1, the combined weight is also that number
# (cases where w * a == -1 are undefined, and handled as a special case).
#
# * When a is 0, the combined weight is w, and vice versa
#
# Finally, the weight of color1 is renormalized to be within [0, 1]
# and the weight of color2 is given by 1 minus the weight of color1.
p = weight.value/100.0
w = p*2 - 1
a = color1.alpha - color2.alpha
w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0
w2 = 1 - w1
rgb = color1.rgb.zip(color2.rgb).map {|v1, v2| v1*w1 + v2*w2}
alpha = color1.alpha*p + color2.alpha*(1-p)
Color.new(rgb + [alpha])
end
|
#opacify(color, amount) ⇒ Color Also known as: fade_in
Makes a color more opaque. Takes a color and an amount between 0 and 1, and returns a color with the opacity increased by that value.
For example:
opacify(rgba(0, 0, 0, 0.5), 0.1) => rgba(0, 0, 0, 0.6)
opacify(rgba(0, 0, 17, 0.8), 0.2) => #001
438 439 440 |
# File 'lib/sass/script/functions.rb', line 438
def opacify(color, amount)
adjust(color, amount, :alpha, 0..1, :+)
end
|
#opacity(color) ⇒ Number
Returns the alpha component (opacity) of a color. This is 1 unless otherwise specified.
419 420 421 422 |
# File 'lib/sass/script/functions.rb', line 419
def opacity(color)
assert_type color, :Color
Sass::Script::Number.new(color.alpha)
end
|
#percentage(value) ⇒ Number
Converts a decimal number to a percentage. For example:
percentage(100px / 50px) => 200%
680 681 682 683 684 685 |
# File 'lib/sass/script/functions.rb', line 680
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
|
#quote(str) ⇒ String
Add quotes to a string if the string isn't quoted, or returns the same string if it is.
quote("foo") => "foo" quote(foo) => "foo"
667 668 669 670 |
# File 'lib/sass/script/functions.rb', line 667
def quote(str)
assert_type str, :String
Sass::Script::String.new(str.value, :string)
end
|
#red(color) ⇒ Number
Returns the red component of a color.
324 325 326 327 |
# File 'lib/sass/script/functions.rb', line 324
def red(color)
assert_type color, :Color
Sass::Script::Number.new(color.red)
end
|
#rgb(red, green, blue) ⇒ Color
Creates a Color object from red, green, and blue values.
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/sass/script/functions.rb', line 207
def rgb(red, green, blue)
assert_type red, :Number
assert_type green, :Number
assert_type blue, :Number
Color.new([red, green, blue].map do |c|
v = c.value
if c.numerator_units == ["%"] && c.denominator_units.empty?
next v * 255 / 100.0 if (0..100).include?(v)
raise ArgumentError.new("Color value #{c} must be between 0% and 100% inclusive")
else
next v if (0..255).include?(v)
raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive")
end
end)
end
|
#rgba(red, green, blue, alpha) ⇒ Color #rgba(color, alpha) ⇒ Color
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/sass/script/functions.rb', line 249
def rgba(*args)
case args.size
when 2
color, alpha = args
assert_type color, :Color
assert_type alpha, :Number
unless (0..1).include?(alpha.value)
raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1 inclusive")
end
color.with(:alpha => alpha.value)
when 4
red, green, blue, alpha = args
rgba(rgb(red, green, blue), alpha)
else
raise ArgumentError.new("wrong number of arguments (#{args.size} for 4)")
end
end
|
#round(value) ⇒ Number
Rounds a number to the nearest whole number. For example:
round(10.4px) => 10px
round(10.6px) => 11px
696 697 698 |
# File 'lib/sass/script/functions.rb', line 696
def round(value)
numeric_transformation(value) {|n| n.round}
end
|
#saturate(color, amount) ⇒ Color
Makes a color more saturated. Takes a color and an amount between 0% and 100%, and returns a color with the saturation increased by that value.
For example:
saturate(hsl(120, 30%, 90%), 20%) => hsl(120, 50%, 90%)
saturate(#855, 20%) => #9e3f3f
512 513 514 |
# File 'lib/sass/script/functions.rb', line 512
def saturate(color, amount)
adjust(color, amount, :saturation, 0..100, :+, "%")
end
|
#saturation(color) ⇒ Number
Returns the saturation component of a color.
See the CSS3 HSL specification.
Calculated from RGB where necessary via this algorithm.
372 373 374 375 |
# File 'lib/sass/script/functions.rb', line 372
def saturation(color)
assert_type color, :Color
Sass::Script::Number.new(color.saturation, ["%"])
end
|
#transparentize(color, amount) ⇒ Color Also known as: fade_out
Makes a color more transparent. Takes a color and an amount between 0 and 1, and returns a color with the opacity decreased by that value.
For example:
transparentize(rgba(0, 0, 0, 0.5), 0.1) => rgba(0, 0, 0, 0.4)
transparentize(rgba(0, 0, 0, 0.8), 0.2) => rgba(0, 0, 0, 0.6)
457 458 459 |
# File 'lib/sass/script/functions.rb', line 457
def transparentize(color, amount)
adjust(color, amount, :alpha, 0..1, :-)
end
|
#unquote(value) ⇒ String
Removes quotes from a string if the string is quoted, or returns the same string if it's not.
unquote("foo") => foo unquote(foo) => foo
652 653 654 655 |
# File 'lib/sass/script/functions.rb', line 652
def unquote(str)
assert_type str, :String
Sass::Script::String.new(str.value, :identifier)
end
|