├── .npmignore ├── .gitignore ├── .sassdocrc ├── knapsack ├── _index.scss ├── _ui.scss ├── _code.scss ├── _settings.scss ├── _tables.scss ├── _typography.scss ├── _animation.scss ├── _utilities.scss ├── _forms.scss ├── _layout.scss └── _reset.scss ├── package.json ├── bower.json ├── readme.md ├── .scss-lint.yml └── test └── concat.scss /.npmignore: -------------------------------------------------------------------------------- 1 | .pages/ 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .sassdoc/ 2 | node_modules/ 3 | bower_components/ 4 | sassdoc/ 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /.sassdocrc: -------------------------------------------------------------------------------- 1 | display: 2 | alias: true 3 | 4 | theme: node_modules/sassdoc-theme-flippant/ 5 | -------------------------------------------------------------------------------- /knapsack/_index.scss: -------------------------------------------------------------------------------- 1 | // ---- 2 | // Index 3 | // ---- 4 | 5 | @import 'settings'; 6 | @import 'utilities'; 7 | @import 'typography'; 8 | @import 'animation'; 9 | @import 'code'; 10 | @import 'layout'; 11 | @import 'tables'; 12 | @import 'reset'; 13 | @import 'ui'; 14 | @import 'forms'; 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "knapsack", 3 | "version": "1.1.0", 4 | "description": "A handy bag of sass utilities and mixins", 5 | "main": "knapsack/_index.scss", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/kni-labs/knapsack.git" 9 | }, 10 | "keywords": [ 11 | "knapsack", 12 | "kni", 13 | "sass", 14 | "scss" 15 | ], 16 | "author": "Daniel Box", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/kni-labs/knapsack/issues" 20 | }, 21 | "homepage": "http://kni-labs.github.io/knapsack", 22 | "devDependencies": { 23 | "sassdoc-theme-flippant": "0.x.x" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "knapsack", 3 | "homepage": "https://github.com/kni-labs/knapsack", 4 | "authors": [ 5 | "Daniel Box " 6 | ], 7 | "description": "Handy sass mixins and utilities", 8 | "main": "knapsack/_index.scss", 9 | "moduleType": [], 10 | "keywords": [ 11 | "knapsack", 12 | "kni", 13 | "scss", 14 | "sass" 15 | ], 16 | "license": "MIT", 17 | "ignore": [ 18 | "**/.*", 19 | "node_modules", 20 | "bower_components", 21 | ".pages", 22 | ".hound.yml", 23 | ".sassdocrc", 24 | ".scss-style.yml", 25 | "test", 26 | "tests" 27 | ], 28 | "dependencies": { 29 | "sanitize.css": "~2.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /knapsack/_ui.scss: -------------------------------------------------------------------------------- 1 | // ---- 2 | // Ui 3 | // ---- 4 | 5 | //- Mixin: Button 6 | /// 7 | /// A starting place for button styling. 8 | /// 9 | /// @param {variable} $background-color [#00BFFF] - Button background color 10 | /// @param {variable} $color [#FFF] - Button text color 11 | /// 12 | /// @group ui 13 | /// @example 14 | /// a.btn { 15 | /// @include button(); 16 | /// } 17 | /// a.yellow-button { 18 | /// @include button(yellow, black); 19 | /// } 20 | 21 | @mixin button($background-color: $color-primary, $color: #FFF) { 22 | $global-border-radius: 3px !default; 23 | padding: 10px 22px; 24 | border-radius: $global-border-radius; 25 | background-color: $background-color; 26 | color: $color; 27 | cursor: pointer; 28 | line-height: 1em; 29 | text-align: center; 30 | text-decoration: none; 31 | display: inline-block; 32 | border: none; 33 | transition: all .2s ease; 34 | 35 | &:hover { 36 | background-color: darken($background-color, 10%); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /knapsack/_code.scss: -------------------------------------------------------------------------------- 1 | // ------ 2 | // Code 3 | // ------ 4 | 5 | //- Mixin: Code 6 | /// 7 | /// Styles inline code snippets on your page. Defaults to a beautiful red, but 8 | /// can be passed any color. 9 | /// 10 | /// @group code 11 | /// @param {variable} $color [#DF5C33] - Text Color 12 | /// @example 13 | /// code { 14 | /// @include code(blue); 15 | /// } 16 | 17 | @mixin code($color : $color-primary) { 18 | padding: 3px 4px; 19 | color: $color; 20 | background-color: lighten($base-gray, 45%); 21 | border: 1px solid lighten($base-gray, 35%); 22 | border-radius: 3px; 23 | font-family: Menlo, Monaco, monospace; 24 | } 25 | 26 | //- Mixin: Pre 27 | /// 28 | /// Some default styles for code blocks on your page. Takes not arguments 29 | /// 30 | /// @group code 31 | /// @example 32 | /// pre { 33 | /// @include pre(); 34 | /// } 35 | 36 | @mixin pre() { 37 | display: block; 38 | padding: 7px; 39 | background-color: lighten($base-gray, 45%); 40 | border: 1px solid lighten($base-gray, 35%); 41 | border-radius: 3px; 42 | white-space: pre-wrap; 43 | word-break: break-all; 44 | font-family: Menlo, Monaco, monospace; 45 | line-height: 160%; 46 | } 47 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Knapsack 2 | [![npm version](https://badge.fury.io/js/knapsack.svg)](https://badge.fury.io/js/knapsack) 3 | 4 | A handy bag of Sass mixins and utilities, and the Sass little brother to Stylus's [Axis](http://www.github.com/jenius/axis/) Library. 5 | 6 | Knapsack only provides pure css as defined by the w3c spec any browser prefixing can and should be applied by [auto-prefixer](https://github.com/postcss/autoprefixer). 7 | 8 | 9 | ## Installation 10 | Currently there are 3 installation options: 11 | - With npm: `npm install knapsack` 12 | - With bower: `bower install knapsack` 13 | - or manually import `knapsack/index` into your css pipeline 14 | 15 | ## Documentation 16 | Full documentation is [**here**](http://kni-labs.github.io/knapsack/). 17 | 18 | ## Codepen Sandbox 19 | Experiment with the latest version of Knapsack [on Codepen](http://codepen.io/dbox/pen/adyyVp). 20 | 21 | ## Contributing 22 | 1. Clone/fork the repo: 23 | 2. Install dependencies: `npm install` 24 | 3. Install linter: `gem install scss-lint` 25 | 4. Add/edit scss in `/knapsack` 26 | 5. Add comments to code following [Sassdoc format](http://sassdoc.com/annotations/) 27 | 6. Run linter: `scss-lint knapsack -c .scss-style.yml` 28 | 7. Create pull request 29 | 30 | (Publishing instructions for contributors [here](https://gist.github.com/dbox/57a572101658659ce120)) 31 | 32 | ## Credits 33 | Several mixins ported and adapted from the incredible [Axis Stylus Library](http://www.github.com/jenius/axis/) and a resets are from [scut](https://github.com/davidtheclark/scut). 34 | -------------------------------------------------------------------------------- /knapsack/_settings.scss: -------------------------------------------------------------------------------- 1 | 2 | // Font stacks 3 | 4 | $sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Open Sans", "Helvetica Neue", Arial, sans-serif !default; 5 | $serif: Georgia, "Times New Roman", Times, serif !default; 6 | $monospace: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default; 7 | 8 | 9 | /// Sets the base font size for rem calculations; 10 | /// 11 | /// @group settings 12 | /// @type Number (px) 13 | $base-font-size: 16px !default; 14 | 15 | 16 | // Color Resets via Material design 17 | // http://www.google.com/design/spec/style/color.html#color-color-palette 18 | $red: #F44336 !default; 19 | $pink: #E91E63 !default; 20 | $purple: #9C27B0 !default; 21 | $deep-purple: #673AB7 !default; 22 | $indigo: #3F51B5 !default; 23 | $blue: #2196F3 !default; 24 | $light-blue: #03A9F4 !default; 25 | $cyan: #00BCD4 !default; 26 | $teal: #009688 !default; 27 | $green: #4CAF50 !default; 28 | $light-green: #8BC34A !default; 29 | $lime: #CDDC39 !default; 30 | $orange: #FF9800 !default; 31 | $deep-orange: #FF5722 !default; 32 | $brown: #795548 !default; 33 | $grey: #9E9E9E !default; 34 | $blue-gray: #607D8B !default; 35 | 36 | 37 | /// Base gray - tweak this to add slight color tint to the grayscale, then base all grays off this color. If you want flat gray use #888888 38 | /// 39 | /// @group settings 40 | /// @type Color (hex) 41 | $base-gray: #707F8C !default; 42 | 43 | // Colors by use 44 | $color-primary: $blue !default; 45 | -------------------------------------------------------------------------------- /knapsack/_tables.scss: -------------------------------------------------------------------------------- 1 | // ------ 2 | // Tables 3 | // ------ 4 | 5 | //- Mixin: Table 6 | /// 7 | /// Ported directly from Twitter Bootstrap (by way of [Axis](axis.netlify.com)), as they did an 8 | /// excellent job with the tables. 9 | /// 10 | /// @param {variable} $border [true] - Makes table bordered 11 | /// @param {variable} $striped [true] - Adds zebra striping 12 | /// @param {variable} $condensed [false] - Makes the table condensed 13 | /// @group table 14 | /// @example 15 | /// table { 16 | /// @include table(); 17 | /// } 18 | /// @todo - make hover effect optional 19 | 20 | @mixin table($border : true, $striped : true, $condensed : false) { 21 | border-collapse: collapse; 22 | border-spacing: 0; 23 | margin-bottom: 18px; 24 | max-width: 100%; 25 | width: 100%; 26 | 27 | th, 28 | td { 29 | border-top: 1px solid lighten($base-gray, 30%); 30 | line-height: 18px; 31 | padding: 8px; 32 | text-align: left; 33 | vertical-align: top; 34 | } 35 | 36 | th { 37 | font-weight: bold; 38 | } 39 | 40 | thead th { 41 | vertical-align: bottom; 42 | } 43 | 44 | thead:first-child tr th, 45 | thead:first-child tr td { 46 | border-top: 0; 47 | } 48 | 49 | tbody + tbody { 50 | border-top: 2px solid lighten($base-gray, 30%); 51 | } 52 | 53 | @if $condensed { 54 | th, 55 | td { 56 | padding: 4px 5px; 57 | } 58 | } 59 | 60 | @if $border { 61 | border: 1px solid lighten($base-gray, 30%); 62 | border-collapse: separate; 63 | border-radius: 4px; 64 | 65 | th + th, 66 | td + td, 67 | th + td, 68 | td + th { 69 | border-left: 1px solid lighten($base-gray, 30%); 70 | } 71 | 72 | thead:first-child tr:first-child th, 73 | tbody:first-child tr:first-child th, 74 | tbody:first-child tr:first-child td { 75 | border-top: 0; 76 | } 77 | 78 | thead:first-child tr:first-child th:first-child, 79 | tbody:first-child tr:first-child td:first-child { 80 | border-radius: 4px 0 0; 81 | } 82 | 83 | thead:first-child tr:first-child th:last-child, 84 | tbody:first-child tr:first-child td:last-child { 85 | border-radius: 0 4px; 86 | } 87 | 88 | thead:last-child tr:last-child th:first-child, 89 | tbody:last-child tr:last-child td:first-child { 90 | border-radius: 0 0 0 4px; 91 | } 92 | 93 | thead:last-child tr:last-child th:last-child, 94 | tbody:last-child tr:last-child td:last-child { 95 | border-radius: 0 0 4px; 96 | } 97 | } 98 | 99 | @if $striped { 100 | tbody tr:nth-child(odd) td, 101 | tbody tr:nth-child(odd) th { 102 | background-color: lighten($base-gray, 47%); 103 | } 104 | } 105 | 106 | tbody tr:hover td, 107 | tbody tr:hover th { 108 | background-color: lighten($base-gray, 47%); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /.scss-lint.yml: -------------------------------------------------------------------------------- 1 | scss_files: "**/*.scss" 2 | exclude: "**/_reset.scss" 3 | linters: 4 | BangFormat: 5 | enabled: true 6 | space_before_bang: true 7 | space_after_bang: false 8 | BorderZero: 9 | enabled: false 10 | convention: zero 11 | ColorKeyword: 12 | enabled: false 13 | severity: warning 14 | ColorVariable: 15 | enabled: false 16 | Comment: 17 | enabled: true 18 | DebugStatement: 19 | enabled: true 20 | DeclarationOrder: 21 | enabled: true 22 | DuplicateProperty: 23 | enabled: true 24 | ElsePlacement: 25 | enabled: true 26 | style: same_line 27 | EmptyLineBetweenBlocks: 28 | enabled: true 29 | ignore_single_line_blocks: true 30 | EmptyRule: 31 | enabled: true 32 | FinalNewline: 33 | enabled: true 34 | present: true 35 | HexLength: 36 | enabled: false 37 | style: short 38 | HexNotation: 39 | enabled: false 40 | style: uppercase 41 | HexValidation: 42 | enabled: true 43 | IdSelector: 44 | enabled: true 45 | ImportantRule: 46 | enabled: true 47 | ImportPath: 48 | enabled: true 49 | leading_underscore: false 50 | filename_extension: false 51 | Indentation: 52 | enabled: true 53 | allow_non_nested_indentation: false 54 | character: space 55 | width: 2 56 | LeadingZero: 57 | enabled: false 58 | style: include_zero 59 | MergeableSelector: 60 | enabled: true 61 | force_nesting: true 62 | NameFormat: 63 | enabled: true 64 | allow_leading_underscore: true 65 | convention: hyphenated_lowercase 66 | NestingDepth: 67 | enabled: true 68 | max_depth: 4 69 | severity: warning 70 | PlaceholderInExtend: 71 | enabled: false 72 | PropertyCount: 73 | enabled: false 74 | include_nested: false 75 | max_properties: 10 76 | PropertySortOrder: 77 | enabled: true 78 | ignore_unspecified: false 79 | severity: warning 80 | separate_groups: false 81 | PropertySpelling: 82 | enabled: true 83 | extra_properties: [] 84 | QualifyingElement: 85 | enabled: false 86 | allow_element_with_attribute: false 87 | allow_element_with_class: false 88 | allow_element_with_id: false 89 | severity: warning 90 | SelectorDepth: 91 | enabled: false 92 | max_depth: 5 93 | severity: warning 94 | SelectorFormat: 95 | enabled: true 96 | convention: hyphenated_lowercase 97 | Shorthand: 98 | enabled: true 99 | severity: warning 100 | SingleLinePerProperty: 101 | enabled: true 102 | allow_single_line_rule_sets: true 103 | SingleLinePerSelector: 104 | enabled: false 105 | SpaceAfterComma: 106 | enabled: true 107 | SpaceAfterPropertyColon: 108 | enabled: true 109 | style: one_space 110 | SpaceAfterPropertyName: 111 | enabled: true 112 | SpaceBeforeBrace: 113 | enabled: true 114 | style: space 115 | allow_single_line_padding: false 116 | SpaceBetweenParens: 117 | enabled: true 118 | spaces: 0 119 | StringQuotes: 120 | enabled: true 121 | style: single_quotes 122 | TrailingSemicolon: 123 | enabled: true 124 | TrailingZero: 125 | enabled: false 126 | UnnecessaryMantissa: 127 | enabled: true 128 | UnnecessaryParentReference: 129 | enabled: true 130 | UrlFormat: 131 | enabled: true 132 | UrlQuotes: 133 | enabled: true 134 | VariableForProperty: 135 | enabled: false 136 | properties: [] 137 | VendorPrefixes: 138 | enabled: true 139 | identifier_list: bourbon 140 | include: [] 141 | exclude: [] 142 | ZeroUnit: 143 | enabled: true 144 | severity: warning 145 | Compass::PropertyWithMixin: 146 | enabled: false 147 | -------------------------------------------------------------------------------- /knapsack/_typography.scss: -------------------------------------------------------------------------------- 1 | // ---- 2 | // Typography 3 | // ---- 4 | 5 | //- Mixin: Inline List 6 | /// 7 | /// For when you need your list to be horizontal. 8 | /// 9 | /// @param {variable} $spacing [20px] - Amount of spacing between elements - 10 | /// can be whatever unit you like. 11 | /// 12 | /// @group typography 13 | /// @example 14 | /// ul { 15 | /// @include inline-list(); 16 | /// } 17 | 18 | @mixin inline-list($spacing: 20px) { 19 | @include clearfix(); 20 | margin: 0; 21 | padding: 0; 22 | 23 | li { 24 | float: left; 25 | list-style-type: none; 26 | margin-right: $spacing; 27 | } 28 | 29 | li:last-child { 30 | margin-right: 0; 31 | } 32 | } 33 | 34 | //- Mixin: Inline List 35 | /// 36 | /// We tend to spend a great deal of time resetting all of the properties for 37 | /// lists. This puts them back to roughly the same state as browser defaults. 38 | /// You can pass it any option that [list-style-type] 39 | /// (http://www.w3schools.com/cssref/pr_list-style-type.asp) would normally 40 | /// take. 41 | /// 42 | /// @param {variable} $style [disc] - Amount of spacing between elements. 43 | /// can be whatever unit you like. 44 | /// 45 | /// @group typography 46 | /// @example 47 | /// ul { 48 | /// @include text-list(); 49 | /// } 50 | /// ul { 51 | /// @include text-list('disc'); 52 | /// } 53 | 54 | @mixin text-list($style: 'disc') { 55 | margin: .32rem .94rem; 56 | padding-left: 1rem; 57 | 58 | li { 59 | list-style-type: unquote($style); 60 | padding: .125rem 0; 61 | } 62 | } 63 | 64 | //- Mixin: Reset List 65 | /// 66 | /// Resets the margins padding, and styles to list. 67 | /// 68 | /// @group typography 69 | /// @example 70 | /// ul { 71 | /// @include reset-list(); 72 | /// } 73 | 74 | @mixin reset-list() { 75 | margin: 0; 76 | padding: 0; 77 | 78 | li { 79 | float: none; 80 | list-style-type: none; 81 | margin: 0; 82 | padding: 0; 83 | } 84 | } 85 | 86 | 87 | //- Mixin: Ellipsis 88 | /// 89 | /// Truncate text to the width of its container... 90 | /// 91 | /// @param {variable} $width [100%] - Width of the container 92 | /// can be whatever unit you like. 93 | /// 94 | /// @group typography 95 | /// @example 96 | /// h3 { 97 | /// @include ellipsis(); 98 | /// } 99 | 100 | @mixin ellipsis($width: 100%) { 101 | white-space: nowrap; 102 | display: inline-block; 103 | max-width: $width; 104 | overflow: hidden; 105 | text-overflow: ellipsis; 106 | word-wrap: normal; 107 | } 108 | 109 | 110 | //- Mixin: Fluid Type 111 | /// 112 | /// Magic calc + vh combo to allow text to be fluid between minimum 113 | /// and maximum breakpoints. 114 | /// 115 | /// @group typography 116 | /// @param {variable} $min-font-size [12px] - Minimum font size 117 | /// @param {variable} $max-font-size [24px] - Maximum font size 118 | /// @param {variable} $lower-range [420px] - Stop scaling font smaller at this screen resolution 119 | /// @param {variable} $upper-range [900px] - Stop scaling font larger at this screen resolution 120 | /// @example 121 | /// h1 { 122 | /// @include fluid-type(20px, 48px); 123 | /// } 124 | /// @link http://codepen.io/dbox/pen/meaMba 125 | 126 | @mixin fluid-type($min-font-size: 12px, $max-font-size: 21px, $lower-range: 420px, $upper-range: 900px) { 127 | font-size: calc(#{$min-font-size} + #{(($max-font-size / ($max-font-size * 0 + 1)) - ($min-font-size / ($min-font-size * 0 + 1)))} * ((100vw - #{$lower-range}) / #{(($upper-range / ($upper-range * 0 + 1)) - ($lower-range / ($lower-range * 0 + 1)))})); 128 | 129 | @media screen and (max-width: $lower-range) { 130 | font-size: $min-font-size; 131 | } 132 | 133 | @media screen and (min-width: $upper-range){ 134 | font-size: $max-font-size; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /knapsack/_animation.scss: -------------------------------------------------------------------------------- 1 | // ------ 2 | // Animations 3 | // ------ 4 | 5 | /// CSS cubic-bezier timing functions ported from Bourbon via jquery.easie (github.com/jaukia/easie) 6 | /// 7 | /// @group animation 8 | /// @type cubic-bezier 9 | /// @link http://jqueryui.com/resources/demos/effect/easing.html 10 | 11 | $ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530); 12 | $ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190); 13 | $ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220); 14 | $ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060); 15 | $ease-in-sine: cubic-bezier(0.470, 0, 0.745, 0.715); 16 | $ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035); 17 | $ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335); 18 | $ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045); 19 | $ease-in-swift: cubic-bezier(0.900, 0, 0.450, 1); 20 | 21 | $ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940); 22 | $ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1); 23 | $ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1); 24 | $ease-out-quint: cubic-bezier(0.230, 1, 0.320, 1); 25 | $ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1); 26 | $ease-out-expo: cubic-bezier(0.190, 1, 0.220, 1); 27 | $ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1); 28 | $ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275); 29 | $ease-out-swift: cubic-bezier(0.550, 0, 0.100, 1); 30 | 31 | $ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955); 32 | $ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1); 33 | $ease-in-out-quart: cubic-bezier(0.770, 0, 0.175, 1); 34 | $ease-in-out-quint: cubic-bezier(0.860, 0, 0.070, 1); 35 | $ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950); 36 | $ease-in-out-expo: cubic-bezier(1, 0, 0, 1); 37 | $ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860); 38 | $ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550); 39 | $ease-in-out-swift: cubic-bezier(0.900, 0, 0.100, 1); 40 | 41 | 42 | //- Mixin: Animated 43 | /// 44 | /// Sets the main animation properties. Optionally, we have a very basic set of custom animtions that can be passed. Note you must call initialize-animation mixin on root of your document to enable the keyframes; 45 | /// 46 | /// @param {variable} $animation-name [null] - Currently available animation names: 'fade-in', 'fade-in-up', 'fade-in-down', 'over-scale' 47 | /// @param {variable} $animation-duration [.65s] - How long animation takes 48 | /// @param {variable} $animation-easing [$ease-out-quad] - Animation easing type 49 | /// @group animation 50 | /// @link http://codepen.io/dbox/pen/ZboVOg 51 | 52 | @mixin animated($animation-name: null, $animation-duration: .65s, $animation-delay: null, $animation-easing: $ease-out-quad) { 53 | animation-duration: $animation-duration; 54 | animation-fill-mode: both; 55 | animation-iteration-count: 1; 56 | animation-timing-function: $animation-easing; 57 | 58 | @if ($animation-name) { 59 | animation-name: $animation-name; 60 | } 61 | @if ($animation-delay) { 62 | animation-delay: $animation-delay; 63 | } 64 | 65 | } 66 | 67 | //- Additive Mixin: Initialize animation 68 | /// 69 | /// Render the keyframes needed for animation mixin. Required to pass animation-names to `animated` mixin. 70 | /// 71 | /// @group animation 72 | /// @example 73 | /// @include initialize-animation(); 74 | /// @link http://codepen.io/dbox/pen/ZboVOg 75 | 76 | @mixin initialize-animation() { 77 | @keyframes fade-in-up { 78 | 0% { opacity: 0; transform: translate3d(0, 15%, 0); } 79 | 100% { opacity: 1; transform: none; } 80 | } 81 | 82 | @keyframes fade-in-down { 83 | 0% { opacity: 0; transform: translate3d(0, -15%, 0); } 84 | 100% { opacity: 1; transform: none; } 85 | } 86 | 87 | @keyframes over-scale { 88 | 0% { opacity: 0; transform: scale(0); } 89 | 70% { transform: scale(1.1); } 90 | 100% { opacity: 1; transform: scale(1); } 91 | } 92 | 93 | @keyframes fade-in { 94 | 0% { opacity: 0; } 95 | 100% { opacity: 1;} 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /knapsack/_utilities.scss: -------------------------------------------------------------------------------- 1 | // ---- 2 | // Utilities 3 | // ---- 4 | 5 | /// Power function 6 | /// @param {Number} $x 7 | /// @param {Number} $n 8 | /// @return {Number} 9 | /// @group utilities 10 | /// @source https://github.com/adambom/Sass-Math/blob/master/math.scss Sass-Math 11 | @function pow($x, $n) { 12 | $result: 1; 13 | 14 | @if $n >= 0 { 15 | @for $i from 1 through $n { 16 | $result: $result * $x; 17 | } 18 | } @else { 19 | @for $i from $n to 0 { 20 | $result: $result / $x; 21 | } 22 | } 23 | @return $result; 24 | } 25 | 26 | /// 27 | /// Calculates and returns the rem value based on px input. Default base font 28 | /// size is 16px, but can be changed with a global `$base-font-size` variable. 29 | /// 30 | /// @param {variable} $size - Size in pixels 31 | /// 32 | /// @group utilities 33 | /// @example 34 | /// font-size: rem(30px); 35 | /// // returns font-size: 1.875rem; 36 | 37 | @function rem($size) { 38 | $rem-size: $size / $base-font-size; 39 | @return #{$rem-size}rem; 40 | } 41 | 42 | //- Function: Strip Unit 43 | /// 44 | /// Sometimes it's just easier to do calculations with the unit is stripped. 45 | /// 46 | /// @param {number} $number - Number that has a unit 47 | /// 48 | /// @group utilities 49 | /// @example 50 | /// $length: 42px; 51 | /// $value: strip-unit($length); 52 | /// // -> 42 53 | /// @link https://css-tricks.com/snippets/sass/strip-unit-function/ 54 | 55 | @function strip-unit($number) { 56 | @if type-of($number) == 'number' and not unitless($number) { 57 | @return $number / ($number * 0 + 1); 58 | } 59 | @return $number; 60 | } 61 | 62 | //- Mixin: Debug 63 | /// 64 | /// Debugging tool - adds a border to the current element, its children, 65 | /// grandchildren, etc so you can see what's up – great for precise layout 66 | /// tweaks. It will also add flags if you made mistakes like put in inline 67 | /// styles, forgot an alt on an image, left the alt blank, etc. Not to be used 68 | /// in production, obviously. 69 | /// 70 | /// @group utilities 71 | /// @example 72 | /// .container-elment { 73 | /// @include debug(); 74 | /// } 75 | /// @link http://codepen.io/dbox/pen/GJZzYo?editors=110 76 | 77 | @mixin debug() {> * { border: 1px solid green;} > * > * {border: 1px solid tomato; } > * > * > * { border: 1px solid DeepSkyBlue; } > * > * > * > * { border: 1px solid DeepPink; } > * > * > * > * > * { border: 1px solid MediumSlateBlue;}} 78 | 79 | // Mixin: Triangle 80 | // 81 | // Makes a little css triangle for you. Pass it a direction (up, down, left, 82 | // right), size (in pixels), and a color. 83 | // 84 | // ex. @include triangle() 85 | // ex. @include triangle('down', 15px, blue) 86 | 87 | //- Mixin: Triangle 88 | /// 89 | /// Makes a little css triangle for you. 90 | /// 91 | /// @param {variable} $direction [up] - Direction of the triangle: up, down left 92 | /// or right 93 | /// @param {variable} $size [10px] - Size of the triangle 94 | /// @param {variable} $color [#000] - Color of the triangle 95 | /// 96 | /// @group utilities 97 | /// @example 98 | /// .element:after { 99 | /// @include triangle(); 100 | /// } 101 | /// span { 102 | /// @include triangle(right, 8px, red); 103 | /// } 104 | 105 | @mixin triangle($direction:'up', $size:10px, $color:#000) { 106 | width: 0; 107 | height: 0; 108 | 109 | @if $direction == 'up' { 110 | border-bottom: $size solid $color; 111 | border-left: $size solid transparent; 112 | border-right: $size solid transparent; 113 | } @else if $direction == 'down' { 114 | border-left: $size solid transparent; 115 | border-right: $size solid transparent; 116 | border-top: $size solid $color; 117 | } @else if $direction == 'left' { 118 | border-bottom: $size solid transparent; 119 | border-right: $size solid $color; 120 | border-top: $size solid transparent; 121 | } @else if $direction == 'right' { 122 | border-bottom: $size solid transparent; 123 | border-left: $size solid $color; 124 | border-top: $size solid transparent; 125 | } 126 | } 127 | 128 | /// Returns the luminance of `$color` as a float (between 0 and 1) 129 | /// 1 is pure white, 0 is pure black 130 | /// @group utilities 131 | /// @param {Color} $color - Color 132 | /// @return {Number} 133 | /// @link http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef Reference 134 | /// @author Hugo Giradel 135 | 136 | @function luminance($color) { 137 | $colors: ( 138 | 'red': red($color), 139 | 'green': green($color), 140 | 'blue': blue($color) 141 | ); 142 | 143 | @each $name, $value in $colors { 144 | $adjusted: 0; 145 | $value: $value / 255; 146 | 147 | @if $value < 0.03928 { 148 | $value: $value / 12.92; 149 | } @else { 150 | $value: ($value + .055) / 1.055; 151 | $value: pow($value, 2); 152 | } 153 | 154 | $colors: map-merge($colors, ($name: $value)); 155 | } 156 | 157 | @return (map-get($colors, 'red') * .2126) + (map-get($colors, 'green') * .7152) + (map-get($colors, 'blue') * .0722); 158 | } 159 | -------------------------------------------------------------------------------- /knapsack/_forms.scss: -------------------------------------------------------------------------------- 1 | 2 | //- Mixin: Select-box 3 | /// 4 | /// Styling select boxes is the worst. Hopefully this makes life a little 5 | /// easier. Automagically colors elements based on luminance of the backbground 6 | /// color. Pass it a custom arrow image, or use a handy css-only triangle by 7 | /// default. Must be called on an element that wraps the select. Works with 8 | /// Safari, Chrome, Firefox, and IE10+. 9 | /// 10 | /// @param {variable} $bg-color [#FFF] - default background-color 11 | /// @param {variable} $border-radius [.2em] - border radius 12 | /// @param {variable} $arrow-image [null] - Custom image for the dropdown 13 | /// @param {variable} $arrow-size [6px] - Size of arrow image (change if image 14 | /// provided) 15 | /// @param {variable} $focus-glow [#B4DEFA] - Sets a glow around the dropdown 16 | /// when focused. Remove with 'null' 17 | /// @param {variable} $text-color [null] - Determined dynamically based on 18 | /// luminance of background color, but can be overwritten. 19 | /// @param {variable} $bg-hover-color [null] - Determined dynamically based on 20 | /// luminance of background color, but can be overwritten. 21 | /// @param {variable} $border-color [null] - Determined dynamically based on 22 | /// luminance of background color, but can be overwritten. 23 | /// @param {variable} $border-hover-color [null] - Determined dynamically based on 24 | /// luminance of background color, but can be overwritten. 25 | /// @group forms 26 | /// @example 27 | /// .select-wrapper { 28 | /// @include select-box(); 29 | /// } 30 | /// 31 | /// .select-wrapper { 32 | /// @include select-box(#efefef, 0px, $arrow-size: 15px, $arrow-image: "http://dbox.us/_img/sample-arrow.png") 33 | /// } 34 | /// @link http://codepen.io/dbox/pen/YyBdog 35 | 36 | @mixin select-box ($bg-color: #FFF, $border-radius: .2em, $arrow-image: null, $arrow-size: 6px, $focus-glow: #B4DEFA, $text-color: null, $bg-hover-color: null, $border-color: null, $border-hover-color: null) { 37 | // Detect if bg color is dark or light, then serve some intelligent defaults based that color 38 | // todo: make more terse 39 | 40 | // tolerance for changing the color 41 | $l-tolerance: .65; 42 | 43 | @if ($text-color) { 44 | $text-color: $text-color; 45 | } @else { 46 | $text-color: if(luminance($bg-color) < $l-tolerance, #FFF, rgba(#000, .7)); 47 | } 48 | @if ($bg-hover-color) { 49 | $bg-hover-color: $bg-hover-color; 50 | } @else { 51 | $bg-hover-color: if(luminance($bg-color) < $l-tolerance, darken($bg-color, 10%), $bg-color); 52 | } 53 | @if ($border-color) { 54 | $border-color: $border-color; 55 | } @else { 56 | $border-color: if(luminance($bg-color) < $l-tolerance, $bg-color, rgba(#000, .25)); 57 | } 58 | @if ($border-hover-color) { 59 | $border-color: $border-hover-color; 60 | } @else { 61 | $border-hover-color: if(luminance($bg-color) < $l-tolerance, $bg-hover-color, rgba(#000, .45)); 62 | } 63 | $arrow-color: if(luminance($bg-color) < $l-tolerance, rgba(255, 255, 255, .9), rgba(#000, .25)); 64 | $arrow-hover-color: if(luminance($bg-color) < $l-tolerance, #FFF, rgba(#000, .45)); 65 | 66 | border: 1px solid $border-color; 67 | border-radius: $border-radius; 68 | display: block; 69 | padding: 0; 70 | position: relative; 71 | background: $bg-color; 72 | color: $text-color; 73 | transition: all .2s ease; 74 | 75 | select { 76 | appearance: none; 77 | background: none; 78 | border: 1px solid transparent; 79 | border-radius: $border-radius; 80 | box-sizing: border-box; 81 | color: inherit; 82 | font-size: 1em; 83 | line-height: 1.3; 84 | margin: 0; 85 | outline: none; 86 | padding: .5em 1.9em .5em .8em; 87 | transition: all .2s ease; 88 | width: 100%; 89 | 90 | &:focus { 91 | background-color: transparent; 92 | border: 1px solid $border-hover-color; 93 | outline: none; 94 | @if ($focus-glow) { 95 | box-shadow: 0 0 3px 3px $focus-glow; 96 | } 97 | } 98 | } 99 | 100 | &:after { 101 | content: ''; 102 | height: $arrow-size; 103 | margin-top: -.25em; 104 | pointer-events: none; 105 | position: absolute; 106 | right: .7em; 107 | top: 50%; 108 | width: $arrow-size; 109 | z-index: 2; 110 | 111 | @if ($arrow-image) { 112 | background-image: url($arrow-image); 113 | background-position: right center; 114 | background-repeat: no-repeat; 115 | background-size: 100% auto; 116 | margin-top: calc(#{$arrow-size} / 1.75 * -1); 117 | } @else { 118 | border-left: $arrow-size solid transparent; 119 | border-right: $arrow-size solid transparent; 120 | border-top: $arrow-size solid $arrow-color; 121 | height: 0; 122 | width: 0; 123 | } 124 | } 125 | 126 | &:hover { 127 | background: $bg-hover-color; 128 | border: 1px solid $border-hover-color; 129 | 130 | &:after { 131 | @if not ($arrow-image) { 132 | border-top: $arrow-size solid $arrow-hover-color; 133 | } 134 | } 135 | } 136 | 137 | option { 138 | font-weight: normal; 139 | } 140 | 141 | // Some browser hacks --------- 142 | 143 | // Firefox 144 | @-moz-document url-prefix() { 145 | overflow: hidden; 146 | 147 | select { 148 | width: 120%; 149 | width: -moz-calc(100% + 3em); 150 | width: calc(100% + 3em); 151 | 152 | &:-moz-focusring { 153 | color: transparent; 154 | text-shadow: 0 0 0 #000; 155 | } 156 | } 157 | } 158 | 159 | // IE10-11 160 | select { 161 | &::-ms-expand { 162 | display: none; 163 | } 164 | 165 | &:focus::-ms-value { 166 | background: transparent; 167 | color: #222; 168 | } 169 | } 170 | // Note: opera support is possible, but needs some hacks outside of mixin: 171 | // http://browserhacks.com/#hack-a3f166304aafed524566bc6814e1d5c7 */ 172 | } 173 | 174 | //- Mixin: Radio 175 | /// 176 | /// A simple reset for radio button styling across browsers. Note must be used 177 | /// on the