├── .gitignore ├── LICENSE.md ├── README.md ├── _neutron.scss ├── bower.json └── modules ├── _floatbox.scss ├── _queries.scss └── _utilities.scss /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .settings 3 | .dropbox 4 | desktop.ini 5 | *.css 6 | *.zip 7 | 8 | 9 | #Node 10 | node_modules 11 | 12 | #Sass 13 | .sass-cache 14 | koala-config.json 15 | *.css.map 16 | 17 | #Editors 18 | .vscode 19 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Christopher Muller 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | Except as contained in this notice, the name(s) of the above copyright holders shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization. 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Neutron 2 | Neutron is a Sass framework that empowers you to create flexible, clear, and semantic website layouts. 3 | 4 | ##Why use Neutron? 5 | Neutron is built from the beginning to be clear, concise, and--primarily--a flexible system for creating website layouts. 6 | 7 | When building it we did away with redundant concepts and ideas that many frameworks still use, such as littering your HTML with classes, or manually declaring each column in the HTML, or being restricted to a specific grid layout. 8 | 9 | ##Installing Neutron 10 | 11 | ###Bower 12 | bower install neutroncss 13 | 14 | ###Git 15 | git clone https://github.com/NeutronCSS/neutroncss.git neutron 16 | 17 | ##Adding Neutron to your project. 18 | Adding Neutron to your project is as simple as downloading the neutron assets and then including the `_neutron.scss` at the top of your Sass stylesheet. 19 | 20 | @import "neutron/neutron"; 21 | 22 | ##Learn more about Neutron 23 | You can learn more about Neutron by visiting the website neutroncss.com. If you're looking for information on how to use Neutron you can check our documentation at neutroncss.com/docs 24 | 25 | ##Roadmap 26 | Once we reach version `1.0` we won't be making any breaking changes to Neutron until version `2.0` comes along. 27 | 28 | We do plan on adding a number of features to Neutron in the near-term however, these include: 29 | 30 | * Fixed width columns: the ability to set some or all of your columns to have a fixed width instead of a percentage-based width. 31 | * Flexbox support: We hope to inplement flexbox support allowing you to create layouts using the same or similar syntax as the rest of Neutron. 32 | 33 | ##Contact Us 34 | You can get in touch with us on Twitter (@NeutronCSS). If you find a bug or have a feature request, you can create an issue here on GitHub. 35 | 36 | If you're having trouble using Neutron you can send us a message on Twitter or submit a question to Stackoverflow. 37 | -------------------------------------------------------------------------------- /_neutron.scss: -------------------------------------------------------------------------------- 1 | /*--------------------------------- 2 | NeutronCSS 3 | ---------------------------------*/ 4 | 5 | // Settings Management 6 | // ============================================ 7 | 8 | $_neutron: ( 9 | layout: ( 10 | column-padding: 4px 8px, 11 | container-max-width: 960px, 12 | flush-margin: true, 13 | flush-padding: false 14 | ), 15 | query: ( 16 | mobile-max: 479px, 17 | phablet-max: 767px, 18 | tablet-max: 1023px, 19 | desktop-sml-max: 1199px, 20 | desktop-mid-max: 1799px 21 | ) 22 | ) !default; 23 | 24 | @function setting($map_name: "", $setting: "") { 25 | @if $map_name != "" and $setting != "" { 26 | $map: map-get($_neutron,$map_name); 27 | @return map-get($map, $setting); 28 | } 29 | } 30 | 31 | // Modules 32 | // ============================================ 33 | @import "modules/floatbox"; 34 | @import "modules/queries"; 35 | @import "modules/utilities"; 36 | 37 | // Default Styles 38 | // ============================================ 39 | // Set root element to use border-box 40 | // sizing and set all elements on the page 41 | // to inherit border-box sizing. 42 | 43 | html { 44 | -moz-box-sizing: border-box; 45 | box-sizing: border-box; 46 | } 47 | 48 | html * { 49 | -moz-box-sizing: inherit; 50 | box-sizing: inherit; 51 | } 52 | 53 | body { 54 | max-width: setting("layout", "container-max-width"); 55 | margin-left: auto; 56 | margin-right: auto; 57 | } 58 | 59 | // Helper Functions 60 | // ============================================ 61 | 62 | //Adds all items in a list and returns the result 63 | @function neutron_sum($list) { 64 | 65 | $total: 0; 66 | @each $element in $list { 67 | $total: $total + $element; 68 | } 69 | @return $total; 70 | 71 | } 72 | 73 | @function neutron_extract-position($shorthand, $position) { 74 | $shorthand-length: length($shorthand); 75 | 76 | //if only one variable passed, return it 77 | @if $shorthand-length == 1 { 78 | @return $shorthand; 79 | } 80 | 81 | @if $shorthand-length == 2 { 82 | @if $position == top or $position == bottom { 83 | @return nth($shorthand, 1); 84 | } 85 | 86 | @if $position == left or $position == right { 87 | @return nth($shorthand, 2); 88 | } 89 | } 90 | 91 | @if $shorthand-length == 3 { 92 | @if $position == top { 93 | @return nth($shorthand, 1); 94 | } 95 | 96 | @if $position == left or $position == right { 97 | @return nth($shorthand, 2); 98 | } 99 | 100 | @if $position == bottom { 101 | @return nth($shorthand, 3); 102 | } 103 | } 104 | 105 | @if $shorthand-length == 4 { 106 | @if $position == top { 107 | @return nth($shorthand, 1); 108 | } 109 | 110 | @if $position == right { 111 | @return nth($shorthand, 2); 112 | } 113 | 114 | @if $position == bottom { 115 | @return nth($shorthand, 3); 116 | } 117 | 118 | @if $position == left { 119 | @return nth($shorthand, 4); 120 | } 121 | } 122 | } 123 | 124 | 125 | /*--------- End of NeutronCSS ---------*/ 126 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "neutroncss", 3 | "homepage": "http://neutroncss.com", 4 | "version": "0.9.2", 5 | "authors": [ 6 | "Christopher Muller" 7 | ], 8 | "description": "A Sass framework that empowers you to create flexible, clear, and semantic website layouts.", 9 | "main": "_neutron.scss", 10 | "keywords": [ 11 | "Sass", 12 | "CSS", 13 | "Neutron", 14 | "Framework", 15 | "Semantic" 16 | ], 17 | "license": "MIT", 18 | "ignore": [ 19 | "**/.*", 20 | "node_modules", 21 | "bower_components", 22 | "test", 23 | "tests" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /modules/_floatbox.scss: -------------------------------------------------------------------------------- 1 | // Floatbox Grid 2 | //--------------------------------------------- 3 | 4 | //Declares the container element of child rows or columns 5 | @mixin columns( 6 | $columns:"", 7 | $container-width: setting("layout","container-max-width"), 8 | $container-align: "", 9 | $margin: "", 10 | $flush-margin: setting("layout","flush-margin"), 11 | $flush-padding: setting("layout","flush-padding"), 12 | $target: "*", 13 | $order: "" 14 | ) { 15 | @include container-width($container-width); 16 | margin-left: auto; 17 | margin-right: auto; 18 | @include clear-fix(); 19 | 20 | @if $columns != "" { 21 | 22 | $columns: neutron_calc-column-ratio($columns); 23 | $column-sum: neutron_sum($columns); 24 | $column-count: length($columns); 25 | $column-widths: neutron_calculate-column-widths($columns); 26 | $target-child-selector: neutron_child-selector($target); 27 | 28 | $margin-left: 0; 29 | $margin-right: 0; 30 | 31 | @if $margin != "" { 32 | 33 | //get margins for left and right of the columns 34 | $margin-left: neutron_extract-position($margin,left); 35 | $margin-right: neutron_extract-position($margin,right); 36 | 37 | } 38 | 39 | //assign calculated widths to elements 40 | $index: 0; 41 | @each $width in $column-widths { 42 | $index: $index + 1; 43 | 44 | & > #{$target}:#{$target-child-selector}(#{$column-count}n+#{$index}) { 45 | 46 | $calc-contents: "#{$width}"; 47 | 48 | @if $margin != "" { 49 | 50 | @if $margin-left != 0 { 51 | $calc-contents: $calc-contents + " - #{$margin-left}"; 52 | } 53 | 54 | @if $margin-right != 0 { 55 | $calc-contents: $calc-contents + " - #{$margin-right}"; 56 | } 57 | 58 | @if $flush-margin and $margin != "" { 59 | $flush-left: $margin-left / $column-count; 60 | $flush-right: $margin-right / $column-count; 61 | $calc-contents: $calc-contents + " + #{$flush-left}"; 62 | $calc-contents: $calc-contents + " + #{$flush-right}"; 63 | } 64 | 65 | } 66 | 67 | width: calc(#{$calc-contents}); 68 | float:left; 69 | 70 | @content; 71 | 72 | @if $margin != "" { 73 | margin: $margin; 74 | } 75 | 76 | //if first column 77 | @if $index == 1 { 78 | clear: left; 79 | 80 | @if $flush-padding { 81 | padding-left: 0; 82 | } 83 | @if $flush-margin { 84 | margin-left: 0; 85 | } 86 | } @else { 87 | clear: none; 88 | } 89 | 90 | //if last column 91 | @if $index == $column-count { 92 | @if $flush-padding { 93 | padding-right: 0; 94 | } 95 | @if $flush-margin { 96 | margin-right: 0; 97 | } 98 | } 99 | } 100 | } 101 | } 102 | 103 | //Set alignment of container 104 | @if $container-align != "" { 105 | @include container-align($container-align); 106 | } 107 | 108 | // Change order of columns 109 | @if type-of($order) == list and type-of($columns) == list { 110 | @include order($order, $columns, $margin, $flush-margin, $target); 111 | } 112 | 113 | } 114 | 115 | //Alias for columns() 116 | @mixin column($arguments...) { 117 | @include columns($arguments...) { 118 | @content; 119 | }; 120 | } 121 | 122 | @mixin col($arguments...) { 123 | @include columns($arguments...) { 124 | @content; 125 | }; 126 | } 127 | 128 | @mixin float-columns($arguments...) { 129 | @include columns($arguments...) { 130 | @content; 131 | }; 132 | } 133 | 134 | @mixin float-column($arguments...) { 135 | @include columns($arguments...) { 136 | @content; 137 | }; 138 | } 139 | 140 | @mixin float-col($arguments...) { 141 | @include columns($arguments...) { 142 | @content; 143 | }; 144 | } 145 | 146 | @mixin order($order: "", $columns:"", $margin:"", $flush-margin:setting("layout","flush-margin"), $target:"*") { 147 | 148 | @if type-of($order) == list { 149 | 150 | //if no ratio is set, use $order to determine number of equal width columns 151 | @if $columns == "" { 152 | $columns: length($order); 153 | } 154 | 155 | //if column ratio is not a list, generate it 156 | $columns: neutron_calc-column-ratio($columns); 157 | $column-sum: neutron_sum($columns); 158 | $column-count: length($columns); 159 | $target-child-selector: neutron_child-selector($target); 160 | 161 | $margin-left: 0; 162 | $margin-right: 0; 163 | 164 | @if $margin != "" { 165 | $margin-left: neutron_extract-position($margin,left); 166 | $margin-right: neutron_extract-position($margin,right); 167 | } 168 | 169 | //calculate width of each column 170 | $column-width-string:(); 171 | 172 | $i: 0; 173 | $columns-offset: (); 174 | @each $column in $columns { 175 | $i: $i + 1; 176 | 177 | // calculate column widths 178 | $col-width: (100% / $column-sum) * $column; 179 | 180 | @if $margin != "" { 181 | @if $flush-margin { 182 | $flush-left: $margin-left / $column-count; 183 | $flush-right: $margin-right / $column-count; 184 | $flush: $flush-left + $flush-right; 185 | $col-width: $col-width + " + #{$flush}"; 186 | } 187 | } 188 | 189 | $column-width-string: append($column-width-string, "(#{$col-width})", comma); 190 | 191 | // get sum of left offset of columns that come before current original position 192 | $current-index: 0; 193 | $current-offset: "0px"; 194 | 195 | @while $current-index < $i { 196 | $current-index: $current-index + 1; 197 | 198 | $add-offset: nth($column-width-string, $current-index); 199 | $current-offset: $current-offset + " + " + $add-offset; 200 | } 201 | 202 | $current-offset: "(" + $current-offset + ")"; 203 | $columns-offset: append($columns-offset, $current-offset, comma) 204 | 205 | } 206 | 207 | $new-column-width-string: neutron_reorder-list($column-width-string, $order); 208 | $offset-totals: (); 209 | 210 | //iterate over each column 211 | $i: 0; 212 | @each $column in $order { 213 | $i: $i + 1; 214 | 215 | // get sum of widths of columns that come before current one and add to offset 216 | $new-position: index($order, $column); 217 | $new-offset: "0px"; 218 | 219 | $index: 0; 220 | @while $index < $new-position { 221 | $index: $index + 1; 222 | 223 | $new-offset: $new-offset + " + " + nth($new-column-width-string, $index); 224 | } 225 | 226 | //Get left offset required for this column to reset column to left side. 227 | $ori-offset: nth($columns-offset, $column); 228 | 229 | & > #{$target}:#{$target-child-selector}(#{$column-count}n+#{$column}) { 230 | left: calc(0px - (#{$ori-offset}) + (#{$new-offset})); 231 | position: relative; 232 | } 233 | } 234 | } 235 | } 236 | 237 | @mixin container-align($align:"") { 238 | //Set alignment 239 | @if $align != "" { 240 | float:none; 241 | 242 | @if $align == left { 243 | margin-left: 0; 244 | } 245 | 246 | @if $align == right { 247 | margin-right: 0; 248 | } 249 | 250 | @if $align == center { 251 | margin-right: auto; 252 | margin-left: auto; 253 | } 254 | } 255 | } 256 | 257 | @mixin container-width($container-width: setting("layout","container-max-width")) { 258 | max-width: $container-width; 259 | } 260 | 261 | // UTILITY FUNCTIONS 262 | @function neutron_reorder-list($list, $order) { 263 | 264 | $new-list:(); 265 | 266 | @each $index in $order { 267 | $item: nth($list, $index); 268 | $new-list: append($new-list, $item, comma); 269 | } 270 | 271 | @return $new-list; 272 | } 273 | 274 | @function neutron_calculate-column-widths($column-ratio) { 275 | 276 | $column-sum: neutron_sum($column-ratio); 277 | $column-count: length($column-ratio); 278 | $column-widths: (); 279 | 280 | //Determine width of each column 281 | @each $column in $column-ratio { 282 | $width: (100% / $column-sum) * $column; 283 | $column-widths: append($column-widths, $width, comma); 284 | } 285 | 286 | @return $column-widths; 287 | } 288 | 289 | @function neutron_calc-column-ratio($columns) { 290 | $column-ratio: $columns; 291 | 292 | @if type-of($columns) != list { 293 | $column-ratio: (); 294 | 295 | @for $i from 1 through $columns { 296 | $column-ratio: append($column-ratio, 1, comma); 297 | } 298 | } 299 | 300 | @return $column-ratio; 301 | } 302 | 303 | @function neutron_child-selector($target-selector) { 304 | $child-selector: "nth-of-type"; 305 | 306 | @if $target-selector == "*" { 307 | $child-selector: "nth-child"; 308 | } 309 | 310 | @return $child-selector; 311 | } 312 | -------------------------------------------------------------------------------- /modules/_queries.scss: -------------------------------------------------------------------------------- 1 | /// Media Queries 2 | //=============================================== 3 | 4 | 5 | // Viewport Settings 6 | //--------------------------------------------- 7 | 8 | $mobile-max: setting("query", "mobile-max"); 9 | $phablet-max: setting("query", "phablet-max"); 10 | $tablet-max: setting("query", "tablet-max"); 11 | $desktop-sml-max: setting("query", "desktop-sml-max"); 12 | $desktop-mid-max: setting("query", "desktop-mid-max"); 13 | 14 | $phablet-min: $mobile-max + 1; 15 | $tablet-min: $phablet-max + 1; 16 | $desktop-sml-min: $tablet-max + 1; 17 | $desktop-mid-min: $desktop-sml-max + 1; 18 | $desktop-lrg-min: $desktop-mid-max + 1; 19 | 20 | @function createBreakpoint($fromThisSize: "", $uptoThisSize: ""){ 21 | $query: ""; 22 | 23 | @if $fromThisSize != "" or $uptoThisSize != "" { 24 | 25 | @if $fromThisSize != "" and $fromThisSize != 0 { 26 | $query: $query + "(min-width:#{$fromThisSize})"; 27 | } 28 | 29 | @if ($fromThisSize != "" and $fromThisSize != 0) and $uptoThisSize != "" { 30 | $query: $query + " and "; 31 | } 32 | 33 | @if $uptoThisSize != "" { 34 | $query: $query + "(max-width:#{$uptoThisSize})"; 35 | } 36 | 37 | @return unquote($query); 38 | } 39 | } 40 | 41 | // Media Queries 42 | //--------------------------------------------- 43 | 44 | // Map of set breakpoints 45 | $neutron_breakpoints: ( 46 | mobile: createBreakpoint(0, $mobile-max), 47 | phablet: createBreakpoint($phablet-min, $phablet-max), 48 | tablet: createBreakpoint($tablet-min, $tablet-max), 49 | desktop: createBreakpoint($desktop-sml-min), 50 | desktop-sml: createBreakpoint($desktop-sml-min, $desktop-sml-max), 51 | desktop-mid: createBreakpoint($desktop-mid-min, $desktop-mid-max), 52 | desktop-lrg: createBreakpoint($desktop-lrg-min), 53 | 54 | to-phablet: createBreakpoint(0, $phablet-max), 55 | to-tablet: createBreakpoint(0, $tablet-max), 56 | to-desktop-sml: createBreakpoint(0, $desktop-sml-max), 57 | to-desktop-mid: createBreakpoint(0, $desktop-mid-max), 58 | 59 | from-phablet: createBreakpoint($phablet-min), 60 | from-tablet: createBreakpoint($tablet-min), 61 | from-desktop: createBreakpoint($desktop-sml-min), 62 | from-desktop-sml: createBreakpoint($desktop-sml-min), 63 | from-desktop-mid: createBreakpoint($desktop-mid-min), 64 | from-desktop-lrg: createBreakpoint($desktop-lrg-min) 65 | ); 66 | 67 | @mixin breakpoint($breakpoint: "", $resolution: "", $media-type: "", $media-feature: "") { 68 | @if $breakpoint != "" or $resolution != "" or $media-feature != "" or $media-type { 69 | 70 | $media: ""; 71 | 72 | // Add breakpoint to media string 73 | @if $breakpoint != "" { 74 | @if map-has-key($neutron_breakpoints, $breakpoint) { 75 | $media: inspect(map-get($neutron_breakpoints, $breakpoint)); 76 | } 77 | } 78 | 79 | // Add dpi to media string 80 | @if $resolution != "" { 81 | $res-dpi: $resolution * 96; 82 | 83 | @if $media != "" { 84 | $media: $media + " and"; 85 | } 86 | 87 | $media: $media + " all and (min-resolution: #{$res-dpi}dpi) "; 88 | } 89 | 90 | // Add additional supplied query types to media string 91 | @if $media-type != "" { 92 | @if $media != "" { 93 | $media: $media + " and "; 94 | } 95 | 96 | $media: $media + $media-type; 97 | } 98 | 99 | // Add additional supplied query features to media string 100 | @if $media-feature != "" { 101 | @if $media != "" { 102 | $media: $media + " and "; 103 | } 104 | 105 | $media: $media + "all and (" + $media-feature + ")"; 106 | } 107 | 108 | @media #{$media} { 109 | @content; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /modules/_utilities.scss: -------------------------------------------------------------------------------- 1 | // Utilities 2 | //--------------------------------------------- 3 | 4 | //hides the element when the 5 | //provided media query is supplied. 6 | @mixin hide($breakpoint: null) { 7 | @if $breakpoint { 8 | @include breakpoint($breakpoint) { 9 | & { 10 | display: none; 11 | } 12 | } 13 | } @else { 14 | display: none; 15 | } 16 | } 17 | 18 | //shows the element when the 19 | //provided media query is supplied. 20 | @mixin show($breakpoint: null) { 21 | @if $breakpoint { 22 | @include breakpoint($breakpoint) { 23 | & { 24 | display: block; 25 | display: initial; 26 | } 27 | } 28 | } @else { 29 | display: block; 30 | display: initial; 31 | } 32 | 33 | } 34 | 35 | //Adds block element self clearing 36 | @mixin clear-fix() { 37 | 38 | &:after { 39 | content: ""; 40 | display: table; 41 | clear: both; 42 | } 43 | 44 | } 45 | --------------------------------------------------------------------------------