Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/rfs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartijn Cuppens <martijn.cuppens@intracto.com>2018-01-28 01:35:36 +0300
committerMartijn Cuppens <martijn.cuppens@intracto.com>2018-01-28 01:35:36 +0300
commite30b0c141616b6df875da282c1fc056c42ff58a6 (patch)
treedb435b7b039eb82861272dcba5b89a1732603037
parent35e0b66d496864a9a3dcdf502a97b812cd557a0d (diff)
combine all languages
-rw-r--r--examples/postcss/gulp/dest/main.css73
-rw-r--r--examples/postcss/gulp/gulpfile.js20
-rw-r--r--examples/postcss/gulp/src/main.css38
-rw-r--r--examples/postcss/node/index.js24
-rw-r--r--examples/postcss/node/main.css38
-rw-r--r--examples/postcss/node/main.dest.css73
-rw-r--r--less/rfs.less204
-rw-r--r--package.json22
-rw-r--r--postcss/rfs.js175
-rw-r--r--stylus/_rfs.styl151
10 files changed, 814 insertions, 4 deletions
diff --git a/examples/postcss/gulp/dest/main.css b/examples/postcss/gulp/dest/main.css
new file mode 100644
index 0000000..121ce9a
--- /dev/null
+++ b/examples/postcss/gulp/dest/main.css
@@ -0,0 +1,73 @@
+/* responsive-font-size property with `px` unit */
+.selector-1,
+.disable-responsive-font-size .selector-1,
+.disable-responsive-font-size.selector-1 {
+ background-color: red;
+ width: 300px;
+ font-size: 2rem;
+}
+@media (max-width: 1200px) {
+ .selector-1 {
+ font-size: calc(1.2rem + 1.066667vw);
+ }
+}
+
+/* responsive-font-size property with `rem` unit */
+.selector-2,
+.disable-responsive-font-size .selector-2,
+.disable-responsive-font-size.selector-2 {
+ font-size: 2rem;
+}
+@media (max-width: 1200px) {
+ .selector-2 {
+ font-size: calc(1.2rem + 1.066667vw);
+ }
+}
+
+/* responsive-font-size property with !important */
+.selector-3,
+.disable-responsive-font-size .selector-3,
+.disable-responsive-font-size.selector-3 {
+ font-size: 2rem !important;
+}
+@media (max-width: 1200px) {
+ .selector-3 {
+ font-size: calc(1.2rem + 1.066667vw) !important;
+ }
+}
+
+/* rfs shorthand */
+.selector-4,
+.disable-responsive-font-size .selector-4,
+.disable-responsive-font-size.selector-4 {
+ font-size: 2rem;
+}
+@media (max-width: 1200px) {
+ .selector-4 {
+ font-size: calc(1.2rem + 1.066667vw);
+ }
+}
+
+/* not supported unit */
+.selector-5 {
+ font-size: 2em;
+}
+
+/* special value */
+.selector-6 {
+ font-size: inherit;
+}
+
+/* responsive-font-size property inside @support-query */
+@supports (display: flex) {
+ .selector-7,
+.disable-responsive-font-size .selector-7,
+.disable-responsive-font-size.selector-7 {
+ font-size: 1.75rem;
+ }
+ @media (max-width: 1200px) {
+ .selector-7 {
+ font-size: calc(1.15rem + 0.8vw);
+ }
+ }
+}
diff --git a/examples/postcss/gulp/gulpfile.js b/examples/postcss/gulp/gulpfile.js
new file mode 100644
index 0000000..873a17d
--- /dev/null
+++ b/examples/postcss/gulp/gulpfile.js
@@ -0,0 +1,20 @@
+const gulp = require('gulp');
+const postcss = require('gulp-postcss');
+const rfs = require('../..');
+const options = {
+ twoDimensional: false,
+ minimumFontSize: 16,
+ fontSizeUnit: 'rem',
+ breakpoint: 1200,
+ breakpointUnit: 'px',
+ factor: 5,
+ unitPrecision: 6,
+ remValue: 16,
+ propList: ['responsive-font-size', 'rfs']
+};
+
+gulp.task('css', () => {
+ return gulp.src('./src/main.css')
+ .pipe(postcss([rfs(options)]))
+ .pipe(gulp.dest('./dest'));
+});
diff --git a/examples/postcss/gulp/src/main.css b/examples/postcss/gulp/src/main.css
new file mode 100644
index 0000000..ebc55d4
--- /dev/null
+++ b/examples/postcss/gulp/src/main.css
@@ -0,0 +1,38 @@
+/* responsive-font-size property with `px` unit */
+.selector-1 {
+ background-color: red;
+ width: 300px;
+ responsive-font-size: 32px;
+}
+
+/* responsive-font-size property with `rem` unit */
+.selector-2 {
+ responsive-font-size: 2rem;
+}
+
+/* responsive-font-size property with !important */
+.selector-3 {
+ responsive-font-size: 2rem !important;
+}
+
+/* rfs shorthand */
+.selector-4 {
+ rfs: 2rem;
+}
+
+/* not supported unit */
+.selector-5 {
+ responsive-font-size: 2em;
+}
+
+/* special value */
+.selector-6 {
+ responsive-font-size: inherit;
+}
+
+/* responsive-font-size property inside @support-query */
+@supports (display: flex) {
+ .selector-7 {
+ rfs: 28px;
+ }
+}
diff --git a/examples/postcss/node/index.js b/examples/postcss/node/index.js
new file mode 100644
index 0000000..e0390b6
--- /dev/null
+++ b/examples/postcss/node/index.js
@@ -0,0 +1,24 @@
+const fs = require('fs');
+const postcss = require('postcss');
+const rfs = require('../..');
+const css = fs.readFileSync('main.css', 'utf8');
+const options = {
+ twoDimensional: false,
+ minimumFontSize: 16,
+ fontSizeUnit: 'rem',
+ // breakpoint: 1200,
+ breakpointUnit: 'px',
+ factor: 5,
+ unitPrecision: 6,
+ remValue: 16,
+ propList: ['responsive-font-size', 'rfs']
+};
+
+const processedCss = postcss(rfs(options)).process(css).css;
+
+fs.writeFile('main.dest.css', processedCss, (err) => {
+ if (err) {
+ throw err;
+ }
+ console.log('Responsive font sizes generated.');
+});
diff --git a/examples/postcss/node/main.css b/examples/postcss/node/main.css
new file mode 100644
index 0000000..ebc55d4
--- /dev/null
+++ b/examples/postcss/node/main.css
@@ -0,0 +1,38 @@
+/* responsive-font-size property with `px` unit */
+.selector-1 {
+ background-color: red;
+ width: 300px;
+ responsive-font-size: 32px;
+}
+
+/* responsive-font-size property with `rem` unit */
+.selector-2 {
+ responsive-font-size: 2rem;
+}
+
+/* responsive-font-size property with !important */
+.selector-3 {
+ responsive-font-size: 2rem !important;
+}
+
+/* rfs shorthand */
+.selector-4 {
+ rfs: 2rem;
+}
+
+/* not supported unit */
+.selector-5 {
+ responsive-font-size: 2em;
+}
+
+/* special value */
+.selector-6 {
+ responsive-font-size: inherit;
+}
+
+/* responsive-font-size property inside @support-query */
+@supports (display: flex) {
+ .selector-7 {
+ rfs: 28px;
+ }
+}
diff --git a/examples/postcss/node/main.dest.css b/examples/postcss/node/main.dest.css
new file mode 100644
index 0000000..121ce9a
--- /dev/null
+++ b/examples/postcss/node/main.dest.css
@@ -0,0 +1,73 @@
+/* responsive-font-size property with `px` unit */
+.selector-1,
+.disable-responsive-font-size .selector-1,
+.disable-responsive-font-size.selector-1 {
+ background-color: red;
+ width: 300px;
+ font-size: 2rem;
+}
+@media (max-width: 1200px) {
+ .selector-1 {
+ font-size: calc(1.2rem + 1.066667vw);
+ }
+}
+
+/* responsive-font-size property with `rem` unit */
+.selector-2,
+.disable-responsive-font-size .selector-2,
+.disable-responsive-font-size.selector-2 {
+ font-size: 2rem;
+}
+@media (max-width: 1200px) {
+ .selector-2 {
+ font-size: calc(1.2rem + 1.066667vw);
+ }
+}
+
+/* responsive-font-size property with !important */
+.selector-3,
+.disable-responsive-font-size .selector-3,
+.disable-responsive-font-size.selector-3 {
+ font-size: 2rem !important;
+}
+@media (max-width: 1200px) {
+ .selector-3 {
+ font-size: calc(1.2rem + 1.066667vw) !important;
+ }
+}
+
+/* rfs shorthand */
+.selector-4,
+.disable-responsive-font-size .selector-4,
+.disable-responsive-font-size.selector-4 {
+ font-size: 2rem;
+}
+@media (max-width: 1200px) {
+ .selector-4 {
+ font-size: calc(1.2rem + 1.066667vw);
+ }
+}
+
+/* not supported unit */
+.selector-5 {
+ font-size: 2em;
+}
+
+/* special value */
+.selector-6 {
+ font-size: inherit;
+}
+
+/* responsive-font-size property inside @support-query */
+@supports (display: flex) {
+ .selector-7,
+.disable-responsive-font-size .selector-7,
+.disable-responsive-font-size.selector-7 {
+ font-size: 1.75rem;
+ }
+ @media (max-width: 1200px) {
+ .selector-7 {
+ font-size: calc(1.15rem + 0.8vw);
+ }
+ }
+}
diff --git a/less/rfs.less b/less/rfs.less
new file mode 100644
index 0000000..ee82401
--- /dev/null
+++ b/less/rfs.less
@@ -0,0 +1,204 @@
+// stylelint-disable declaration-property-value-blacklist
+
+// RFS mixin.
+//
+// Automated font-resizing.
+//
+// See https://github.com/MartijnCuppens/rfs.
+
+// Configuration.
+
+// Minimum font size.
+@rfs-minimum-font-size: 1rem;
+@rfs-font-size-unit: rem;
+
+// Breakpoint at where font-size starts decreasing if screen width is smaller.
+@rfs-breakpoint: 1200px;
+@rfs-breakpoint-unit: px;
+
+// Resize font-size based on screen height and width.
+@rfs-two-dimensional: false;
+
+// Factor of decrease.
+@rfs-factor: 5;
+
+// Generate disable classes
+@rfs-generate-disable-classes: true;
+
+// 1 rem = @rfs-rem-value px.
+@rfs-rem-value: 16;
+
+// Disable RFS by setting @enable-responsive-font-sizes to false.
+@enable-responsive-font-sizes: true;
+
+// Responsive font-size mixin.
+.rfs(@fs, @important: false) {
+
+ & when (not(@important)) {
+ ._rfs-prefix(@fs, e(''));
+ }
+
+ & when (@important) {
+ ._rfs-prefix(@fs, e(' !important'));
+ }
+}
+
+._rfs-prefix(@fs, @suffix) {
+
+ & when ((not(isnumber(@fs)) and not(isunit(@fs, px)) and not(isunit(@fs, rem))) or (@fs = 0)) {
+ font-size: @fs @suffix;
+ }
+
+ & when (((isnumber(@fs)) and (get-unit(@fs) = e(''))) or (isunit(@fs, px)) or (isunit(@fs, rem))) {
+ ._rfs-render-base(@fs, @suffix);
+ }
+}
+
+._rfs-render-base(@fs, @suffix) {
+
+ & when ((isnumber(@fs)) and (get-unit(@fs) = e(''))) {
+ ._rfs-render-base-number(@fs, @suffix);
+ ._rfs-render-media-query(@fs, @suffix);
+ }
+
+ & when ((isunit(@fs, px))) {
+ ._rfs-render-base-number(unit(@fs), @suffix);
+ ._rfs-render-media-query(unit(@fs), @suffix);
+ }
+
+ & when ((isunit(@fs, rem))) {
+ ._rfs-render-base-number(unit(@fs/.0625), @suffix);
+ ._rfs-render-media-query(unit(@fs/.0625), @suffix);
+ }
+}
+
+._rfs-render-media-query(@fs, @suffix) {
+ & when ((@fs > @rfs-minimum-font-size) and (@rfs-factor > 1) and (@enable-responsive-font-sizes = true)) {
+
+ & when ((isnumber(@rfs-breakpoint)) and (get-unit(@rfs-breakpoint) = e(''))) {
+ ._rfs-render-media-query-breakpoint(@fs, @suffix, @rfs-breakpoint);
+ }
+
+ & when ((isunit(@rfs-breakpoint, px))) {
+ ._rfs-render-media-query-breakpoint(@fs, @suffix, unit(@rfs-breakpoint));
+ }
+
+ & when ((isunit(@rfs-breakpoint, rem))) {
+ ._rfs-render-media-query-breakpoint(@fs, @suffix, unit(@rfs-breakpoint * @rfs-rem-value));
+ }
+
+ & when ((isunit(@rfs-breakpoint, em))) {
+ ._rfs-render-media-query-breakpoint(@fs, @suffix, unit(@rfs-breakpoint * @rfs-rem-value));
+ }
+ }
+}
+
+._rfs-render-media-query-breakpoint(@fs, @suffix, @breakpoint) {
+ & when (@rfs-two-dimensional) {
+ ._rfs-render-media-query-two-dimensional(@fs, @suffix, @breakpoint);
+ }
+ & when (not(@rfs-two-dimensional)) {
+ ._rfs-render-media-query-one-dimension(@fs, @suffix, @breakpoint);
+ }
+}
+
+._rfs-render-media-query-one-dimension(@fs, @suffix, @breakpoint) {
+ & when (@rfs-breakpoint-unit = px) {
+ @media (max-width: unit(@breakpoint, px)) {
+ ._rfs-render-media-query-content(@fs, @suffix, @breakpoint);
+ }
+ }
+
+ & when (@rfs-breakpoint-unit = rem) {
+ @media (max-width: unit((@breakpoint / @rfs-rem-value), rem)) {
+ ._rfs-render-media-query-content(@fs, @suffix, @breakpoint);
+ }
+ }
+
+ & when (@rfs-breakpoint-unit = em) {
+ @media (max-width: unit((@breakpoint / @rfs-rem-value), em)) {
+ ._rfs-render-media-query-content(@fs, @suffix, @breakpoint);
+ }
+ }
+}
+
+._rfs-render-media-query-two-dimensional(@fs, @suffix, @breakpoint) {
+ & when (@rfs-breakpoint-unit = px) {
+ @media (max-width: unit(@breakpoint, px)), (max-height: unit(@breakpoint, px)) {
+ ._rfs-render-media-query-content(@fs, @suffix, @breakpoint);
+ }
+ }
+
+ & when (@rfs-breakpoint-unit = rem) {
+ @media (max-width: unit((@breakpoint / @rfs-rem-value), rem)), (max-height: unit((@breakpoint / @rfs-rem-value), rem)) {
+ ._rfs-render-media-query-content(@fs, @suffix, @breakpoint);
+ }
+ }
+
+ & when (@rfs-breakpoint-unit = em) {
+ @media (max-width: unit((@breakpoint / @rfs-rem-value), em)), (max-height: unit((@breakpoint / @rfs-rem-value), em)) {
+ ._rfs-render-media-query-content(@fs, @suffix, @breakpoint);
+ }
+ }
+}
+
+._rfs-render-media-query-content(@fs, @suffix, @breakpoint) {
+ & when ((isnumber(@rfs-minimum-font-size)) and (get-unit(@rfs-minimum-font-size) = e(''))) {
+ ._rfs-render-media-query-content-dimensional(@fs, @suffix, @rfs-minimum-font-size, @breakpoint);
+ }
+
+ & when ((isunit(@rfs-minimum-font-size, px))) {
+ ._rfs-render-media-query-content-dimensional(@fs, @suffix, unit(@rfs-minimum-font-size), @breakpoint);
+ }
+
+ & when ((isunit(@rfs-minimum-font-size, rem))) {
+ ._rfs-render-media-query-content-dimensional(@fs, @suffix, unit(@rfs-minimum-font-size * @rfs-rem-value), @breakpoint);
+ }
+}
+
+._rfs-render-media-query-content-dimensional(@fs, @suffix, @rfs-min, @breakpoint) {
+ & when (@rfs-two-dimensional) {
+ // Calculate minimum font-size for given font-size.
+ @fs-min: @rfs-min + (@fs - @rfs-min) / @rfs-factor;
+ // Calculate difference between given font-size and minimum font-size for given font-size.
+ @fs-variable-width: unit((@fs - @fs-min) / (@breakpoint / 100), vmin);
+
+ ._rfs-render-fluid(@fs-min, @fs-variable-width, @suffix);
+ }
+
+ & when (not(@rfs-two-dimensional)) {
+ // Calculate minimum font-size for given font-size.
+ @fs-min: @rfs-min + (@fs - @rfs-min) / @rfs-factor;
+ // Calculate difference between given font-size and minimum font-size for given font-size.
+ @fs-variable-width: unit((@fs - @fs-min) / (@breakpoint / 100), vw);
+
+ ._rfs-render-fluid(@fs-min, @fs-variable-width, @suffix);
+ }
+}
+
+._rfs-render-fluid(@fs-min, @fs-variable-width, @suffix) {
+
+ & when (@rfs-font-size-unit = px) {
+ font-size: calc(unit(@fs-min, px) e('+') @fs-variable-width)@suffix;
+ }
+
+ & when (@rfs-font-size-unit = rem) {
+ font-size: calc(unit(@fs-min / @rfs-rem-value, rem) e('+') @fs-variable-width)@suffix;
+ }
+}
+
+._rfs-render-base-number(@fs, @suffix) {
+
+ & when (@rfs-font-size-unit = px) {
+ font-size: unit(@fs, px)@suffix;
+ }
+
+ & when (@rfs-font-size-unit = rem) {
+ font-size: unit((@fs / @rfs-rem-value), rem)@suffix;
+ }
+}
+
+// The responsive-font-size mixin uses RFS to rescale font sizes.
+.responsive-font-size(@fs, @important: false) {
+ .rfs(@fs, @important);
+}
diff --git a/package.json b/package.json
index f41f0ae..62e415f 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,6 @@
"name": "rfs",
"version": "7.0.4",
"description": "A scss-mixin for responsive font-sizes.",
- "main": "scss/_rfs.scss",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
@@ -11,15 +10,30 @@
"url": "git+https://github.com/MartijnCuppens/rfs.git"
},
"keywords": [
- "scss",
+ "rfs",
"responsive",
"font-size",
- "typography"
+ "typography",
+ "scss",
+ "sass",
+ "less",
+ "stylus",
+ "postcss"
],
"author": "Martijn Cuppens <martijn.cuppens@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/MartijnCuppens/rfs/issues"
},
- "homepage": "https://github.com/MartijnCuppens/rfs#readme"
+ "homepage": "https://github.com/MartijnCuppens/rfs#readme",
+ "devDependencies": {
+ "postcss": "^6.0.14",
+ "babel-cli": "^6.26.0",
+ "babel-preset-env": "^1.6.1",
+ "browserify": "^14.5.0",
+ "postcss-nested": "^3.0.0",
+ "uglify-js": "^3.2.2",
+ "gulp-postcss" : "^7.0.0",
+ "gulp": "^3.9.1"
+ }
}
diff --git a/postcss/rfs.js b/postcss/rfs.js
new file mode 100644
index 0000000..abe02a5
--- /dev/null
+++ b/postcss/rfs.js
@@ -0,0 +1,175 @@
+'use strict';
+
+const postcss = require('postcss');
+
+module.exports = postcss.plugin('postcss-rfs', function (opts) {
+ const BREAKPOINT_ERROR = 'breakpoint option is invalid, it must be set in `px`, `rem` or `em`.';
+ const BREAKPOINT_UNIT_ERROR = 'breakpointUnit option is invalid, it must be `px`, `rem` or `em`.';
+ const MINIMUM_FONT_SIZE_ERROR = 'minimumFontSize option is invalid, it must be set in `px` or `rem`.';
+ const DISABLE_RESPONSIVE_FONT_SIZE_SELECTOR = '.disable-responsive-font-size';
+ opts = opts || {};
+ opts.minimumFontSize = opts.minimumFontSize || 16;
+ opts.fontSizeUnit = opts.fontSizeUnit || 'rem';
+ opts.breakpoint = opts.breakpoint || 1200;
+ opts.breakpointUnit = opts.breakpointUnit || 'px';
+ opts.factor = opts.factor || 5;
+ opts.twoDimensional = opts.twoDimensional || false;
+ opts.unitPrecision = opts.unitPrecision || 5;
+ opts.generateDisableClasses = opts.generateDisableClasses || true;
+ opts.remValue = opts.remValue || 16;
+ opts.propList = opts.propList || ['responsive-font-size', 'rfs'];
+
+ if (typeof opts.minimumFontSize !== 'number') {
+ if (opts.minimumFontSize.endsWith('px')) {
+ opts.minimumFontSize = parseFloat(opts.minimumFontSize);
+ }
+ else if (opts.minimumFontSize.endsWith('rem')) {
+ opts.minimumFontSize = parseFloat(opts.minimumFontSize) / opts.remValue;
+ }
+ else {
+ console.error(MINIMUM_FONT_SIZE_ERROR);
+ }
+ }
+
+ if (typeof opts.breakpoint !== 'number') {
+ if (opts.breakpoint.endsWith('px')) {
+ opts.breakpoint = parseFloat(opts.breakpoint);
+ }
+ else if (opts.breakpoint.endsWith('em')) {
+ opts.breakpoint = parseFloat(opts.breakpoint) * opts.remValue;
+ }
+ else {
+ console.error(BREAKPOINT_ERROR);
+ }
+ }
+
+ return function (css) {
+
+ css.walkRules(function (rule) {
+
+ if (rule.selector.includes(DISABLE_RESPONSIVE_FONT_SIZE_SELECTOR)){
+ return;
+ }
+
+ rule.walkDecls(function (decl) {
+ // Skip if property is not in propList.
+ if (opts.propList.indexOf(decl.prop) === -1) {
+ return;
+ }
+
+ // Set property to font-size.
+ decl.prop = 'font-size';
+
+ // Skip if value is not in px or rem.
+ if (!new RegExp(/(\d*\.?\d+)(px|rem)/g).test(decl.value)) {
+ return;
+ }
+
+ // Get the float value of the value.
+ let value = parseFloat(decl.value);
+
+ // Multiply by remValue if value is in rem.
+ if (decl.value.indexOf('rem') > -1) {
+ value *= opts.remValue;
+ }
+
+ // Render value in desired unit.
+ if (opts.fontSizeUnit === 'px') {
+ decl.value = toFixed(value, opts.unitPrecision) + 'px';
+ }
+ else if (opts.fontSizeUnit === 'rem') {
+ decl.value = toFixed(value / opts.remValue, opts.unitPrecision) + 'rem';
+ }
+ else {
+ console.error('fontSizeUnit option is not valid, it must be `px` or `rem`.');
+ }
+
+ // Only add media query if needed.
+ if (opts.minimumFontSize >= value || opts.factor === 1) {
+ return;
+ }
+
+ // Calculate font-size and font-size difference.
+ let baseFontSize = opts.minimumFontSize + (value - opts.minimumFontSize) / opts.factor;
+ const fontSizeDiff = value - baseFontSize;
+
+ // Divide by remValue if needed.
+ if (opts.fontSizeUnit === 'rem') {
+ baseFontSize /= opts.remValue;
+ }
+
+ // Save selector for later.
+ const rule_selector = rule.selector;
+
+ // Disable classes.
+ if (opts.generateDisableClasses) {
+ const selectors = rule.selector.split(',');
+ let ruleSelector = '';
+
+ for (let selector of selectors) {
+ ruleSelector += selector + ',\n';
+ ruleSelector += DISABLE_RESPONSIVE_FONT_SIZE_SELECTOR + ' ' + selector + ',\n';
+ ruleSelector += DISABLE_RESPONSIVE_FONT_SIZE_SELECTOR + selector + ',\n';
+ }
+
+ rule.selector = ruleSelector.slice(0, - 2);
+ }
+
+ const viewportUnit = opts.twoDimensional ? 'vmin' : 'vw';
+
+ value = 'calc(' + toFixed(baseFontSize, opts.unitPrecision) + opts.fontSizeUnit + ' + ' + toFixed((fontSizeDiff * 100 / opts.breakpoint), opts.unitPrecision) + viewportUnit + ')';
+
+ const mediaQuery = postcss.atRule(renderMediaQuery(opts));
+ const mediaQueryRule = postcss.rule({
+ selector: rule_selector,
+ source: rule.source
+ });
+ mediaQueryRule.append(decl.clone({value: value}));
+ mediaQuery.append(mediaQueryRule);
+ rule.parent.insertAfter(rule, mediaQuery.clone());
+ });
+ });
+
+ };
+
+ function renderMediaQuery (opts) {
+ const mediaQuery = {
+ name: 'media'
+ };
+
+ switch (opts.breakpointUnit) {
+ case 'em':
+ case 'rem':
+ const breakpoint = opts.breakpoint / opts.remValue;
+
+ if (opts.twoDimensional) {
+ mediaQuery.params = '(max-width: ' + breakpoint + opts.breakpointUnit + '), (max-height: ' + breakpoint + opts.breakpointUnit + ')';
+ }
+ else {
+ mediaQuery.params = '(max-width: ' + breakpoint + opts.breakpointUnit + ')';
+ }
+ break;
+
+ case 'px':
+ if (opts.twoDimensional) {
+ mediaQuery.params = '(max-width: ' + opts.breakpoint + 'px), (max-height: ' + opts.breakpoint + 'px)';
+ }
+ else {
+ mediaQuery.params = '(max-width: ' + opts.breakpoint + 'px)';
+ }
+ break;
+
+ default:
+ console.error(BREAKPOINT_UNIT_ERROR);
+ break;
+ }
+
+ return mediaQuery;
+ }
+
+ function toFixed (number, precision) {
+ const multiplier = Math.pow(10, precision + 1),
+ wholeNumber = Math.floor(number * multiplier);
+ return Math.round(wholeNumber / 10) * 10 / multiplier;
+ }
+});
diff --git a/stylus/_rfs.styl b/stylus/_rfs.styl
new file mode 100644
index 0000000..330dceb
--- /dev/null
+++ b/stylus/_rfs.styl
@@ -0,0 +1,151 @@
+// stylelint-disable declaration-property-value-blacklist
+
+// RFS mixin.
+//
+// Automated font-resizing.
+//
+// See https://github.com/MartijnCuppens/rfs.
+
+// Configuration.
+
+// Minimum fontsize.
+$rfs-minimum-font-size = 1rem
+$rfs-font-size-unit = rem
+
+// Breakpoint at where font-size starts decreasing if screen width is smaller.
+$rfs-breakpoint = 1200px
+$rfs-breakpoint-unit = px
+
+// Resize font-size based on screen height and width.
+$rfs-two-dimensional = false
+
+// Factor of decrease.
+$rfs-factor = 5
+
+// Generate disable classes
+$rfs-generate-disable-classes = true
+
+// 1 rem = $rfs-rem-value px.
+$rfs-rem-value = 16
+
+// Disable RFS by setting $enable-responsive-font-sizes to false.
+$enable-responsive-font-sizes = true
+
+if $enable-responsive-font-sizes == false
+ // If $rfs-factor is set to 1, fluid font-resizing is disabled.
+ $rfs-factor = 1
+
+// Remove px-unit from $rfs-minimum-font-size for calculations.
+if unit($rfs-minimum-font-size) == "px"
+ $rfs-minimum-font-size = unit($rfs-minimum-font-size, '')
+else if unit($rfs-minimum-font-size) == "rem"
+ $rfs-minimum-font-size = unit($rfs-minimum-font-size * $rfs-rem-value, '')
+
+// Remove unit from $rfs-breakpoint for calculations.
+if unit($rfs-breakpoint) == "px"
+ $rfs-breakpoint = unit($rfs-breakpoint, '')
+else if unit($rfs-breakpoint) == "rem" or unit($rfs-breakpoint) == "em"
+ $rfs-breakpoint = unit($rfs-breakpoint / $rfs-rem-value, '')
+
+// Responsive font-size mixin.
+rfs($fs, $important = false)
+ $rfs-suffix = "%s" % ()
+
+ // Add !important suffix if needed.
+ if $important
+ $rfs-suffix = !important
+
+ // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value.
+ if type-of($fs) != "unit" or !unitless($fs) and unit($fs) != "px" and unit($fs) != "rem" or $fs == 0
+ font-size: "%s%s" % ($fs $rfs-suffix)
+ else
+ // Variables for storing static and fluid rescaling.
+ $rfs-static = null
+ $rfs-fluid = null
+
+ // Remove px-unit from $fs for calculations.
+ if unit($fs) == px
+ $fs = unit($fs, '')
+ else if unit($fs) == rem
+ $fs = unit($fs / $rfs-rem-value, '')
+
+ // Set default font-size.
+ if $rfs-font-size-unit == rem
+ $rfs-static = "%s%s" % (unit(($fs / $rfs-rem-value), rem) $rfs-suffix)
+ else if $rfs-font-size-unit == px
+ $rfs-static = "%s%s" % (unit($fs, px) $rfs-suffix)
+ else
+ @error "`$rfs-font-size-unit` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`."
+
+ if type-of($rfs-factor) != "unit" or $rfs-factor < 1
+ @error "`$rfs-factor` is not a valid $rfs-factor, it must be greater or equal to 1."
+
+ // Only add media query if font-size is bigger as the minimum font-size.
+ // If $rfs-factor == 1, no rescaling will take place.
+ if $fs > $rfs-minimum-font-size and $rfs-factor != 1
+ $min-width = null
+ $variable-unit = null
+
+ // Calculate minimum font-size for given font-size.
+ $fs-min = $rfs-minimum-font-size + ($fs - $rfs-minimum-font-size) / $rfs-factor
+
+ // Calculate difference between given font-size and minimum font-size for given font-size.
+ $fs-diff = $fs - $fs-min
+
+ // Minimum font-size formatting.
+ // No need to check if the unit is valid, because we did that before.
+ if $rfs-font-size-unit == rem
+ $min-width = unit($fs-min / $rfs-rem-value, rem)
+ else
+ $min-width = unit($fs-min, px)
+
+ // If two-dimensional, use smallest of screen width and height.
+ if $rfs-two-dimensional
+ $variable-unit = vmin
+ else
+ $variable-unit = vw
+
+ // Calculate the variable width between 0 and $rfs-breakpoint.
+ $variable-width = "%s%s" % ($fs-diff * 100 / $rfs-breakpoint $variable-unit)
+
+ // Set the calculated font-size.
+ $rfs-fluid = "calc(%s + %s)%s" % ($min-width $variable-width $rfs-suffix)
+
+ // Rendering.
+ if $rfs-fluid == null
+ // Only render static font-size if no fluid font-size is available.
+ font-size: $rfs-static
+ else
+ $mq-value = null
+
+ // RFS breakpoint formatting.
+ if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem
+ $mq-value = unit($rfs-breakpoint / $rfs-rem-value, $rfs-breakpoint-unit)
+ else if $rfs-breakpoint-unit == px
+ $mq-value = unit($rfs-breakpoint, px)
+ else
+ @error "`$rfs-breakpoint-unit` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`."
+
+ if $rfs-generate-disable-classes
+ // Adding an extra class increases specificity,
+ // which prevents the media query to override the font size
+ &,
+ .disable-responsive-font-size &,
+ &.disable-responsive-font-size
+ font-size: $rfs-static
+ else
+ font-size: $rfs-static
+
+ if $rfs-two-dimensional
+ @media (max-width: $mq-value), (max-height: $mq-value)
+ font-size: $rfs-fluid
+ else
+ @media (max-width: $mq-value)
+ font-size: $rfs-fluid
+
+// The responsive-font-size mixin uses RFS to rescale font sizes.
+responsive-font-size($fs, $important = false)
+ rfs($fs, $important)
+
+.title
+ responsive-font-size(40)