mostly filebased Content Presentation System
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

442 lines
11KB

  1. /// Grid Math Engine
  2. /// ================
  3. /// The `su` functions give you direct access to the math layer,
  4. /// without any syntax-sugar like shorthand parsing, and normalization.
  5. /// If you prefer named arguments, and stripped-down syntax,
  6. /// you can use these functions directly in your code –
  7. /// replacing `span`, `gutter`, and `slice`.
  8. ///
  9. /// These functions are also useful
  10. /// for building mixins or other extensions to Susy.
  11. /// Apply the Susy syntax to new mixins and functions,
  12. /// using our "Plugin Helpers",
  13. /// or write your own syntax and pass the normalized results along
  14. /// to `su` for compilation.
  15. ///
  16. /// @group su-math
  17. ///
  18. /// @see su-span
  19. /// @see su-gutter
  20. /// @see su-slice
  21. /// @ignore _su-sum
  22. /// @ignore _su-calc-span
  23. /// @ignore _su-calc-sum
  24. /// @ignore _su-needs-calc-output
  25. // Su Span
  26. // -------
  27. /// Calculates and returns a CSS-ready span width,
  28. /// based on normalized span and context data –
  29. /// a low-level version of `susy-span`,
  30. /// with all of the logic and none of the syntax sugar.
  31. ///
  32. /// - Grids defined with unitless numbers will return `%` values.
  33. /// - Grids defined with comparable units
  34. /// will return a value in the units provided.
  35. /// - Grids defined with a mix of units,
  36. /// or a combination of untiless numbers and unit-lengths,
  37. /// will return a `calc()` string.
  38. ///
  39. /// @group su-math
  40. /// @see susy-span
  41. ///
  42. /// @param {number | list} $span -
  43. /// Number or list of grid columns to span
  44. /// @param {list} $columns -
  45. /// List of columns available
  46. /// @param {number} $gutters -
  47. /// Width of a gutter in column-comparable units
  48. /// @param {0 | 1 | -1} $spread -
  49. /// Number of gutters spanned,
  50. /// relative to `span` count
  51. /// @param {0 | 1 | -1} $container-spread [$spread] -
  52. /// Number of gutters spanned,
  53. /// relative to `columns` count
  54. /// @param {integer} $location [1] -
  55. /// Optional position of sub-span among full set of columns
  56. ///
  57. /// @return {length} -
  58. /// Relative or static length of a span on the grid
  59. @function su-span(
  60. $span,
  61. $columns,
  62. $gutters,
  63. $spread,
  64. $container-spread: $spread,
  65. $location: 1
  66. ) {
  67. $span: su-valid-span($span);
  68. $columns: su-valid-columns($columns);
  69. $gutters: su-valid-gutters($gutters);
  70. $spread: su-valid-spread($spread);
  71. @if (type-of($span) == 'number') {
  72. @if (not unitless($span)) {
  73. @return $span;
  74. }
  75. $location: su-valid-location($span, $location, $columns);
  76. $span: su-slice($span, $columns, $location, $validate: false);
  77. }
  78. @if _su-needs-calc-output($span, $columns, $gutters, $spread, not 'validate') {
  79. @return _su-calc-span($span, $columns, $gutters, $spread, $container-spread, not 'validate');
  80. }
  81. $span-width: _su-sum($span, $gutters, $spread, $validate: false);
  82. @if unitless($span-width) {
  83. $container-spread: su-valid-spread($container-spread);
  84. $container: _su-sum($columns, $gutters, $container-spread, $validate: false);
  85. @return percentage($span-width / $container);
  86. }
  87. @return $span-width;
  88. }
  89. // Su Gutter
  90. // ---------
  91. /// Calculates and returns a CSS-ready gutter width,
  92. /// based on normalized grid data –
  93. /// a low-level version of `susy-gutter`,
  94. /// with all of the logic and none of the syntax sugar.
  95. ///
  96. /// - Grids defined with unitless numbers will return `%` values.
  97. /// - Grids defined with comparable units
  98. /// will return a value in the units provided.
  99. /// - Grids defined with a mix of units,
  100. /// or a combination of untiless numbers and unit-lengths,
  101. /// will return a `calc()` string.
  102. ///
  103. /// @group su-math
  104. /// @see susy-gutter
  105. ///
  106. /// @param {list} $columns -
  107. /// List of columns in the grid
  108. /// @param {number} $gutters -
  109. /// Width of a gutter in column-comparable units
  110. /// @param {0 | 1 | -1} $container-spread -
  111. /// Number of gutters spanned,
  112. /// relative to `columns` count
  113. ///
  114. /// @return {length} -
  115. /// Relative or static length of one gutter in a grid
  116. @function su-gutter(
  117. $columns,
  118. $gutters,
  119. $container-spread
  120. ) {
  121. @if (type-of($gutters) == 'number') {
  122. @if ($gutters == 0) or (not unitless($gutters)) {
  123. @return $gutters;
  124. }
  125. }
  126. @if _su-needs-calc-output($gutters, $columns, $gutters, -1, not 'validate') {
  127. @return _su-calc-span($gutters, $columns, $gutters, -1, $container-spread, not 'validate');
  128. }
  129. $container: _su-sum($columns, $gutters, $container-spread);
  130. @return percentage($gutters / $container);
  131. }
  132. // Su Slice
  133. // --------
  134. /// Returns a list of columns
  135. /// based on a given span/location slice of the grid –
  136. /// a low-level version of `susy-slice`,
  137. /// with all of the logic and none of the syntax sugar.
  138. ///
  139. /// @group su-math
  140. /// @see susy-slice
  141. ///
  142. /// @param {number} $span -
  143. /// Number of grid columns to span
  144. /// @param {list} $columns -
  145. /// List of columns in the grid
  146. /// @param {number} $location [1] -
  147. /// Starting index of a span in the list of columns
  148. /// @param {bool} $validate [true] -
  149. /// Check that arguments are valid before proceeding
  150. ///
  151. /// @return {list} -
  152. /// Subset list of grid columns, based on span and location
  153. @function su-slice(
  154. $span,
  155. $columns,
  156. $location: 1,
  157. $validate: true
  158. ) {
  159. @if $validate {
  160. $columns: su-valid-columns($columns);
  161. $location: su-valid-location($span, $location, $columns);
  162. }
  163. $floor: floor($span);
  164. $sub-columns: ();
  165. @for $i from $location to ($location + $floor) {
  166. $sub-columns: append($sub-columns, nth($columns, $i));
  167. }
  168. @if $floor != $span {
  169. $remainder: $span - $floor;
  170. $column: $location + $floor;
  171. $sub-columns: append($sub-columns, nth($columns, $column) * $remainder);
  172. }
  173. @return $sub-columns;
  174. }
  175. // Su Sum
  176. // ------
  177. /// Get the total sum of column-units in a layout.
  178. ///
  179. /// @group su-math
  180. /// @access private
  181. ///
  182. /// @param {list} $columns -
  183. /// List of columns in the grid
  184. /// @param {number} $gutters -
  185. /// Width of a gutter in column-comparable units
  186. /// @param {0 | 1 | -1} $spread -
  187. /// Number of gutters spanned,
  188. /// relative to `columns` count
  189. /// @param {bool} $validate [true] -
  190. /// Check that arguments are valid before proceeding
  191. ///
  192. /// @return {number} -
  193. /// Total sum of column-units in a grid
  194. @function _su-sum(
  195. $columns,
  196. $gutters,
  197. $spread,
  198. $validate: true
  199. ) {
  200. @if $validate {
  201. $columns: su-valid-span($columns);
  202. $gutters: su-valid-gutters($gutters);
  203. $spread: su-valid-spread($spread);
  204. }
  205. // Calculate column-sum
  206. $column-sum: 0;
  207. @each $column in $columns {
  208. $column-sum: $column-sum + $column;
  209. }
  210. $gutter-sum: (ceil(length($columns)) + $spread) * $gutters;
  211. $total: if(($gutter-sum > 0), $column-sum + $gutter-sum, $column-sum);
  212. @return $total;
  213. }
  214. // Su Calc
  215. // -------
  216. /// Return a usable span width as a `calc()` function,
  217. /// in order to create mixed-unit grids.
  218. ///
  219. /// @group su-math
  220. /// @access private
  221. ///
  222. /// @param {number | list} $span -
  223. /// Pre-sliced list of grid columns to span
  224. /// @param {list} $columns -
  225. /// List of columns available
  226. /// @param {number} $gutters -
  227. /// Width of a gutter in column-comparable units
  228. /// @param {0 | 1 | -1} $spread -
  229. /// Number of gutters spanned,
  230. /// relative to `span` count
  231. /// @param {0 | 1 | -1} $container-spread [$spread] -
  232. /// Number of gutters spanned,
  233. /// relative to `columns` count
  234. /// @param {bool} $validate [true] -
  235. /// Check that arguments are valid before proceeding
  236. ///
  237. /// @return {length} -
  238. /// Relative or static length of a span on the grid
  239. @function _su-calc-span(
  240. $span,
  241. $columns,
  242. $gutters,
  243. $spread,
  244. $container-spread: $spread,
  245. $validate: true
  246. ) {
  247. @if $validate {
  248. $span: su-valid-span($span);
  249. $columns: su-valid-columns($columns);
  250. $gutters: su-valid-gutters($gutters);
  251. $spread: su-valid-spread($spread);
  252. $container-spread: su-valid-spread($container-spread);
  253. }
  254. // Span and context
  255. $span: _su-calc-sum($span, $gutters, $spread, not 'validate');
  256. $context: _su-calc-sum($columns, $gutters, $container-spread, not 'validate');
  257. // Fixed and fluid
  258. $fixed-span: map-get($span, 'fixed');
  259. $fluid-span: map-get($span, 'fluid');
  260. $fixed-context: map-get($context, 'fixed');
  261. $fluid-context: map-get($context, 'fluid');
  262. $calc: '#{$fixed-span}';
  263. $fluid-calc: '(100% - #{$fixed-context})';
  264. // Fluid-values
  265. @if (not $fluid-span) {
  266. $fluid-calc: null;
  267. } @else if ($fluid-span != $fluid-context) {
  268. $fluid-span: '* #{$fluid-span}';
  269. $fluid-context: if($fluid-context, '/ #{$fluid-context}', '');
  270. $fluid-calc: '(#{$fluid-calc $fluid-context $fluid-span})';
  271. }
  272. @if $fluid-calc {
  273. $calc: if(($calc != ''), '#{$calc} + ', '');
  274. $calc: '#{$calc + $fluid-calc}';
  275. }
  276. @return calc(#{unquote($calc)});
  277. }
  278. // Su Calc-Sum
  279. // -----------
  280. /// Get the total sum of fixed and fluid column-units
  281. /// for creating a mixed-unit layout with `calc()` values.
  282. ///
  283. /// @group su-math
  284. /// @access private
  285. ///
  286. /// @param {list} $columns -
  287. /// List of columns available
  288. /// @param {number} $gutters -
  289. /// Width of a gutter in column-comparable units
  290. /// @param {0 | 1 | -1} $spread -
  291. /// Number of gutters spanned,
  292. /// relative to `span` count
  293. /// @param {bool} $validate [true] -
  294. /// Check that arguments are valid before proceeding
  295. ///
  296. /// @return {map} -
  297. /// Map with `fixed` and `fluid` keys
  298. /// containing the proper math as strings
  299. @function _su-calc-sum(
  300. $columns,
  301. $gutters,
  302. $spread,
  303. $validate: true
  304. ) {
  305. @if $validate {
  306. $columns: su-valid-span($columns);
  307. $gutters: su-valid-gutters($gutters);
  308. $spread: su-valid-spread($spread);
  309. }
  310. $fluid: 0;
  311. $fixed: ();
  312. $calc: null;
  313. // Gutters
  314. $gutters: $gutters * (length($columns) + $spread);
  315. // Columns
  316. @each $col in append($columns, $gutters) {
  317. @if unitless($col) {
  318. $fluid: $fluid + $col;
  319. } @else {
  320. $fixed: _su-map-add-units($fixed, $col);
  321. }
  322. }
  323. // Compile Fixed Units
  324. @each $unit, $total in $fixed {
  325. @if ($total != (0 * $total)) {
  326. $calc: if($calc, '#{$calc} + #{$total}', '#{$total}');
  327. }
  328. }
  329. // Calc null or string
  330. @if $calc {
  331. $calc: if(str-index($calc, '+'), '(#{$calc})', '#{$calc}');
  332. }
  333. // Fluid 0 => null
  334. $fluid: if(($fluid == 0), null, $fluid);
  335. // Return map
  336. $return: (
  337. 'fixed': $calc,
  338. 'fluid': $fluid,
  339. );
  340. @return $return;
  341. }
  342. // Needs Calc
  343. // ----------
  344. /// Check if `calc()` will be needed in defining a span,
  345. /// if the necessary units in a grid are not comparable.
  346. ///
  347. /// @group su-math
  348. /// @access private
  349. ///
  350. /// @param {list} $span -
  351. /// Slice of columns to span
  352. /// @param {list} $columns -
  353. /// List of available columns in the grid
  354. /// @param {number} $gutters -
  355. /// Width of a gutter
  356. /// @param {0 | 1 | -1} $spread -
  357. /// Number of gutters spanned,
  358. /// relative to `span` count
  359. /// @param {bool} $validate [true] -
  360. /// Check that arguments are valid before proceeding
  361. ///
  362. /// @return {bool} -
  363. /// `True` when units do not match, and `calc()` will be required
  364. @function _su-needs-calc-output(
  365. $span,
  366. $columns,
  367. $gutters,
  368. $spread,
  369. $validate: true
  370. ) {
  371. @if $validate {
  372. $span: su-valid-span($span);
  373. $columns: su-valid-columns($columns);
  374. $gutters: su-valid-gutters($gutters);
  375. }
  376. $has-gutter: if((length($span) > 1) or ($spread >= 0), true, false);
  377. $check: if($has-gutter, append($span, $gutters), $span);
  378. $safe-span: _su-is-comparable($check...);
  379. @if ($safe-span == 'static') {
  380. @return false;
  381. } @else if (not $safe-span) {
  382. @return true;
  383. }
  384. $safe-fluid: _su-is-comparable($gutters, $columns...);
  385. @return not $safe-fluid;
  386. }