[CSS3] Support for the border-image property.

This commit is contained in:
Chris Eppstein 2010-11-14 16:39:43 -08:00
parent 3ade4e3f3a
commit 4dc455f312
8 changed files with 129 additions and 28 deletions

View File

@ -1,24 +1,5 @@
@import "shared";
@import "compass/utilities/general/hacks";
@mixin background-image(
$image-1, $image-2: false, $image-3: false,
$image-4: false, $image-5: false, $image-6: false,
$image-7: false, $image-8: false, $image-9: false, $image-10: false
) {
$images: compact($image-1, $image-2, $image-3, $image-4 ,$image-5, $image-6, $image-7, $image-8, $image-9, $image-10);
@if $experimental-support-for-webkit and prefixed(-webkit, $images) {
background-image: -webkit($images);
}
@if $experimental-support-for-mozilla and prefixed(-moz, $images) {
background-image: -moz($images);
}
@if $experimental-support-for-svg and prefixed(-svg, $images) {
background-image: -svg($images);
}
background-image: $images;
}
// The linear gradient mixin works best across browsers if you use percentage-based color stops.
//
// Examples:

View File

@ -0,0 +1,34 @@
@import "shared";
@mixin background-image(
$image-1,
$image-2: false,
$image-3: false,
$image-4: false,
$image-5: false,
$image-6: false,
$image-7: false,
$image-8: false,
$image-9: false,
$image-10: false
) {
$images: compact($image-1, $image-2, $image-3, $image-4, $image-5, $image-6, $image-7, $image-8, $image-9, $image-10);
@if $experimental-support-for-mozilla and prefixed(-moz, $images) { background-image: -moz($images); }
@if $experimental-support-for-webkit and prefixed(-webkit, $images) { background-image: -webkit($images); }
@if $experimental-support-for-svg and prefixed(-svg, $images) { background-image: -svg($images); }
background-image: $images;
}
@mixin border-image($value) {
// This is just until we have Official Sass list support in 3.1
$values: -compass-list($value);
$image: -compass-nth($values, first);
$rest: -compass-slice($values, 2);
@if $experimental-support-for-mozilla { -moz-border-image: -moz($image) $rest; }
@if $experimental-support-for-webkit { -webkit-border-image: -webkit($image) $rest; }
@if $experimental-support-for-svg { border-image: -svg($image) $rest; }
border-image: $image $rest;
}

View File

@ -6,6 +6,7 @@
@import "columns";
@import "box-sizing";
@import "box";
@import "images";
@import "gradient";
@import "background-clip";
@import "background-origin";

View File

@ -6,6 +6,7 @@
@import "columns";
@import "box-sizing";
@import "box";
@import "images";
@import "gradient";
@import "background-clip";
@import "background-origin";

View File

@ -5,11 +5,20 @@ module Compass::SassExtensions::Functions::GradientSupport
def initialize(*values)
self.values = values
end
def join_with
", "
end
def inspect
values.map{|v| v.inspect}.join(", ")
to_s
end
def to_s
values.map{|v| v.to_s}.join(", ")
values.map {|v| v.to_s }.join(join_with)
end
end
class SpaceList < List
def join_with
" "
end
end
@ -111,7 +120,6 @@ module Compass::SassExtensions::Functions::GradientSupport
end
end
module Functions
def radial_gradient(position_or_angle, shape_or_size, *color_stops)
@ -260,6 +268,49 @@ module Compass::SassExtensions::Functions::GradientSupport
List.new(*args.reject{|a| !a.to_bool})
end
# Returns a list object from a value that was passed.
# This can be used to unpack a space separated list that got turned
# into a string by sass before it was passed to a mixin.
def _compass_list(arg)
return arg if arg.is_a?(List)
values = case arg
when Sass::Script::String
expr = Sass::Script::Parser.parse(arg.value, 0, 0)
if expr.is_a?(Sass::Script::Operation)
extract_list_values(expr)
elsif expr.is_a?(Sass::Script::Funcall)
expr.perform(Sass::Environment.new) #we already evaluated the args in context so no harm in using a fake env
else
[arg]
end
else
[arg]
end
SpaceList.new(*values)
end
# Get the nth value from a list
def _compass_nth(list, place)
if place.value == "last"
list.values.last
elsif place.value == "first"
list.values.first
else
list.values[place.value - 1]
end
end
# slice a sublist from a list
def _compass_slice(list, start_index, end_index = nil)
end_index ||= Sass::Script::Number.new(-1)
start_index = start_index.value
end_index = end_index.value
start_index -= 1 unless start_index < 0
end_index -= 1 unless end_index < 0
list.class.new *list.values[start_index..end_index]
end
%w(webkit moz o ms svg).each do |prefix|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def _#{prefix}(*args)
@ -269,6 +320,7 @@ module Compass::SassExtensions::Functions::GradientSupport
RUBY
end
# Check if any of the arguments passed have a tendency towards vendor prefixing.
def prefixed(prefix, *args)
method = prefix.value.sub(/^-/,"to_").to_sym
args.map!{|a| a.is_a?(List) ? a.values : a}.flatten!
@ -276,6 +328,28 @@ module Compass::SassExtensions::Functions::GradientSupport
end
private
# After using the sass script parser to parse a string, this reconstructs
# a list from operands to the space/concat operation
def extract_list_values(operation)
left = operation.instance_variable_get("@operand1")
right = operation.instance_variable_get("@operand2")
left = extract_list_values(left) if left.is_a?(Sass::Script::Operation)
right = extract_list_values(right) if right.is_a?(Sass::Script::Operation)
left = literalize(left) unless left.is_a?(Array)
right = literalize(right) unless right.is_a?(Array)
Array(left) + Array(right)
end
# Makes a literal from other various script nodes.
def literalize(node)
case node
when Sass::Script::Literal
node
when Sass::Script::Funcall
node.perform(Sass::Environment.new)
else
Sass::Script::String.new(node.to_s)
end
end
def normalize_stops!(color_list)
positions = color_list.values
# fill in the start and end positions, if unspecified

View File

@ -2,31 +2,37 @@
background-image: url("foo.png"); }
.bg-linear-gradient {
background-image: -moz-linear-gradient(top left, #dddddd, #aaaaaa);
background-image: -webkit-gradient(linear, 0% 0%, 100% 100%, color-stop(0%, #dddddd), color-stop(100%, #aaaaaa));
background-image: -moz-linear-gradient(top left, #dddddd 0%, #aaaaaa 100%);
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+IDxkZWZzPiA8bGluZWFyR3JhZGllbnQgaWQ9ImdyYWQiIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPiA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZGRkZGRkIiAvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2FhYWFhYSIgLz4gPC9saW5lYXJHcmFkaWVudD4gPC9kZWZzPiA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPiA8L3N2Zz4g');
background-image: linear-gradient(top left, #dddddd 0%, #aaaaaa 100%); }
.bg-radial-gradient {
background-image: -moz-radial-gradient(center center, #dddddd, #aaaaaa 100px);
background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, #dddddd), color-stop(100%, #aaaaaa));
background-image: -moz-radial-gradient(center center, #dddddd 0%, #aaaaaa 100px);
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+IDxkZWZzPiA8cmFkaWFsR3JhZGllbnQgaWQ9ImdyYWQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjeD0iNTAlIiBjeT0iNTAlIiByPSIxMDAiPiA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZGRkZGRkIiAvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2FhYWFhYSIgLz4gPC9yYWRpYWxHcmFkaWVudD4gPC9kZWZzPiA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPiA8L3N2Zz4g');
background-image: radial-gradient(center center, #dddddd 0%, #aaaaaa 100px); }
.bg-all-gradient-types {
background-image: url('/images/4x6.png?busted=true'), -moz-linear-gradient(top left, #dddddd, #aaaaaa), -moz-radial-gradient(center center, #dddddd, #aaaaaa 100px);
background-image: url('/images/4x6.png?busted=true'), -webkit-gradient(linear, 0% 0%, 100% 100%, color-stop(0%, #dddddd), color-stop(100%, #aaaaaa)), -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, #dddddd), color-stop(100%, #aaaaaa));
background-image: url('/images/4x6.png?busted=true'), -moz-linear-gradient(top left, #dddddd 0%, #aaaaaa 100%), -moz-radial-gradient(center center, #dddddd 0%, #aaaaaa 100px);
background-image: url('/images/4x6.png?busted=true'), url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+IDxkZWZzPiA8bGluZWFyR3JhZGllbnQgaWQ9ImdyYWQiIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPiA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZGRkZGRkIiAvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2FhYWFhYSIgLz4gPC9saW5lYXJHcmFkaWVudD4gPC9kZWZzPiA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPiA8L3N2Zz4g'), url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+IDxkZWZzPiA8cmFkaWFsR3JhZGllbnQgaWQ9ImdyYWQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjeD0iNTAlIiBjeT0iNTAlIiByPSIxMDAiPiA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZGRkZGRkIiAvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2FhYWFhYSIgLz4gPC9yYWRpYWxHcmFkaWVudD4gPC9kZWZzPiA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPiA8L3N2Zz4g');
background-image: url('/images/4x6.png?busted=true'), linear-gradient(top left, #dddddd 0%, #aaaaaa 100%), radial-gradient(center center, #dddddd 0%, #aaaaaa 100px); }
.border-image-gradient {
-moz-border-image: -moz-radial-gradient(#00ff00, #ff0000 100px) 100 stretch;
-webkit-border-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, #00ff00), color-stop(100%, #ff0000)) 100 stretch;
border-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+IDxkZWZzPiA8cmFkaWFsR3JhZGllbnQgaWQ9ImdyYWQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjeD0iNTAlIiBjeT0iNTAlIiByPSIxMDAiPiA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjMDBmZjAwIiAvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmMDAwMCIgLz4gPC9yYWRpYWxHcmFkaWVudD4gPC9kZWZzPiA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPiA8L3N2Zz4g') 100 stretch;
border-image: radial-gradient(#00ff00 0%, #ff0000 100px) 100 stretch; }
.bg-linear-gradient-no-position {
background-image: -moz-linear-gradient(#dddddd, #aaaaaa);
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #dddddd), color-stop(100%, #aaaaaa));
background-image: -moz-linear-gradient(#dddddd 0%, #aaaaaa 100%);
background-image: linear-gradient(#dddddd 0%, #aaaaaa 100%); }
.bg-radial-gradient-no-position {
background-image: -moz-radial-gradient(#dddddd, #aaaaaa 100px);
background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, #dddddd), color-stop(100%, #aaaaaa));
background-image: -moz-radial-gradient(#dddddd 0%, #aaaaaa 100px);
background-image: radial-gradient(#dddddd 0%, #aaaaaa 100px); }
.linear-1 {

View File

@ -12,6 +12,10 @@ $experimental-support-for-svg: true
.bg-all-gradient-types
+background-image(image-url("4x6.png"), linear-gradient(top left, #ddd, #aaa), radial-gradient(center center, #ddd, #aaa 100px))
.border-image-gradient
+border-image(radial-gradient(#0f0,#f00 100px) 100 stretch)
$experimental-support-for-svg: false
.bg-linear-gradient-no-position