├── features ├── support │ ├── env.rb │ └── bourbon_support.rb ├── version.feature ├── step_definitions │ └── bourbon_steps.rb ├── update.feature └── install.feature ├── lib ├── bourbon │ ├── version.rb │ ├── engine.rb │ └── generator.rb ├── bourbon.rb └── tasks │ └── install.rake ├── .gitignore ├── Gemfile ├── app └── assets │ └── stylesheets │ ├── css3 │ ├── _appearance.scss │ ├── _user-select.scss │ ├── _background-size.scss │ ├── _box-sizing.scss │ ├── _inline-block.scss │ ├── _perspective.scss │ ├── _image-rendering.scss │ ├── _transform.scss │ ├── _placeholder.scss │ ├── _hidpi-media-query.scss │ ├── _border-radius.scss │ ├── _font-face.scss │ ├── _columns.scss │ ├── _flex-box.scss │ ├── _transition.scss │ ├── _keyframes.scss │ ├── _animation.scss │ ├── _background-image.scss │ ├── _linear-gradient.scss │ ├── _border-image.scss │ ├── _radial-gradient.scss │ └── _background.scss │ ├── functions │ ├── _linear-gradient.scss │ ├── _compact.scss │ ├── _px-to-em.scss │ ├── _tint-shade.scss │ ├── _grid-width.scss │ ├── _render-gradients.scss │ ├── _transition-property-name.scss │ ├── _modular-scale.scss │ ├── _deprecated-webkit-gradient.scss │ ├── _flex-grid.scss │ └── _radial-gradient.scss │ ├── addons │ ├── _font-family.scss │ ├── _hide-text.scss │ ├── _clearfix.scss │ ├── _retina-image.scss │ ├── _position.scss │ ├── _size.scss │ ├── _triangle.scss │ ├── _prefixer.scss │ ├── _timing-functions.scss │ ├── _html5-input-types.scss │ └── _button.scss │ ├── _bourbon-deprecated-upcoming.scss │ └── _bourbon.scss ├── bin └── bourbon ├── Rakefile ├── Gemfile.lock ├── LICENSE ├── bourbon.gemspec └── readme.md /features/support/env.rb: -------------------------------------------------------------------------------- 1 | require "aruba/cucumber" 2 | -------------------------------------------------------------------------------- /lib/bourbon/version.rb: -------------------------------------------------------------------------------- 1 | module Bourbon 2 | VERSION = "3.1.0" 3 | end 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *swp 2 | *gem 3 | .sass-cache/ 4 | /bourbon/ 5 | demo/ 6 | tmp/ 7 | tags 8 | -------------------------------------------------------------------------------- /lib/bourbon/engine.rb: -------------------------------------------------------------------------------- 1 | module Bourbon 2 | class Engine < Rails::Engine 3 | # auto wire 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | # Specify your gem's dependencies in sass-mixins.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_appearance.scss: -------------------------------------------------------------------------------- 1 | @mixin appearance ($value) { 2 | @include prefixer(appearance, $value, webkit moz ms o spec); 3 | } 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_user-select.scss: -------------------------------------------------------------------------------- 1 | @mixin user-select($arg: none) { 2 | @include prefixer(user-select, $arg, webkit moz ms spec); 3 | } 4 | -------------------------------------------------------------------------------- /bin/bourbon: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # CodeKit needs relative paths 4 | require File.dirname(__FILE__) + '/../lib/bourbon.rb' 5 | 6 | Bourbon::Generator.start 7 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_background-size.scss: -------------------------------------------------------------------------------- 1 | @mixin background-size ($lengths...) { 2 | @include prefixer(background-size, $lengths, webkit moz ms o spec); 3 | } 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_box-sizing.scss: -------------------------------------------------------------------------------- 1 | @mixin box-sizing ($box) { 2 | // content-box | border-box | inherit 3 | @include prefixer(box-sizing, $box, webkit moz spec); 4 | } 5 | -------------------------------------------------------------------------------- /app/assets/stylesheets/functions/_linear-gradient.scss: -------------------------------------------------------------------------------- 1 | @function linear-gradient($gradients...) { 2 | $type: linear; 3 | $type-gradient: append($type, $gradients, comma); 4 | 5 | @return $type-gradient; 6 | } 7 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | require 'rubygems' 3 | require 'bundler' 4 | require 'cucumber/rake/task' 5 | 6 | Bundler::GemHelper.install_tasks 7 | Cucumber::Rake::Task.new 8 | 9 | task :default => :cucumber 10 | -------------------------------------------------------------------------------- /features/version.feature: -------------------------------------------------------------------------------- 1 | @disable-bundler 2 | Feature: Show version 3 | Scenario: Viewing version 4 | When I successfully run `bundle exec bourbon --version` 5 | Then the output should contain the current version of Bourbon 6 | 7 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_inline-block.scss: -------------------------------------------------------------------------------- 1 | // Legacy support for inline-block in IE7 (maybe IE6) 2 | @mixin inline-block { 3 | display: inline-block; 4 | vertical-align: baseline; 5 | zoom: 1; 6 | *display: inline; 7 | *vertical-align: auto; 8 | } 9 | -------------------------------------------------------------------------------- /app/assets/stylesheets/functions/_compact.scss: -------------------------------------------------------------------------------- 1 | // Remove `false` values from a list 2 | 3 | @function compact($vars...) { 4 | $list: (); 5 | @each $var in $vars { 6 | @if $var { 7 | $list: append($list, $var, comma); 8 | } 9 | } 10 | @return $list; 11 | } 12 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_perspective.scss: -------------------------------------------------------------------------------- 1 | @mixin perspective($depth: none) { 2 | // none | 3 | @include prefixer(perspective, $depth, webkit moz o spec); 4 | } 5 | 6 | @mixin perspective-origin($value: 50% 50%) { 7 | @include prefixer(perspective-origin, $value, webkit moz o spec); 8 | } 9 | -------------------------------------------------------------------------------- /app/assets/stylesheets/functions/_px-to-em.scss: -------------------------------------------------------------------------------- 1 | // Convert pixels to ems 2 | // eg. for a relational value of 12px write em(12) when the parent is 16px 3 | // if the parent is another value say 24px write em(12, 24) 4 | 5 | @function em($pxval, $base: 16) { 6 | @return ($pxval / $base) * 1em; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /app/assets/stylesheets/functions/_tint-shade.scss: -------------------------------------------------------------------------------- 1 | // Add percentage of white to a color 2 | @function tint($color, $percent){ 3 | @return mix(white, $color, $percent); 4 | } 5 | 6 | // Add percentage of black to a color 7 | @function shade($color, $percent){ 8 | @return mix(black, $color, $percent); 9 | } 10 | -------------------------------------------------------------------------------- /app/assets/stylesheets/addons/_font-family.scss: -------------------------------------------------------------------------------- 1 | $georgia: Georgia, Cambria, "Times New Roman", Times, serif; 2 | $helvetica: "Helvetica Neue", Helvetica, Arial, sans-serif; 3 | $lucida-grande: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif; 4 | $monospace: "Bitstream Vera Sans Mono", Consolas, Courier, monospace; 5 | $verdana: Verdana, Geneva, sans-serif; 6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/addons/_hide-text.scss: -------------------------------------------------------------------------------- 1 | @mixin hide-text { 2 | background-color: transparent; 3 | border: 0; 4 | color: transparent; 5 | font: 0/0 a; 6 | text-shadow: none; 7 | } 8 | 9 | // A CSS image replacement method that does not require the use of text-indent. 10 | // 11 | // Examples 12 | // 13 | // .ir { 14 | // @include hide-text; 15 | // } 16 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_image-rendering.scss: -------------------------------------------------------------------------------- 1 | @mixin image-rendering ($mode:optimizeQuality) { 2 | 3 | @if ($mode == optimize-contrast) { 4 | image-rendering: -moz-crisp-edges; 5 | image-rendering: -o-crisp-edges; 6 | image-rendering: -webkit-optimize-contrast; 7 | image-rendering: optimize-contrast; 8 | } 9 | 10 | @else { 11 | image-rendering: $mode; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_transform.scss: -------------------------------------------------------------------------------- 1 | @mixin transform($property: none) { 2 | // none | 3 | @include prefixer(transform, $property, webkit moz ms o spec); 4 | } 5 | 6 | @mixin transform-origin($axes: 50%) { 7 | // x-axis - left | center | right | length | % 8 | // y-axis - top | center | bottom | length | % 9 | // z-axis - length 10 | @include prefixer(transform-origin, $axes, webkit moz ms o spec); 11 | } 12 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_placeholder.scss: -------------------------------------------------------------------------------- 1 | $placeholders: '-webkit-input-placeholder', 2 | '-moz-placeholder', 3 | '-ms-input-placeholder'; 4 | 5 | @mixin placeholder { 6 | @each $placeholder in $placeholders { 7 | @if $placeholder == "-webkit-input-placeholder" { 8 | &::#{$placeholder} { 9 | @content; 10 | } 11 | } 12 | @else { 13 | &:#{$placeholder} { 14 | @content; 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /features/support/bourbon_support.rb: -------------------------------------------------------------------------------- 1 | module BourbonSupport 2 | def install_bourbon(path = nil) 3 | if path 4 | run_simple("bundle exec bourbon install --path '#{path}'") 5 | else 6 | run_simple("bundle exec bourbon install") 7 | end 8 | end 9 | 10 | def bourbon_path(prefix, path) 11 | if prefix 12 | File.join(prefix, 'bourbon', path) 13 | else 14 | File.join('bourbon', path) 15 | end 16 | end 17 | end 18 | 19 | World(BourbonSupport) 20 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_bourbon-deprecated-upcoming.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // These mixins/functions are deprecated 3 | // They will be removed in the next MAJOR version release 4 | //************************************************************************// 5 | @mixin box-shadow ($shadows...) { 6 | @include prefixer(box-shadow, $shadows, spec); 7 | @warn "box-shadow is deprecated and will be removed in the next major version release"; 8 | } 9 | -------------------------------------------------------------------------------- /app/assets/stylesheets/functions/_grid-width.scss: -------------------------------------------------------------------------------- 1 | @function grid-width($n) { 2 | @return $n * $gw-column + ($n - 1) * $gw-gutter; 3 | } 4 | 5 | // The $gw-column and $gw-gutter variables must be defined in your base stylesheet to properly use the grid-width function. 6 | // 7 | // $gw-column: 100px; // Column Width 8 | // $gw-gutter: 40px; // Gutter Width 9 | // 10 | // div { 11 | // width: grid-width(4); // returns 520px; 12 | // margin-left: $gw-gutter; // returns 40px; 13 | // } 14 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_hidpi-media-query.scss: -------------------------------------------------------------------------------- 1 | // HiDPI mixin. Default value set to 1.3 to target Google Nexus 7 (http://bjango.com/articles/min-device-pixel-ratio/) 2 | @mixin hidpi($ratio: 1.3) { 3 | @media only screen and (-webkit-min-device-pixel-ratio: $ratio), 4 | only screen and (min--moz-device-pixel-ratio: $ratio), 5 | only screen and (-o-min-device-pixel-ratio: #{$ratio}/1), 6 | only screen and (min-resolution: #{round($ratio*96)}dpi), 7 | only screen and (min-resolution: #{$ratio}dppx) { 8 | @content; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /app/assets/stylesheets/functions/_render-gradients.scss: -------------------------------------------------------------------------------- 1 | // User for linear and radial gradients within background-image or border-image properties 2 | 3 | @function render-gradients($gradients, $gradient-type, $vendor: false) { 4 | $vendor-gradients: false; 5 | @if $vendor { 6 | $vendor-gradients: -#{$vendor}-#{$gradient-type}-gradient($gradients); 7 | } 8 | 9 | @else if $vendor == false { 10 | $vendor-gradients: "#{$gradient-type}-gradient(#{$gradients})"; 11 | $vendor-gradients: unquote($vendor-gradients); 12 | } 13 | @return $vendor-gradients; 14 | } 15 | -------------------------------------------------------------------------------- /app/assets/stylesheets/addons/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // Micro clearfix provides an easy way to contain floats without adding additional markup 2 | // 3 | // Example usage: 4 | // 5 | // // Contain all floats within .wrapper 6 | // .wrapper { 7 | // @include clearfix; 8 | // .content, 9 | // .sidebar { 10 | // float : left; 11 | // } 12 | // } 13 | 14 | @mixin clearfix { 15 | *zoom: 1; 16 | 17 | &:before, 18 | &:after { 19 | content: " "; 20 | display: table; 21 | } 22 | 23 | &:after { 24 | clear: both; 25 | } 26 | } 27 | 28 | // Acknowledgements 29 | // Micro clearfix: [Nicolas Gallagher](http://nicolasgallagher.com/micro-clearfix-hack/) 30 | -------------------------------------------------------------------------------- /lib/bourbon.rb: -------------------------------------------------------------------------------- 1 | # CodeKit needs relative paths 2 | dir = File.dirname(__FILE__) 3 | $LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir) 4 | 5 | require "bourbon/generator" 6 | 7 | unless defined?(Sass) 8 | require 'sass' 9 | end 10 | 11 | module Bourbon 12 | if defined?(Rails) && defined?(Rails::Engine) 13 | class Engine < ::Rails::Engine 14 | require 'bourbon/engine' 15 | end 16 | 17 | module Rails 18 | class Railtie < ::Rails::Railtie 19 | rake_tasks do 20 | load "tasks/install.rake" 21 | end 22 | end 23 | end 24 | else 25 | Sass.load_paths << File.expand_path("../../app/assets/stylesheets", __FILE__) 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /app/assets/stylesheets/functions/_transition-property-name.scss: -------------------------------------------------------------------------------- 1 | // Return vendor-prefixed property names if appropriate 2 | // Example: transition-property-names((transform, color, background), moz) -> -moz-transform, color, background 3 | //************************************************************************// 4 | @function transition-property-names($props, $vendor: false) { 5 | $new-props: (); 6 | 7 | @each $prop in $props { 8 | $new-props: append($new-props, transition-property-name($prop, $vendor), comma); 9 | } 10 | 11 | @return $new-props; 12 | } 13 | 14 | @function transition-property-name($prop, $vendor: false) { 15 | // put other properties that need to be prefixed here aswell 16 | @if $vendor and $prop == transform { 17 | @return unquote('-'+$vendor+'-'+$prop); 18 | } 19 | @else { 20 | @return $prop; 21 | } 22 | } -------------------------------------------------------------------------------- /app/assets/stylesheets/addons/_retina-image.scss: -------------------------------------------------------------------------------- 1 | @mixin retina-image($filename, $background-size, $extension: png, $retina-filename: null, $asset-pipeline: false) { 2 | background-image: url($filename + "." + $extension); 3 | 4 | @include hidpi { 5 | 6 | @if $asset-pipeline { 7 | @if $retina-filename { 8 | background-image: image_url($retina-filename + "." + $extension); 9 | } 10 | @else { 11 | background-image: image_url($filename + "@2x" + "." + $extension); 12 | } 13 | } 14 | 15 | @else { 16 | @if $retina-filename { 17 | background-image: url($retina-filename + "." + $extension); 18 | } 19 | @else { 20 | background-image: url($filename + "@2x" + "." + $extension); 21 | } 22 | } 23 | 24 | background-size: $background-size; 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/tasks/install.rake: -------------------------------------------------------------------------------- 1 | # Needed for pre-3.1. 2 | 3 | require "fileutils" 4 | require "find" 5 | 6 | namespace :bourbon do 7 | desc "Move files to the Rails assets directory." 8 | task :install, [:sass_path] do |t, args| 9 | args.with_defaults(:sass_path => 'public/stylesheets/sass') 10 | source_root = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')) 11 | FileUtils.mkdir_p("#{Rails.root}/#{args.sass_path}/bourbon") 12 | FileUtils.cp_r("#{source_root}/app/assets/stylesheets/.", "#{Rails.root}/#{args.sass_path}/bourbon", { :preserve => true }) 13 | Find.find("#{Rails.root}/#{args.sass_path}/bourbon") do |path| 14 | if path.end_with?(".css.scss") 15 | path_without_css_extension = path.gsub(/\.css\.scss$/, ".scss") 16 | FileUtils.mv(path, path_without_css_extension) 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/assets/stylesheets/addons/_position.scss: -------------------------------------------------------------------------------- 1 | @mixin position ($position: relative, $coordinates: 0 0 0 0) { 2 | 3 | @if type-of($position) == list { 4 | $coordinates: $position; 5 | $position: relative; 6 | } 7 | 8 | $top: nth($coordinates, 1); 9 | $right: nth($coordinates, 2); 10 | $bottom: nth($coordinates, 3); 11 | $left: nth($coordinates, 4); 12 | 13 | position: $position; 14 | 15 | @if $top == auto { 16 | top: $top; 17 | } 18 | @else if not(unitless($top)) { 19 | top: $top; 20 | } 21 | 22 | @if $right == auto { 23 | right: $right; 24 | } 25 | @else if not(unitless($right)) { 26 | right: $right; 27 | } 28 | 29 | @if $bottom == auto { 30 | bottom: $bottom; 31 | } 32 | @else if not(unitless($bottom)) { 33 | bottom: $bottom; 34 | } 35 | 36 | @if $left == auto { 37 | left: $left; 38 | } 39 | @else if not(unitless($left)) { 40 | left: $left; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_border-radius.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Shorthand Border-radius mixins 3 | //************************************************************************// 4 | @mixin border-top-radius($radii) { 5 | @include prefixer(border-top-left-radius, $radii, spec); 6 | @include prefixer(border-top-right-radius, $radii, spec); 7 | } 8 | 9 | @mixin border-bottom-radius($radii) { 10 | @include prefixer(border-bottom-left-radius, $radii, spec); 11 | @include prefixer(border-bottom-right-radius, $radii, spec); 12 | } 13 | 14 | @mixin border-left-radius($radii) { 15 | @include prefixer(border-top-left-radius, $radii, spec); 16 | @include prefixer(border-bottom-left-radius, $radii, spec); 17 | } 18 | 19 | @mixin border-right-radius($radii) { 20 | @include prefixer(border-top-right-radius, $radii, spec); 21 | @include prefixer(border-bottom-right-radius, $radii, spec); 22 | } 23 | -------------------------------------------------------------------------------- /features/step_definitions/bourbon_steps.rb: -------------------------------------------------------------------------------- 1 | Given /^bourbon is already installed$/ do 2 | install_bourbon 3 | end 4 | 5 | Given /^I install bourbon to "([^"]*)"$/ do |path| 6 | end 7 | 8 | Then /^the sass directories(?: with "([^"]+)" prefix)? should have been generated$/ do |prefix| 9 | sass_directories = ["addons", "css3", "functions"] 10 | sass_directories.map!{ |directory| bourbon_path(prefix, directory) } 11 | check_directory_presence(sass_directories, true) 12 | end 13 | 14 | Then /^the master bourbon partial should have been generated(?: within "([^"]+)" directory)?$/ do |prefix| 15 | check_file_presence([bourbon_path(prefix, '_bourbon.scss')], true) 16 | end 17 | 18 | Then /^bourbon should not have been generated$/ do 19 | check_directory_presence(['bourbon'], false) 20 | end 21 | 22 | Then /^the output should contain the current version of Bourbon$/ do 23 | step %(the output should contain exactly "Bourbon #{Bourbon::VERSION}\n") 24 | end 25 | -------------------------------------------------------------------------------- /app/assets/stylesheets/addons/_size.scss: -------------------------------------------------------------------------------- 1 | @mixin size($size) { 2 | @if length($size) == 1 { 3 | @if $size == auto { 4 | width: $size; 5 | height: $size; 6 | } 7 | 8 | @else if unitless($size) { 9 | width: $size + px; 10 | height: $size + px; 11 | } 12 | 13 | @else if not(unitless($size)) { 14 | width: $size; 15 | height: $size; 16 | } 17 | } 18 | 19 | // Width x Height 20 | @if length($size) == 2 { 21 | $width: nth($size, 1); 22 | $height: nth($size, 2); 23 | 24 | @if $width == auto { 25 | width: $width; 26 | } 27 | @else if not(unitless($width)) { 28 | width: $width; 29 | } 30 | @else if unitless($width) { 31 | width: $width + px; 32 | } 33 | 34 | @if $height == auto { 35 | height: $height; 36 | } 37 | @else if not(unitless($height)) { 38 | height: $height; 39 | } 40 | @else if unitless($height) { 41 | height: $height + px; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | bourbon (3.0.0) 5 | sass (>= 3.2.0) 6 | thor 7 | 8 | GEM 9 | remote: http://rubygems.org/ 10 | specs: 11 | aruba (0.4.11) 12 | childprocess (>= 0.2.3) 13 | cucumber (>= 1.1.1) 14 | ffi (>= 1.0.11) 15 | rspec (>= 2.7.0) 16 | builder (3.0.0) 17 | childprocess (0.3.1) 18 | ffi (~> 1.0.6) 19 | cucumber (1.1.9) 20 | builder (>= 2.1.2) 21 | diff-lcs (>= 1.1.2) 22 | gherkin (~> 2.9.0) 23 | json (>= 1.4.6) 24 | term-ansicolor (>= 1.0.6) 25 | diff-lcs (1.1.3) 26 | ffi (1.0.11) 27 | gherkin (2.9.0) 28 | json (>= 1.4.6) 29 | json (1.6.5) 30 | rake (0.9.2.2) 31 | rspec (2.8.0) 32 | rspec-core (~> 2.8.0) 33 | rspec-expectations (~> 2.8.0) 34 | rspec-mocks (~> 2.8.0) 35 | rspec-core (2.8.0) 36 | rspec-expectations (2.8.0) 37 | diff-lcs (~> 1.1.2) 38 | rspec-mocks (2.8.0) 39 | sass (3.2.3) 40 | term-ansicolor (1.0.7) 41 | thor (0.16.0) 42 | 43 | PLATFORMS 44 | ruby 45 | 46 | DEPENDENCIES 47 | aruba (~> 0.4) 48 | bourbon! 49 | rake 50 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_font-face.scss: -------------------------------------------------------------------------------- 1 | // Order of the includes matters, and it is: normal, bold, italic, bold+italic. 2 | 3 | @mixin font-face($font-family, $file-path, $weight: normal, $style: normal, $asset-pipeline: false ) { 4 | @font-face { 5 | font-family: $font-family; 6 | font-weight: $weight; 7 | font-style: $style; 8 | 9 | @if $asset-pipeline == true { 10 | src: font-url('#{$file-path}.eot'); 11 | src: font-url('#{$file-path}.eot?#iefix') format('embedded-opentype'), 12 | font-url('#{$file-path}.woff') format('woff'), 13 | font-url('#{$file-path}.ttf') format('truetype'), 14 | font-url('#{$file-path}.svg##{$font-family}') format('svg'); 15 | } @else { 16 | src: url('#{$file-path}.eot'); 17 | src: url('#{$file-path}.eot?#iefix') format('embedded-opentype'), 18 | url('#{$file-path}.woff') format('woff'), 19 | url('#{$file-path}.ttf') format('truetype'), 20 | url('#{$file-path}.svg##{$font-family}') format('svg'); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | LICENSE 2 | 3 | The MIT License 4 | 5 | Copyright (c) 2011-2013 thoughtbot, inc. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /app/assets/stylesheets/functions/_modular-scale.scss: -------------------------------------------------------------------------------- 1 | @function modular-scale($value, $increment, $ratio) { 2 | @if $increment > 0 { 3 | @for $i from 1 through $increment { 4 | $value: ($value * $ratio); 5 | } 6 | } 7 | 8 | @if $increment < 0 { 9 | $increment: abs($increment); 10 | @for $i from 1 through $increment { 11 | $value: ($value / $ratio); 12 | } 13 | } 14 | 15 | @return $value; 16 | } 17 | 18 | // div { 19 | // Increment Up GR with positive value 20 | // font-size: modular-scale(14px, 1, 1.618); // returns: 22.652px 21 | // 22 | // Increment Down GR with negative value 23 | // font-size: modular-scale(14px, -1, 1.618); // returns: 8.653px 24 | // 25 | // Can be used with ceil(round up) or floor(round down) 26 | // font-size: floor( modular-scale(14px, 1, 1.618) ); // returns: 22px 27 | // font-size: ceil( modular-scale(14px, 1, 1.618) ); // returns: 23px 28 | // } 29 | // 30 | // modularscale.com 31 | 32 | @function golden-ratio($value, $increment) { 33 | @return modular-scale($value, $increment, 1.618) 34 | } 35 | 36 | // div { 37 | // font-size: golden-ratio(14px, 1); // returns: 22.652px 38 | // } 39 | // 40 | // goldenratiocalculator.com 41 | -------------------------------------------------------------------------------- /features/update.feature: -------------------------------------------------------------------------------- 1 | @disable-bundler 2 | Feature: Update bourbon files 3 | 4 | Scenario: Updating updates an existing bourbon install 5 | Given bourbon is already installed 6 | When I write to "bourbon/_bourbon.scss" with: 7 | """ 8 | foobar 9 | """ 10 | And I run `bundle exec bourbon update` 11 | Then the output should contain "Bourbon files updated." 12 | And the file "bourbon/_bourbon.scss" should not contain "foobar" 13 | 14 | Scenario: Updating with a --path option 15 | Given I install bourbon to "custom_path" 16 | When I write to "custom_path/bourbon/_bourbon.scss" with: 17 | """ 18 | foobar 19 | """ 20 | And I run `bundle exec bourbon update` 21 | Then the output should contain "No existing bourbon installation. Doing nothing." 22 | 23 | When I run `bundle exec bourbon update --path custom_path` 24 | Then the output should contain "Bourbon files updated." 25 | And the file "custom_path/bourbon/_bourbon.scss" should not contain "foobar" 26 | 27 | Scenario: Updating does not generate a new bourbon install 28 | And I run `bundle exec bourbon update` 29 | Then bourbon should not have been generated 30 | And the output should contain "No existing bourbon installation. Doing nothing." 31 | -------------------------------------------------------------------------------- /app/assets/stylesheets/addons/_triangle.scss: -------------------------------------------------------------------------------- 1 | @mixin triangle ($size, $color, $direction) { 2 | height: 0; 3 | width: 0; 4 | 5 | @if ($direction == up) or ($direction == down) or ($direction == right) or ($direction == left) { 6 | border-color: transparent; 7 | border-style: solid; 8 | border-width: $size / 2; 9 | 10 | @if $direction == up { 11 | border-bottom-color: $color; 12 | 13 | } @else if $direction == right { 14 | border-left-color: $color; 15 | 16 | } @else if $direction == down { 17 | border-top-color: $color; 18 | 19 | } @else if $direction == left { 20 | border-right-color: $color; 21 | } 22 | } 23 | 24 | @else if ($direction == up-right) or ($direction == up-left) { 25 | border-top: $size solid $color; 26 | 27 | @if $direction == up-right { 28 | border-left: $size solid transparent; 29 | 30 | } @else if $direction == up-left { 31 | border-right: $size solid transparent; 32 | } 33 | } 34 | 35 | @else if ($direction == down-right) or ($direction == down-left) { 36 | border-bottom: $size solid $color; 37 | 38 | @if $direction == down-right { 39 | border-left: $size solid transparent; 40 | 41 | } @else if $direction == down-left { 42 | border-right: $size solid transparent; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_columns.scss: -------------------------------------------------------------------------------- 1 | @mixin columns($arg: auto) { 2 | // || 3 | @include prefixer(columns, $arg, webkit moz spec); 4 | } 5 | 6 | @mixin column-count($int: auto) { 7 | // auto || integer 8 | @include prefixer(column-count, $int, webkit moz spec); 9 | } 10 | 11 | @mixin column-gap($length: normal) { 12 | // normal || length 13 | @include prefixer(column-gap, $length, webkit moz spec); 14 | } 15 | 16 | @mixin column-fill($arg: auto) { 17 | // auto || length 18 | @include prefixer(columns-fill, $arg, webkit moz spec); 19 | } 20 | 21 | @mixin column-rule($arg) { 22 | // || || 23 | @include prefixer(column-rule, $arg, webkit moz spec); 24 | } 25 | 26 | @mixin column-rule-color($color) { 27 | @include prefixer(column-rule-color, $color, webkit moz spec); 28 | } 29 | 30 | @mixin column-rule-style($style: none) { 31 | // none | hidden | dashed | dotted | double | groove | inset | inset | outset | ridge | solid 32 | @include prefixer(column-rule-style, $style, webkit moz spec); 33 | } 34 | 35 | @mixin column-rule-width ($width: none) { 36 | @include prefixer(column-rule-width, $width, webkit moz spec); 37 | } 38 | 39 | @mixin column-span($arg: none) { 40 | // none || all 41 | @include prefixer(column-span, $arg, webkit moz spec); 42 | } 43 | 44 | @mixin column-width($length: auto) { 45 | // auto || length 46 | @include prefixer(column-width, $length, webkit moz spec); 47 | } 48 | -------------------------------------------------------------------------------- /app/assets/stylesheets/addons/_prefixer.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Example: @include prefixer(border-radius, $radii, webkit ms spec); 3 | //************************************************************************// 4 | $prefix-for-webkit: true !default; 5 | $prefix-for-mozilla: true !default; 6 | $prefix-for-microsoft: true !default; 7 | $prefix-for-opera: true !default; 8 | $prefix-for-spec: true !default; // required for keyframe mixin 9 | 10 | @mixin prefixer ($property, $value, $prefixes) { 11 | @each $prefix in $prefixes { 12 | 13 | @if $prefix == webkit and $prefix-for-webkit == true { 14 | -webkit-#{$property}: $value; 15 | } 16 | @else if $prefix == moz and $prefix-for-mozilla == true { 17 | -moz-#{$property}: $value; 18 | } 19 | @else if $prefix == ms and $prefix-for-microsoft == true { 20 | -ms-#{$property}: $value; 21 | } 22 | @else if $prefix == o and $prefix-for-opera == true { 23 | -o-#{$property}: $value; 24 | } 25 | @else if $prefix == spec and $prefix-for-spec == true { 26 | #{$property}: $value; 27 | } 28 | @else { 29 | @warn "Unrecognized prefix: #{$prefix}"; 30 | } 31 | } 32 | } 33 | 34 | @mixin disable-prefix-for-all() { 35 | $prefix-for-webkit: false; 36 | $prefix-for-mozilla: false; 37 | $prefix-for-microsoft: false; 38 | $prefix-for-opera: false; 39 | $prefix-for-spec: false; 40 | } 41 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_flex-box.scss: -------------------------------------------------------------------------------- 1 | // CSS3 Flexible Box Model and property defaults 2 | 3 | // Custom shorthand notation for flexbox 4 | @mixin box($orient: inline-axis, $pack: start, $align: stretch) { 5 | @include display-box; 6 | @include box-orient($orient); 7 | @include box-pack($pack); 8 | @include box-align($align); 9 | } 10 | 11 | @mixin display-box { 12 | display: -webkit-box; 13 | display: -moz-box; 14 | display: box; 15 | } 16 | 17 | @mixin box-orient($orient: inline-axis) { 18 | // horizontal|vertical|inline-axis|block-axis|inherit 19 | @include prefixer(box-orient, $orient, webkit moz spec); 20 | } 21 | 22 | @mixin box-pack($pack: start) { 23 | // start|end|center|justify 24 | @include prefixer(box-pack, $pack, webkit moz spec); 25 | } 26 | 27 | @mixin box-align($align: stretch) { 28 | // start|end|center|baseline|stretch 29 | @include prefixer(box-align, $align, webkit moz spec); 30 | } 31 | 32 | @mixin box-direction($direction: normal) { 33 | // normal|reverse|inherit 34 | @include prefixer(box-direction, $direction, webkit moz spec); 35 | } 36 | 37 | @mixin box-lines($lines: single) { 38 | // single|multiple 39 | @include prefixer(box-lines, $lines, webkit moz spec); 40 | } 41 | 42 | @mixin box-ordinal-group($int: 1) { 43 | @include prefixer(box-ordinal-group, $int, webkit moz spec); 44 | } 45 | 46 | @mixin box-flex($value: 0.0) { 47 | @include prefixer(box-flex, $value, webkit moz spec); 48 | } 49 | 50 | @mixin box-flex-group($int: 1) { 51 | @include prefixer(box-flex-group, $int, webkit moz spec); 52 | } 53 | -------------------------------------------------------------------------------- /features/install.feature: -------------------------------------------------------------------------------- 1 | @disable-bundler 2 | Feature: Install bourbon files 3 | 4 | Scenario: Bourbon generates a new bourbon installation 5 | When I run `bundle exec bourbon install` 6 | Then the sass directories should have been generated 7 | And the following directories should exist: 8 | | bourbon | 9 | And the master bourbon partial should have been generated 10 | And the output should contain "Bourbon files installed to bourbon/" 11 | 12 | Scenario: Generating does not overwrite an existing bourbon directory 13 | Given bourbon is already installed 14 | When I run `bundle exec bourbon install` 15 | Then the output should contain "Bourbon files already installed, doing nothing." 16 | 17 | Scenario: Install Bourbon into a custom path 18 | When I run `bundle exec bourbon install --path=custom_path` 19 | Then the sass directories with "custom_path" prefix should have been generated 20 | And the following directories should exist: 21 | | custom_path/bourbon | 22 | And the master bourbon partial should have been generated within "custom_path" directory 23 | And the output should contain "Bourbon files installed to custom_path/bourbon/" 24 | 25 | Scenario: Forcing install of bourbon 26 | Given bourbon is already installed 27 | When I run `bundle exec bourbon install --force` 28 | Then the output from "bundle exec bourbon install --force" should contain "Bourbon files installed to bourbon/" 29 | And the output should not contain "Bourbon files already installed, doing nothing." 30 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_transition.scss: -------------------------------------------------------------------------------- 1 | // Shorthand mixin. Supports multiple parentheses-deliminated values for each variable. 2 | // Example: @include transition (all, 2.0s, ease-in-out); 3 | // @include transition ((opacity, width), (1.0s, 2.0s), ease-in, (0, 2s)); 4 | // @include transition ($property:(opacity, width), $delay: (1.5s, 2.5s)); 5 | 6 | @mixin transition ($properties...) { 7 | @if length($properties) >= 1 { 8 | @include prefixer(transition, $properties, webkit moz ms o spec); 9 | } 10 | 11 | @else { 12 | $properties: all 0.15s ease-out 0; 13 | @include prefixer(transition, $properties, webkit moz ms o spec); 14 | } 15 | } 16 | 17 | @mixin transition-property ($properties...) { 18 | -webkit-transition-property: transition-property-names($properties, 'webkit'); 19 | -moz-transition-property: transition-property-names($properties, 'moz'); 20 | -ms-transition-property: transition-property-names($properties, 'ms'); 21 | -o-transition-property: transition-property-names($properties, 'o'); 22 | transition-property: transition-property-names($properties, false); 23 | } 24 | 25 | @mixin transition-duration ($times...) { 26 | @include prefixer(transition-duration, $times, webkit moz ms o spec); 27 | } 28 | 29 | @mixin transition-timing-function ($motions...) { 30 | // ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier() 31 | @include prefixer(transition-timing-function, $motions, webkit moz ms o spec); 32 | } 33 | 34 | @mixin transition-delay ($times...) { 35 | @include prefixer(transition-delay, $times, webkit moz ms o spec); 36 | } 37 | -------------------------------------------------------------------------------- /app/assets/stylesheets/functions/_deprecated-webkit-gradient.scss: -------------------------------------------------------------------------------- 1 | // Render Deprecated Webkit Gradient - Linear || Radial 2 | //************************************************************************// 3 | @function deprecated-webkit-gradient($type, 4 | $deprecated-pos1, $deprecated-pos2, 5 | $full, 6 | $deprecated-radius1: false, $deprecated-radius2: false) { 7 | $gradient-list: (); 8 | $gradient: false; 9 | $full-length: length($full); 10 | $percentage: false; 11 | $gradient-type: $type; 12 | 13 | @for $i from 1 through $full-length { 14 | $gradient: nth($full, $i); 15 | 16 | @if length($gradient) == 2 { 17 | $color-stop: color-stop(nth($gradient, 2), nth($gradient, 1)); 18 | $gradient-list: join($gradient-list, $color-stop, comma); 19 | } 20 | 21 | @else if $gradient != null { 22 | @if $i == $full-length { 23 | $percentage: 100%; 24 | } 25 | 26 | @else { 27 | $percentage: ($i - 1) * (100 / ($full-length - 1)) + "%"; 28 | } 29 | 30 | $color-stop: color-stop(unquote($percentage), $gradient); 31 | $gradient-list: join($gradient-list, $color-stop, comma); 32 | } 33 | } 34 | 35 | @if $type == radial { 36 | $gradient: -webkit-gradient(radial, $deprecated-pos1, $deprecated-radius1, $deprecated-pos2, $deprecated-radius2, $gradient-list); 37 | } 38 | 39 | @else if $type == linear { 40 | $gradient: -webkit-gradient(linear, $deprecated-pos1, $deprecated-pos2, $gradient-list); 41 | } 42 | 43 | @return $gradient; 44 | } 45 | -------------------------------------------------------------------------------- /bourbon.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "bourbon/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "bourbon" 7 | s.version = Bourbon::VERSION 8 | s.platform = Gem::Platform::RUBY 9 | s.authors = ["Phil LaPier", "Chad Mazzola", "Matt Jankowski", "Nick Quaranto", "Jeremy Raines", "Mike Burns", "Andres Mejia", "Travis Haynes", "Chris Lloyd", "Gabe Berke-Williams", "J. Edward Dewyea", "Reda Lemeden"] 10 | s.email = ["support@thoughtbot.com"] 11 | s.homepage = "https://github.com/thoughtbot/bourbon" 12 | s.summary = "Bourbon Sass Mixins using SCSS syntax." 13 | s.description = <<-DESC 14 | The purpose of Bourbon Vanilla Sass Mixins is to provide a comprehensive framework of 15 | sass mixins that are designed to be as vanilla as possible. Meaning they 16 | should not deter from the original CSS syntax. The mixins contain vendor 17 | specific prefixes for all CSS3 properties for support amongst modern 18 | browsers. The prefixes also ensure graceful degradation for older browsers 19 | that support only CSS3 prefixed properties. 20 | DESC 21 | 22 | s.rubyforge_project = "bourbon" 23 | 24 | s.files = `git ls-files`.split("\n") 25 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 26 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 27 | s.require_paths = ["lib"] 28 | 29 | s.add_dependency('sass', '>= 3.2.0') 30 | s.add_dependency('thor') 31 | 32 | s.add_development_dependency('aruba', '~> 0.4') 33 | s.add_development_dependency('rake') 34 | end 35 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_bourbon.scss: -------------------------------------------------------------------------------- 1 | // Custom Functions 2 | @import "functions/compact"; 3 | @import "functions/deprecated-webkit-gradient"; 4 | @import "functions/flex-grid"; 5 | @import "functions/grid-width"; 6 | @import "functions/linear-gradient"; 7 | @import "functions/modular-scale"; 8 | @import "functions/px-to-em"; 9 | @import "functions/radial-gradient"; 10 | @import "functions/render-gradients"; 11 | @import "functions/tint-shade"; 12 | @import "functions/transition-property-name"; 13 | 14 | // CSS3 Mixins 15 | @import "css3/animation"; 16 | @import "css3/appearance"; 17 | @import "css3/background"; 18 | @import "css3/background-image"; 19 | @import "css3/background-size"; 20 | @import "css3/border-image"; 21 | @import "css3/border-radius"; 22 | @import "css3/box-sizing"; 23 | @import "css3/columns"; 24 | @import "css3/flex-box"; 25 | @import "css3/font-face"; 26 | @import "css3/hidpi-media-query"; 27 | @import "css3/image-rendering"; 28 | @import "css3/inline-block"; 29 | @import "css3/keyframes"; 30 | @import "css3/linear-gradient"; 31 | @import "css3/perspective"; 32 | @import "css3/radial-gradient"; 33 | @import "css3/transform"; 34 | @import "css3/transition"; 35 | @import "css3/user-select"; 36 | @import "css3/placeholder"; 37 | 38 | // Addons & other mixins 39 | @import "addons/button"; 40 | @import "addons/clearfix"; 41 | @import "addons/font-family"; 42 | @import "addons/hide-text"; 43 | @import "addons/html5-input-types"; 44 | @import "addons/position"; 45 | @import "addons/prefixer"; 46 | @import "addons/retina-image"; 47 | @import "addons/size"; 48 | @import "addons/timing-functions"; 49 | @import "addons/triangle"; 50 | 51 | // Soon to be deprecated Mixins 52 | @import "bourbon-deprecated-upcoming"; 53 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_keyframes.scss: -------------------------------------------------------------------------------- 1 | // Adds keyframes blocks for supported prefixes, removing redundant prefixes in the block's content 2 | @mixin keyframes($name) { 3 | $original-prefix-for-webkit: $prefix-for-webkit; 4 | $original-prefix-for-mozilla: $prefix-for-mozilla; 5 | $original-prefix-for-microsoft: $prefix-for-microsoft; 6 | $original-prefix-for-opera: $prefix-for-opera; 7 | $original-prefix-for-spec: $prefix-for-spec; 8 | 9 | @if $original-prefix-for-webkit { 10 | @include disable-prefix-for-all(); 11 | $prefix-for-webkit: true; 12 | @-webkit-keyframes #{$name} { 13 | @content; 14 | } 15 | } 16 | @if $original-prefix-for-mozilla { 17 | @include disable-prefix-for-all(); 18 | $prefix-for-mozilla: true; 19 | @-moz-keyframes #{$name} { 20 | @content; 21 | } 22 | } 23 | @if $original-prefix-for-microsoft { 24 | @include disable-prefix-for-all(); 25 | $prefix-for-microsoft: true; 26 | @-ms-keyframes #{$name} { 27 | @content; 28 | } 29 | } 30 | @if $original-prefix-for-opera { 31 | @include disable-prefix-for-all(); 32 | $prefix-for-opera: true; 33 | @-o-keyframes #{$name} { 34 | @content; 35 | } 36 | } 37 | @if $original-prefix-for-spec { 38 | $prefix-for-spec: true !default; 39 | @include disable-prefix-for-all(); 40 | $prefix-for-spec: true; 41 | @keyframes #{$name} { 42 | @content; 43 | } 44 | } 45 | 46 | $prefix-for-webkit: $original-prefix-for-webkit; 47 | $prefix-for-mozilla: $original-prefix-for-mozilla; 48 | $prefix-for-microsoft: $original-prefix-for-microsoft; 49 | $prefix-for-opera: $original-prefix-for-opera; 50 | $prefix-for-spec: $original-prefix-for-spec; 51 | } 52 | -------------------------------------------------------------------------------- /app/assets/stylesheets/functions/_flex-grid.scss: -------------------------------------------------------------------------------- 1 | // Flexible grid 2 | @function flex-grid($columns, $container-columns: $fg-max-columns) { 3 | $width: $columns * $fg-column + ($columns - 1) * $fg-gutter; 4 | $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter; 5 | @return percentage($width / $container-width); 6 | } 7 | 8 | // Flexible gutter 9 | @function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) { 10 | $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter; 11 | @return percentage($gutter / $container-width); 12 | } 13 | 14 | // The $fg-column, $fg-gutter and $fg-max-columns variables must be defined in your base stylesheet to properly use the flex-grid function. 15 | // This function takes the fluid grid equation (target / context = result) and uses columns to help define each. 16 | // 17 | // The calculation presumes that your column structure will be missing the last gutter: 18 | // 19 | // -- column -- gutter -- column -- gutter -- column 20 | // 21 | // $fg-column: 60px; // Column Width 22 | // $fg-gutter: 25px; // Gutter Width 23 | // $fg-max-columns: 12; // Total Columns For Main Container 24 | // 25 | // div { 26 | // width: flex-grid(4); // returns (315px / 995px) = 31.65829%; 27 | // margin-left: flex-gutter(); // returns (25px / 995px) = 2.51256%; 28 | // 29 | // p { 30 | // width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%; 31 | // float: left; 32 | // margin: flex-gutter(4); // returns (25px / 315px) = 7.936508%; 33 | // } 34 | // 35 | // blockquote { 36 | // float: left; 37 | // width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%; 38 | // } 39 | // } -------------------------------------------------------------------------------- /app/assets/stylesheets/functions/_radial-gradient.scss: -------------------------------------------------------------------------------- 1 | // This function is required and used by the background-image mixin. 2 | @function radial-gradient($G1, $G2, 3 | $G3: false, $G4: false, 4 | $G5: false, $G6: false, 5 | $G7: false, $G8: false, 6 | $G9: false, $G10: false, 7 | $pos: 50% 50%, 8 | $shape-size: ellipse cover) { 9 | 10 | @each $value in $G1, $G2 { 11 | $first-val: nth($value, 1); 12 | $pos-type: type-of($first-val); 13 | 14 | @if ($pos-type != color) or ($first-val != "transparent") { 15 | @if ($pos-type == number) 16 | or ($first-val == "center") 17 | or ($first-val == "top") 18 | or ($first-val == "right") 19 | or ($first-val == "bottom") 20 | or ($first-val == "left") { 21 | 22 | $pos: $value; 23 | 24 | @if $pos == $G1 { 25 | $G1: false; 26 | } 27 | } 28 | 29 | @else if 30 | ($first-val == "ellipse") 31 | or ($first-val == "circle") 32 | or ($first-val == "closest-side") 33 | or ($first-val == "closest-corner") 34 | or ($first-val == "farthest-side") 35 | or ($first-val == "farthest-corner") 36 | or ($first-val == "contain") 37 | or ($first-val == "cover") { 38 | 39 | $shape-size: $value; 40 | 41 | @if $value == $G1 { 42 | $G1: false; 43 | } 44 | 45 | @else if $value == $G2 { 46 | $G2: false; 47 | } 48 | } 49 | } 50 | } 51 | 52 | $type: radial; 53 | $gradient: compact($pos, $shape-size, $G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10); 54 | $type-gradient: append($type, $gradient, comma); 55 | 56 | @return $type-gradient; 57 | } 58 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_animation.scss: -------------------------------------------------------------------------------- 1 | // http://www.w3.org/TR/css3-animations/#the-animation-name-property- 2 | // Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties. 3 | 4 | // Official animation shorthand property. 5 | @mixin animation ($animations...) { 6 | @include prefixer(animation, $animations, webkit moz spec); 7 | } 8 | 9 | // Individual Animation Properties 10 | @mixin animation-name ($names...) { 11 | @include prefixer(animation-name, $names, webkit moz spec); 12 | } 13 | 14 | 15 | @mixin animation-duration ($times...) { 16 | @include prefixer(animation-duration, $times, webkit moz spec); 17 | } 18 | 19 | 20 | @mixin animation-timing-function ($motions...) { 21 | // ease | linear | ease-in | ease-out | ease-in-out 22 | @include prefixer(animation-timing-function, $motions, webkit moz spec); 23 | } 24 | 25 | 26 | @mixin animation-iteration-count ($values...) { 27 | // infinite | 28 | @include prefixer(animation-iteration-count, $values, webkit moz spec); 29 | } 30 | 31 | 32 | @mixin animation-direction ($directions...) { 33 | // normal | alternate 34 | @include prefixer(animation-direction, $directions, webkit moz spec); 35 | } 36 | 37 | 38 | @mixin animation-play-state ($states...) { 39 | // running | paused 40 | @include prefixer(animation-play-state, $states, webkit moz spec); 41 | } 42 | 43 | 44 | @mixin animation-delay ($times...) { 45 | @include prefixer(animation-delay, $times, webkit moz spec); 46 | } 47 | 48 | 49 | @mixin animation-fill-mode ($modes...) { 50 | // none | forwards | backwards | both 51 | @include prefixer(animation-fill-mode, $modes, webkit moz spec); 52 | } 53 | -------------------------------------------------------------------------------- /app/assets/stylesheets/addons/_timing-functions.scss: -------------------------------------------------------------------------------- 1 | // CSS cubic-bezier timing functions. Timing functions courtesy of jquery.easie (github.com/jaukia/easie) 2 | // Timing functions are the same as demo'ed here: http://jqueryui.com/demos/effect/easing.html 3 | 4 | // EASE IN 5 | $ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530); 6 | $ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190); 7 | $ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220); 8 | $ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060); 9 | $ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715); 10 | $ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035); 11 | $ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335); 12 | $ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045); 13 | 14 | // EASE OUT 15 | $ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940); 16 | $ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000); 17 | $ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000); 18 | $ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000); 19 | $ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000); 20 | $ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000); 21 | $ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000); 22 | $ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275); 23 | 24 | // EASE IN OUT 25 | $ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955); 26 | $ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000); 27 | $ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000); 28 | $ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000); 29 | $ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950); 30 | $ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000); 31 | $ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860); 32 | $ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550); 33 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_background-image.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Background-image property for adding multiple background images with 3 | // gradients, or for stringing multiple gradients together. 4 | //************************************************************************// 5 | 6 | @mixin background-image($images...) { 7 | background-image: add-prefix($images, webkit); 8 | background-image: add-prefix($images, moz); 9 | background-image: add-prefix($images, ms); 10 | background-image: add-prefix($images, o); 11 | background-image: add-prefix($images); 12 | } 13 | 14 | 15 | @function add-prefix($images, $vendor: false) { 16 | $images-prefixed: (); 17 | 18 | @for $i from 1 through length($images) { 19 | $type: type-of(nth($images, $i)); // Get type of variable - List or String 20 | 21 | // If variable is a list - Gradient 22 | @if $type == list { 23 | $gradient-type: nth(nth($images, $i), 1); // Get type of gradient (linear || radial) 24 | $gradient-args: nth(nth($images, $i), 2); // Get actual gradient (red, blue) 25 | 26 | $gradient: render-gradients($gradient-args, $gradient-type, $vendor); 27 | $images-prefixed: append($images-prefixed, $gradient, comma); 28 | } 29 | 30 | // If variable is a string - Image 31 | @else if $type == string { 32 | $images-prefixed: join($images-prefixed, nth($images, $i), comma); 33 | } 34 | } 35 | @return $images-prefixed; 36 | } 37 | 38 | 39 | //Examples: 40 | //@include background-image(linear-gradient(top, orange, red)); 41 | //@include background-image(radial-gradient(50% 50%, cover circle, orange, red)); 42 | //@include background-image(url("/images/a.png"), linear-gradient(orange, red)); 43 | //@include background-image(url("image.png"), linear-gradient(orange, red), url("image.png")); 44 | //@include background-image(linear-gradient(hsla(0, 100%, 100%, 0.25) 0%, hsla(0, 100%, 100%, 0.08) 50%, transparent 50%), linear-gradient(orange, red)); 45 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_linear-gradient.scss: -------------------------------------------------------------------------------- 1 | @mixin linear-gradient($pos, $G1, $G2: false, 2 | $G3: false, $G4: false, 3 | $G5: false, $G6: false, 4 | $G7: false, $G8: false, 5 | $G9: false, $G10: false, 6 | $deprecated-pos1: left top, 7 | $deprecated-pos2: left bottom, 8 | $fallback: false) { 9 | // Detect what type of value exists in $pos 10 | $pos-type: type-of(nth($pos, 1)); 11 | 12 | // If $pos is missing from mixin, reassign vars and add default position 13 | @if ($pos-type == color) or (nth($pos, 1) == "transparent") { 14 | $G10: $G9; $G9: $G8; $G8: $G7; $G7: $G6; $G6: $G5; 15 | $G5: $G4; $G4: $G3; $G3: $G2; $G2: $G1; $G1: $pos; 16 | $pos: top; // Default position 17 | } 18 | 19 | $full: compact($G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10); 20 | 21 | // Set $G1 as the default fallback color 22 | $fallback-color: nth($G1, 1); 23 | 24 | // If $fallback is a color use that color as the fallback color 25 | @if (type-of($fallback) == color) or ($fallback == "transparent") { 26 | $fallback-color: $fallback; 27 | } 28 | 29 | background-color: $fallback-color; 30 | background-image: deprecated-webkit-gradient(linear, $deprecated-pos1, $deprecated-pos2, $full); // Safari <= 5.0 31 | background-image: -webkit-linear-gradient($pos, $full); // Safari 5.1+, Chrome 32 | background-image: -moz-linear-gradient($pos, $full); 33 | background-image: -ms-linear-gradient($pos, $full); 34 | background-image: -o-linear-gradient($pos, $full); 35 | background-image: unquote("linear-gradient(#{$pos}, #{$full})"); 36 | } 37 | 38 | 39 | // Usage: Gradient position is optional, default is top. Position can be a degree. Color stops are optional as well. 40 | // @include linear-gradient(#1e5799, #2989d8); 41 | // @include linear-gradient(#1e5799, #2989d8, $fallback:#2989d8); 42 | // @include linear-gradient(top, #1e5799 0%, #2989d8 50%); 43 | // @include linear-gradient(50deg, rgba(10, 10, 10, 0.5) 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%); 44 | -------------------------------------------------------------------------------- /lib/bourbon/generator.rb: -------------------------------------------------------------------------------- 1 | require 'bourbon/version' 2 | require "fileutils" 3 | require 'thor' 4 | 5 | module Bourbon 6 | class Generator < Thor 7 | map ['-v', '--version'] => :version 8 | 9 | desc 'install', 'Install Bourbon into your project' 10 | method_options :path => :string, :force => :boolean 11 | def install 12 | if bourbon_files_already_exist? && !options[:force] 13 | puts "Bourbon files already installed, doing nothing." 14 | else 15 | install_files 16 | puts "Bourbon files installed to #{install_path}/" 17 | end 18 | end 19 | 20 | desc 'update', 'Update Bourbon' 21 | method_options :path => :string 22 | def update 23 | if bourbon_files_already_exist? 24 | remove_bourbon_directory 25 | install_files 26 | puts "Bourbon files updated." 27 | else 28 | puts "No existing bourbon installation. Doing nothing." 29 | end 30 | end 31 | 32 | desc 'version', 'Show Bourbon version' 33 | def version 34 | say "Bourbon #{Bourbon::VERSION}" 35 | end 36 | 37 | private 38 | 39 | def bourbon_files_already_exist? 40 | install_path.exist? 41 | end 42 | 43 | def install_path 44 | @install_path ||= if options[:path] 45 | Pathname.new(File.join(options[:path], 'bourbon')) 46 | else 47 | Pathname.new('bourbon') 48 | end 49 | end 50 | 51 | def install_files 52 | make_install_directory 53 | copy_in_scss_files 54 | end 55 | 56 | def remove_bourbon_directory 57 | FileUtils.rm_rf("bourbon") 58 | end 59 | 60 | def make_install_directory 61 | FileUtils.mkdir_p(install_path) 62 | end 63 | 64 | def copy_in_scss_files 65 | FileUtils.cp_r(all_stylesheets, install_path) 66 | end 67 | 68 | def all_stylesheets 69 | Dir["#{stylesheets_directory}/*"] 70 | end 71 | 72 | def stylesheets_directory 73 | File.join(top_level_directory, "app", "assets", "stylesheets") 74 | end 75 | 76 | def top_level_directory 77 | File.dirname(File.dirname(File.dirname(__FILE__))) 78 | end 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /app/assets/stylesheets/addons/_html5-input-types.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Generate a variable ($all-text-inputs) with a list of all html5 3 | // input types that have a text-based input, excluding textarea. 4 | // http://diveintohtml5.org/forms.html 5 | //************************************************************************// 6 | $inputs-list: 'input[type="email"]', 7 | 'input[type="number"]', 8 | 'input[type="password"]', 9 | 'input[type="search"]', 10 | 'input[type="tel"]', 11 | 'input[type="text"]', 12 | 'input[type="url"]', 13 | 14 | // Webkit & Gecko may change the display of these in the future 15 | 'input[type="color"]', 16 | 'input[type="date"]', 17 | 'input[type="datetime"]', 18 | 'input[type="datetime-local"]', 19 | 'input[type="month"]', 20 | 'input[type="time"]', 21 | 'input[type="week"]'; 22 | 23 | $unquoted-inputs-list: (); 24 | @each $input-type in $inputs-list { 25 | $unquoted-inputs-list: append($unquoted-inputs-list, unquote($input-type), comma); 26 | } 27 | 28 | $all-text-inputs: $unquoted-inputs-list; 29 | 30 | 31 | // Hover Pseudo-class 32 | //************************************************************************// 33 | $all-text-inputs-hover: (); 34 | @each $input-type in $unquoted-inputs-list { 35 | $input-type-hover: $input-type + ":hover"; 36 | $all-text-inputs-hover: append($all-text-inputs-hover, $input-type-hover, comma); 37 | } 38 | 39 | // Focus Pseudo-class 40 | //************************************************************************// 41 | $all-text-inputs-focus: (); 42 | @each $input-type in $unquoted-inputs-list { 43 | $input-type-focus: $input-type + ":focus"; 44 | $all-text-inputs-focus: append($all-text-inputs-focus, $input-type-focus, comma); 45 | } 46 | 47 | // You must use interpolation on the variable: 48 | // #{$all-text-inputs} 49 | // #{$all-text-inputs-hover} 50 | // #{$all-text-inputs-focus} 51 | 52 | // Example 53 | //************************************************************************// 54 | // #{$all-text-inputs}, textarea { 55 | // border: 1px solid red; 56 | // } 57 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_border-image.scss: -------------------------------------------------------------------------------- 1 | @mixin border-image($images) { 2 | -webkit-border-image: border-add-prefix($images, webkit); 3 | -moz-border-image: border-add-prefix($images, moz); 4 | -o-border-image: border-add-prefix($images, o); 5 | border-image: border-add-prefix($images); 6 | } 7 | 8 | @function border-add-prefix($images, $vendor: false) { 9 | $border-image: (); 10 | $images-type: type-of(nth($images, 1)); 11 | $first-var: nth(nth($images, 1), 1); // Get type of Gradient (Linear || radial) 12 | 13 | // If input is a gradient 14 | @if $images-type == string { 15 | @if ($first-var == "linear") or ($first-var == "radial") { 16 | @for $i from 2 through length($images) { 17 | $gradient-type: nth($images, 1); // Get type of gradient (linear || radial) 18 | $gradient-args: nth($images, $i); // Get actual gradient (red, blue) 19 | $border-image: render-gradients($gradient-args, $gradient-type, $vendor); 20 | } 21 | } 22 | 23 | // If input is a URL 24 | @else { 25 | $border-image: $images; 26 | } 27 | } 28 | 29 | // If input is gradient or url + additional args 30 | @else if $images-type == list { 31 | @for $i from 1 through length($images) { 32 | $type: type-of(nth($images, $i)); // Get type of variable - List or String 33 | 34 | // If variable is a list - Gradient 35 | @if $type == list { 36 | $gradient-type: nth(nth($images, $i), 1); // Get type of gradient (linear || radial) 37 | $gradient-args: nth(nth($images, $i), 2); // Get actual gradient (red, blue) 38 | $border-image: render-gradients($gradient-args, $gradient-type, $vendor); 39 | } 40 | 41 | // If variable is a string - Image or number 42 | @else if ($type == string) or ($type == number) { 43 | $border-image: append($border-image, nth($images, $i)); 44 | } 45 | } 46 | } 47 | @return $border-image; 48 | } 49 | 50 | //Examples: 51 | // @include border-image(url("image.png")); 52 | // @include border-image(url("image.png") 20 stretch); 53 | // @include border-image(linear-gradient(45deg, orange, yellow)); 54 | // @include border-image(linear-gradient(45deg, orange, yellow) stretch); 55 | // @include border-image(linear-gradient(45deg, orange, yellow) 20 30 40 50 stretch round); 56 | // @include border-image(radial-gradient(top, cover, orange, yellow, orange)); 57 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_radial-gradient.scss: -------------------------------------------------------------------------------- 1 | // Requires Sass 3.1+ 2 | @mixin radial-gradient($G1, $G2, 3 | $G3: false, $G4: false, 4 | $G5: false, $G6: false, 5 | $G7: false, $G8: false, 6 | $G9: false, $G10: false, 7 | $pos: 50% 50%, 8 | $shape-size: ellipse cover, 9 | $deprecated-pos1: center center, 10 | $deprecated-pos2: center center, 11 | $deprecated-radius1: 0, 12 | $deprecated-radius2: 460, 13 | $fallback: false) { 14 | 15 | @each $value in $G1, $G2 { 16 | $first-val: nth($value, 1); 17 | $pos-type: type-of($first-val); 18 | 19 | @if ($pos-type != color) or ($first-val != "transparent") { 20 | @if ($pos-type == number) 21 | or ($first-val == "center") 22 | or ($first-val == "top") 23 | or ($first-val == "right") 24 | or ($first-val == "bottom") 25 | or ($first-val == "left") { 26 | 27 | $pos: $value; 28 | 29 | @if $pos == $G1 { 30 | $G1: false; 31 | } 32 | } 33 | 34 | @else if 35 | ($first-val == "ellipse") 36 | or ($first-val == "circle") 37 | or ($first-val == "closest-side") 38 | or ($first-val == "closest-corner") 39 | or ($first-val == "farthest-side") 40 | or ($first-val == "farthest-corner") 41 | or ($first-val == "contain") 42 | or ($first-val == "cover") { 43 | 44 | $shape-size: $value; 45 | 46 | @if $value == $G1 { 47 | $G1: false; 48 | } 49 | 50 | @else if $value == $G2 { 51 | $G2: false; 52 | } 53 | } 54 | } 55 | } 56 | 57 | $full: compact($G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10); 58 | 59 | // Set $G1 as the default fallback color 60 | $first-color: nth($full, 1); 61 | $fallback-color: nth($first-color, 1); 62 | 63 | @if (type-of($fallback) == color) or ($fallback == "transparent") { 64 | $fallback-color: $fallback; 65 | } 66 | 67 | background-color: $fallback-color; 68 | background-image: deprecated-webkit-gradient(radial, $deprecated-pos1, $deprecated-pos2, $full, $deprecated-radius1, $deprecated-radius2); // Safari <= 5.0 69 | background-image: -webkit-radial-gradient($pos, $shape-size, $full); 70 | background-image: -moz-radial-gradient($pos, $shape-size, $full); 71 | background-image: -ms-radial-gradient($pos, $shape-size, $full); 72 | background-image: -o-radial-gradient($pos, $shape-size, $full); 73 | background-image: unquote("radial-gradient(#{$pos}, #{$shape-size}, #{$full})"); 74 | } 75 | 76 | // Usage: Gradient position and shape-size are required. Color stops are optional. 77 | // @include radial-gradient(50% 50%, circle cover, #1e5799, #efefef); 78 | // @include radial-gradient(50% 50%, circle cover, #eee 10%, #1e5799 30%, #efefef); 79 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | [![Bourbon Sass Mixin Library](http://bourbon.io/images/bourbon-logo.png)](http://bourbon.io) 2 | 3 | # A simple and lightweight mixin library for Sass 4 | Bourbon is a comprehensive library of sass mixins that are designed to be simple 5 | and easy to use. No configuration required. 6 | The mixins aim to be as vanilla as possible, meaning they should be as close to the original CSS syntax as possible. 7 | 8 | The mixins contain vendor specific prefixes for all CSS3 properties for support 9 | amongst modern browsers. The prefixes also ensure graceful degradation for older 10 | browsers that support only CSS3 prefixed properties. Bourbon uses SCSS syntax. 11 | 12 | #[Documentation & Demo](http://bourbon.io) 13 | 14 | ## Requirements 15 | Sass 3.2+ 16 | 17 | # Install for Rails 3.1+ 18 | In your Gemfile: 19 | 20 | gem 'bourbon' 21 | 22 | Then run: 23 | 24 | $ bundle install 25 | 26 | Restart your server. Then rename application`.css` to application`.css.scss`: 27 | 28 | mv app/assets/stylesheets/application.css app/assets/stylesheets/application.css.scss 29 | 30 | Delete the sprocket directive in application.css.scss: [Why?](https://github.com/thoughtbot/bourbon/wiki/Rails-Sprockets) 31 | 32 | *= require_tree . 33 | 34 | Import Bourbon at the beginning of application.css.scss. All additional stylesheets must be imported below Bourbon: 35 | 36 | @import "bourbon"; 37 | @import "home"; 38 | @import "users"; 39 | 40 | 41 | [Help! I'm getting an undefined mixin error.](https://github.com/thoughtbot/bourbon/wiki/Rails-Help-%5C-Undefined-mixin) 42 | 43 | ##### [Rails 3.0.x Install Instructions](https://github.com/thoughtbot/bourbon/wiki/Rails-3.0.x-Install) | [Rails 2.3 Install Instructions](https://github.com/thoughtbot/bourbon/wiki/Bourbon-v2.x-or-Rails-2.3-Install) 44 | 45 | # Non-Rails projects 46 | Bourbon includes an easy way to generate a directory with all the necessary files. 47 | For command line help: `$ bourbon help` or visit the [Command line tools wiki](https://github.com/thoughtbot/bourbon/wiki/Command-Line-Tools) 48 | 49 | ####Install (Bourbon v3.0+) 50 | 51 | gem install bourbon 52 | 53 | Install Bourbon into the current directory by generating the `bourbon` folder: 54 | 55 | bourbon install 56 | 57 | The generated folder will contain all the mixins and other necessary Bourbon files. It is recommended not to add or modify the Bourbon files so that you can update Bourbon easily. 58 | 59 | #### Import 60 | 61 | Lastly, import the mixins at the beginning of your stylesheet(s): 62 | 63 | @import 'bourbon/bourbon'; 64 | 65 | Note: Bourbon no longer requires a custom `sass --watch` command for Bourbon v3.0+ 66 | 67 | #### Other Commands 68 | Visit the [Command line tools wiki](https://github.com/thoughtbot/bourbon/wiki/Command-Line-Tools) for a complete list 69 | 70 | bourbon help 71 | bourbon update 72 | 73 | ##### [Bourbon v2.x install instructions](https://github.com/thoughtbot/bourbon/wiki/Bourbon-v2.x-or-Rails-2.3-Install) 74 | 75 | ------- 76 | # [Changelog](https://github.com/thoughtbot/bourbon/wiki) 77 | 78 | # [Browser support](https://github.com/thoughtbot/bourbon/wiki/Browser-Support) 79 | ------- 80 | 81 | Credits 82 | ------- 83 | 84 | ![thoughtbot](http://thoughtbot.com/images/tm/logo.png) 85 | 86 | Bourbon is maintained and funded by [thoughtbot, inc](http://thoughtbot.com/community) 87 | 88 | The names and logos for thoughtbot are trademarks of thoughtbot, inc. 89 | 90 | Got questions? Need help? Tweet at [@phillapier](http://twitter.com/phillapier). 91 | 92 | License 93 | ------- 94 | 95 | Bourbon is Copyright © 2011-2013 thoughtbot. It is free software, and may be redistributed under the terms specified in the LICENSE file. 96 | -------------------------------------------------------------------------------- /app/assets/stylesheets/css3/_background.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Background property for adding multiple backgrounds using shorthand 3 | // notation. 4 | //************************************************************************// 5 | 6 | @mixin background( 7 | $background-1 , $background-2: false, 8 | $background-3: false, $background-4: false, 9 | $background-5: false, $background-6: false, 10 | $background-7: false, $background-8: false, 11 | $background-9: false, $background-10: false, 12 | $fallback: false 13 | ) { 14 | $backgrounds: compact($background-1, $background-2, 15 | $background-3, $background-4, 16 | $background-5, $background-6, 17 | $background-7, $background-8, 18 | $background-9, $background-10); 19 | 20 | $fallback-color: false; 21 | @if (type-of($fallback) == color) or ($fallback == "transparent") { 22 | $fallback-color: $fallback; 23 | } 24 | @else { 25 | $fallback-color: extract-background-color($backgrounds); 26 | } 27 | 28 | @if $fallback-color { 29 | background-color: $fallback-color; 30 | } 31 | background: background-add-prefix($backgrounds, webkit); 32 | background: background-add-prefix($backgrounds, moz); 33 | background: background-add-prefix($backgrounds, ms); 34 | background: background-add-prefix($backgrounds, o); 35 | background: background-add-prefix($backgrounds); 36 | } 37 | 38 | @function extract-background-color($backgrounds) { 39 | $final-bg-layer: nth($backgrounds, length($backgrounds)); 40 | @if type-of($final-bg-layer) == list { 41 | @for $i from 1 through length($final-bg-layer) { 42 | $value: nth($final-bg-layer, $i); 43 | @if type-of($value) == color { 44 | @return $value; 45 | } 46 | } 47 | } 48 | @return false; 49 | } 50 | 51 | 52 | @function background-add-prefix($backgrounds, $vendor: false) { 53 | $backgrounds-prefixed: (); 54 | 55 | @for $i from 1 through length($backgrounds) { 56 | $shorthand: nth($backgrounds, $i); // Get member for current index 57 | $type: type-of($shorthand); // Get type of variable - List or String 58 | 59 | // If shorthand is a list 60 | @if $type == list { 61 | $first-member: nth($shorthand, 1); // Get first member of shorthand 62 | 63 | // Linear Gradient 64 | @if index(linear radial, nth($first-member, 1)) { 65 | $gradient-type: nth($first-member, 1); // linear || radial 66 | 67 | // Get actual gradient (red, blue) 68 | $gradient-args: false; 69 | $shorthand-start: false; 70 | // Linear gradient and positioning, repeat, etc. values 71 | @if type-of($first-member) == list { 72 | $gradient-args: nth($first-member, 2); 73 | $shorthand-start: 2; 74 | } 75 | // Linear gradient only 76 | @else { 77 | $gradient-args: nth($shorthand, 2); // Get actual gradient (red, blue) 78 | $shorthand-start: 3; 79 | } 80 | 81 | $gradient: render-gradients($gradient-args, $gradient-type, $vendor); 82 | @for $j from $shorthand-start through length($shorthand) { 83 | $gradient: join($gradient, nth($shorthand, $j), space); 84 | } 85 | $backgrounds-prefixed: append($backgrounds-prefixed, $gradient, comma); 86 | } 87 | 88 | // Image with additional properties 89 | @else { 90 | $backgrounds-prefixed: append($backgrounds-prefixed, $shorthand, comma); 91 | } 92 | 93 | } 94 | 95 | // If shorthand is a simple string, color or image 96 | @else if $type == string { 97 | $backgrounds-prefixed: join($backgrounds-prefixed, $shorthand, comma); 98 | } 99 | } 100 | @return $backgrounds-prefixed; 101 | } 102 | 103 | //Examples: 104 | //@include background(linear-gradient(top, orange, red)); 105 | //@include background(radial-gradient(50% 50%, cover circle, orange, red)); 106 | //@include background(url("/images/a.png") no-repeat, linear-gradient(orange, red)); 107 | //@include background(url("image.png") center center, linear-gradient(orange, red), url("image.png")); 108 | -------------------------------------------------------------------------------- /app/assets/stylesheets/addons/_button.scss: -------------------------------------------------------------------------------- 1 | @mixin button ($style: simple, $base-color: #4294f0) { 2 | 3 | @if type-of($style) == color { 4 | $base-color: $style; 5 | $style: simple; 6 | } 7 | 8 | // Grayscale button 9 | @if $base-color == grayscale($base-color) { 10 | @if $style == simple { 11 | @include simple($base-color, $grayscale: true); 12 | } 13 | 14 | @else if $style == shiny { 15 | @include shiny($base-color, $grayscale: true); 16 | } 17 | 18 | @else if $style == pill { 19 | @include pill($base-color, $grayscale: true); 20 | } 21 | } 22 | 23 | // Colored button 24 | @else { 25 | @if $style == simple { 26 | @include simple($base-color); 27 | } 28 | 29 | @else if $style == shiny { 30 | @include shiny($base-color); 31 | } 32 | 33 | @else if $style == pill { 34 | @include pill($base-color); 35 | } 36 | } 37 | 38 | &:disabled { 39 | opacity: 0.5; 40 | cursor: not-allowed; 41 | } 42 | } 43 | 44 | 45 | // Simple Button 46 | //************************************************************************// 47 | @mixin simple($base-color, $grayscale: false) { 48 | $color: hsl(0, 0, 100%); 49 | $border: adjust-color($base-color, $saturation: 9%, $lightness: -14%); 50 | $inset-shadow: adjust-color($base-color, $saturation: -8%, $lightness: 15%); 51 | $stop-gradient: adjust-color($base-color, $saturation: 9%, $lightness: -11%); 52 | $text-shadow: adjust-color($base-color, $saturation: 15%, $lightness: -18%); 53 | 54 | @if lightness($base-color) > 70% { 55 | $color: hsl(0, 0, 20%); 56 | $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); 57 | } 58 | 59 | @if $grayscale == true { 60 | $border: grayscale($border); 61 | $inset-shadow: grayscale($inset-shadow); 62 | $stop-gradient: grayscale($stop-gradient); 63 | $text-shadow: grayscale($text-shadow); 64 | } 65 | 66 | border: 1px solid $border; 67 | border-radius: 3px; 68 | @include box-shadow (inset 0 1px 0 0 $inset-shadow); 69 | color: $color; 70 | display: inline-block; 71 | font-size: 11px; 72 | font-weight: bold; 73 | @include linear-gradient ($base-color, $stop-gradient); 74 | padding: 7px 18px; 75 | text-decoration: none; 76 | text-shadow: 0 1px 0 $text-shadow; 77 | -webkit-background-clip: padding-box; 78 | 79 | &:hover:not(:disabled) { 80 | $base-color-hover: adjust-color($base-color, $saturation: -4%, $lightness: -5%); 81 | $inset-shadow-hover: adjust-color($base-color, $saturation: -7%, $lightness: 5%); 82 | $stop-gradient-hover: adjust-color($base-color, $saturation: 8%, $lightness: -14%); 83 | 84 | @if $grayscale == true { 85 | $base-color-hover: grayscale($base-color-hover); 86 | $inset-shadow-hover: grayscale($inset-shadow-hover); 87 | $stop-gradient-hover: grayscale($stop-gradient-hover); 88 | } 89 | 90 | @include box-shadow (inset 0 1px 0 0 $inset-shadow-hover); 91 | cursor: pointer; 92 | @include linear-gradient ($base-color-hover, $stop-gradient-hover); 93 | } 94 | 95 | &:active:not(:disabled) { 96 | $border-active: adjust-color($base-color, $saturation: 9%, $lightness: -14%); 97 | $inset-shadow-active: adjust-color($base-color, $saturation: 7%, $lightness: -17%); 98 | 99 | @if $grayscale == true { 100 | $border-active: grayscale($border-active); 101 | $inset-shadow-active: grayscale($inset-shadow-active); 102 | } 103 | 104 | border: 1px solid $border-active; 105 | @include box-shadow (inset 0 0 8px 4px $inset-shadow-active, inset 0 0 8px 4px $inset-shadow-active, 0 1px 1px 0 #eee); 106 | } 107 | } 108 | 109 | 110 | // Shiny Button 111 | //************************************************************************// 112 | @mixin shiny($base-color, $grayscale: false) { 113 | $color: hsl(0, 0, 100%); 114 | $border: adjust-color($base-color, $red: -117, $green: -111, $blue: -81); 115 | $border-bottom: adjust-color($base-color, $red: -126, $green: -127, $blue: -122); 116 | $fourth-stop: adjust-color($base-color, $red: -79, $green: -70, $blue: -46); 117 | $inset-shadow: adjust-color($base-color, $red: 37, $green: 29, $blue: 12); 118 | $second-stop: adjust-color($base-color, $red: -56, $green: -50, $blue: -33); 119 | $text-shadow: adjust-color($base-color, $red: -140, $green: -141, $blue: -114); 120 | $third-stop: adjust-color($base-color, $red: -86, $green: -75, $blue: -48); 121 | 122 | @if lightness($base-color) > 70% { 123 | $color: hsl(0, 0, 20%); 124 | $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); 125 | } 126 | 127 | @if $grayscale == true { 128 | $border: grayscale($border); 129 | $border-bottom: grayscale($border-bottom); 130 | $fourth-stop: grayscale($fourth-stop); 131 | $inset-shadow: grayscale($inset-shadow); 132 | $second-stop: grayscale($second-stop); 133 | $text-shadow: grayscale($text-shadow); 134 | $third-stop: grayscale($third-stop); 135 | } 136 | 137 | border: 1px solid $border; 138 | border-bottom: 1px solid $border-bottom; 139 | border-radius: 5px; 140 | @include box-shadow(inset 0 1px 0 0 $inset-shadow); 141 | color: $color; 142 | display: inline-block; 143 | font-size: 14px; 144 | font-weight: bold; 145 | @include linear-gradient(top, $base-color 0%, $second-stop 50%, $third-stop 50%, $fourth-stop 100%); 146 | padding: 8px 20px; 147 | text-align: center; 148 | text-decoration: none; 149 | text-shadow: 0 -1px 1px $text-shadow; 150 | 151 | &:hover:not(:disabled) { 152 | $first-stop-hover: adjust-color($base-color, $red: -13, $green: -15, $blue: -18); 153 | $second-stop-hover: adjust-color($base-color, $red: -66, $green: -62, $blue: -51); 154 | $third-stop-hover: adjust-color($base-color, $red: -93, $green: -85, $blue: -66); 155 | $fourth-stop-hover: adjust-color($base-color, $red: -86, $green: -80, $blue: -63); 156 | 157 | @if $grayscale == true { 158 | $first-stop-hover: grayscale($first-stop-hover); 159 | $second-stop-hover: grayscale($second-stop-hover); 160 | $third-stop-hover: grayscale($third-stop-hover); 161 | $fourth-stop-hover: grayscale($fourth-stop-hover); 162 | } 163 | 164 | cursor: pointer; 165 | @include linear-gradient(top, $first-stop-hover 0%, 166 | $second-stop-hover 50%, 167 | $third-stop-hover 50%, 168 | $fourth-stop-hover 100%); 169 | } 170 | 171 | &:active:not(:disabled) { 172 | $inset-shadow-active: adjust-color($base-color, $red: -111, $green: -116, $blue: -122); 173 | 174 | @if $grayscale == true { 175 | $inset-shadow-active: grayscale($inset-shadow-active); 176 | } 177 | 178 | @include box-shadow(inset 0 0 20px 0 $inset-shadow-active, 0 1px 0 #fff); 179 | } 180 | } 181 | 182 | 183 | // Pill Button 184 | //************************************************************************// 185 | @mixin pill($base-color, $grayscale: false) { 186 | $color: hsl(0, 0, 100%); 187 | $border-bottom: adjust-color($base-color, $hue: 8, $saturation: -11%, $lightness: -26%); 188 | $border-sides: adjust-color($base-color, $hue: 4, $saturation: -21%, $lightness: -21%); 189 | $border-top: adjust-color($base-color, $hue: -1, $saturation: -30%, $lightness: -15%); 190 | $inset-shadow: adjust-color($base-color, $hue: -1, $saturation: -1%, $lightness: 7%); 191 | $stop-gradient: adjust-color($base-color, $hue: 8, $saturation: 14%, $lightness: -10%); 192 | $text-shadow: adjust-color($base-color, $hue: 5, $saturation: -19%, $lightness: -15%); 193 | 194 | @if lightness($base-color) > 70% { 195 | $color: hsl(0, 0, 20%); 196 | $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); 197 | } 198 | 199 | @if $grayscale == true { 200 | $border-bottom: grayscale($border-bottom); 201 | $border-sides: grayscale($border-sides); 202 | $border-top: grayscale($border-top); 203 | $inset-shadow: grayscale($inset-shadow); 204 | $stop-gradient: grayscale($stop-gradient); 205 | $text-shadow: grayscale($text-shadow); 206 | } 207 | 208 | border: 1px solid $border-top; 209 | border-color: $border-top $border-sides $border-bottom; 210 | border-radius: 16px; 211 | @include box-shadow(inset 0 1px 0 0 $inset-shadow, 0 1px 2px 0 #b3b3b3); 212 | color: $color; 213 | display: inline-block; 214 | font-size: 11px; 215 | font-weight: normal; 216 | line-height: 1; 217 | @include linear-gradient ($base-color, $stop-gradient); 218 | padding: 5px 16px; 219 | text-align: center; 220 | text-decoration: none; 221 | text-shadow: 0 -1px 1px $text-shadow; 222 | -webkit-background-clip: padding-box; 223 | 224 | &:hover:not(:disabled) { 225 | $base-color-hover: adjust-color($base-color, $lightness: -4.5%); 226 | $border-bottom: adjust-color($base-color, $hue: 8, $saturation: 13.5%, $lightness: -32%); 227 | $border-sides: adjust-color($base-color, $hue: 4, $saturation: -2%, $lightness: -27%); 228 | $border-top: adjust-color($base-color, $hue: -1, $saturation: -17%, $lightness: -21%); 229 | $inset-shadow-hover: adjust-color($base-color, $saturation: -1%, $lightness: 3%); 230 | $stop-gradient-hover: adjust-color($base-color, $hue: 8, $saturation: -4%, $lightness: -15.5%); 231 | $text-shadow-hover: adjust-color($base-color, $hue: 5, $saturation: -5%, $lightness: -22%); 232 | 233 | @if $grayscale == true { 234 | $base-color-hover: grayscale($base-color-hover); 235 | $border-bottom: grayscale($border-bottom); 236 | $border-sides: grayscale($border-sides); 237 | $border-top: grayscale($border-top); 238 | $inset-shadow-hover: grayscale($inset-shadow-hover); 239 | $stop-gradient-hover: grayscale($stop-gradient-hover); 240 | $text-shadow-hover: grayscale($text-shadow-hover); 241 | } 242 | 243 | border: 1px solid $border-top; 244 | border-color: $border-top $border-sides $border-bottom; 245 | @include box-shadow(inset 0 1px 0 0 $inset-shadow-hover); 246 | cursor: pointer; 247 | @include linear-gradient ($base-color-hover, $stop-gradient-hover); 248 | text-shadow: 0 -1px 1px $text-shadow-hover; 249 | -webkit-background-clip: padding-box; 250 | } 251 | 252 | &:active:not(:disabled) { 253 | $active-color: adjust-color($base-color, $hue: 4, $saturation: -12%, $lightness: -10%); 254 | $border-active: adjust-color($base-color, $hue: 6, $saturation: -2.5%, $lightness: -30%); 255 | $border-bottom-active: adjust-color($base-color, $hue: 11, $saturation: 6%, $lightness: -31%); 256 | $inset-shadow-active: adjust-color($base-color, $hue: 9, $saturation: 2%, $lightness: -21.5%); 257 | $text-shadow-active: adjust-color($base-color, $hue: 5, $saturation: -12%, $lightness: -21.5%); 258 | 259 | @if $grayscale == true { 260 | $active-color: grayscale($active-color); 261 | $border-active: grayscale($border-active); 262 | $border-bottom-active: grayscale($border-bottom-active); 263 | $inset-shadow-active: grayscale($inset-shadow-active); 264 | $text-shadow-active: grayscale($text-shadow-active); 265 | } 266 | 267 | background: $active-color; 268 | border: 1px solid $border-active; 269 | border-bottom: 1px solid $border-bottom-active; 270 | @include box-shadow(inset 0 0 6px 3px $inset-shadow-active, 0 1px 0 0 #fff); 271 | text-shadow: 0 -1px 1px $text-shadow-active; 272 | } 273 | } 274 | --------------------------------------------------------------------------------