├── .gitignore ├── .release-it.json ├── CHANGELOG.md ├── README.md ├── index.js ├── package-lock.json ├── package.json └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | -------------------------------------------------------------------------------- /.release-it.json: -------------------------------------------------------------------------------- 1 | { 2 | "git": { 3 | "tagName": "v${version}", 4 | "requireCleanWorkingDir": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [3.0.0] - 2020-02-05 9 | 10 | ### Added 11 | - A ratio of `0` is now valid (generates `padding-bottom: 0`) 12 | 13 | ### Changed 14 | - Changed to use Tailwind 1.2’s new plugin definition syntax 15 | 16 | ## [2.0.0] - 2019-07-03 17 | 18 | ### Added 19 | - Tailwind 1.0.0 compatibility 20 | 21 | ## [1.0.1] - 2018-06-25 22 | 23 | ### Fixed 24 | - More robust escaping of class names 25 | 26 | ## [1.0.0] - 2018-03-20 27 | 28 | Initial release 29 | 30 | [Unreleased]: https://github.com/webdna/tailwindcss-aspect-ratio/compare/v3.0.0...HEAD 31 | [3.0.0]: https://github.com/webdna/tailwindcss-aspect-ratio/compare/v2.0.0...v3.0.0 32 | [2.0.0]: https://github.com/webdna/tailwindcss-aspect-ratio/compare/v1.0.1...v2.0.0 33 | [1.0.1]: https://github.com/webdna/tailwindcss-aspect-ratio/compare/v1.0.0...v1.0.1 34 | [1.0.0]: https://github.com/webdna/tailwindcss-aspect-ratio/releases/tag/v1.0.0 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⛔️ DEPRECATED 2 | 3 | This plugin was created before the [`aspect-ratio`](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio) property was supported by any browser. You should now use the official [`@tailwindcss/aspect-ratio`](https://github.com/tailwindlabs/tailwindcss-aspect-ratio) plugin. 4 | 5 | # Aspect Ratio Plugin for Tailwind CSS 6 | 7 | ## Requirements 8 | 9 | This plugin requires Tailwind CSS 1.2 or later. If your project uses an older version of Tailwind, you should install the latest 2.x version of this plugin (`npm install tailwindcss-aspect-ratio@2.x`). 10 | 11 | ## Installation 12 | 13 | ```bash 14 | npm install tailwindcss-aspect-ratio 15 | ``` 16 | 17 | ## Usage 18 | 19 | This plugin uses the `aspectRatio` key in your Tailwind config’s `theme` and `variants` objects to generate aspect ratio utilities. Here is an example: 20 | 21 | ```js 22 | // tailwind.config.js 23 | module.exports = { 24 | theme: { 25 | aspectRatio: { // defaults to {} 26 | 'none': 0, 27 | 'square': [1, 1], // or 1 / 1, or simply 1 28 | '16/9': [16, 9], // or 16 / 9 29 | '4/3': [4, 3], // or 4 / 3 30 | '21/9': [21, 9], // or 21 / 9 31 | }, 32 | }, 33 | variants: { 34 | aspectRatio: ['responsive'], // defaults to ['responsive'] 35 | }, 36 | plugins: [ 37 | require('tailwindcss-aspect-ratio'), 38 | ], 39 | }; 40 | ``` 41 | 42 | The `aspectRatio` theme object is a dictionary where the key is the suffix of the class name and the value is an array of width and height or a number that represents a width / height ratio. The key doesn’t have to replicate the values, so if you prefer "nice names" you could have something like `'video': [16, 9]`. 43 | 44 | The above configuration would create the following classes, as well as their responsive variants: 45 | 46 | ```css 47 | .aspect-ratio-none { 48 | padding-bottom: 0; 49 | } 50 | .aspect-ratio-square { 51 | padding-bottom: 100%; 52 | } 53 | .aspect-ratio-16\/9 { 54 | padding-bottom: 56.25%; 55 | } 56 | .aspect-ratio-4\/3 { 57 | padding-bottom: 75%; 58 | } 59 | .aspect-ratio-21\/9 { 60 | padding-bottom: 42.86%; 61 | } 62 | ``` 63 | 64 | Which you can then use in your HTML like this: 65 | 66 | ```html 67 |
68 |
69 | 70 |
71 | ``` 72 | 73 | Or inside a `flex` container to behave like a “minimum aspect ratio” (if the content overflows, the container will grow instead of forcing the aspect ratio): 74 | 75 | ```html 76 |
77 |
78 |

79 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sed dictum sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Maecenas et lacus ut dolor rutrum dignissim. 80 |

81 |
82 | ``` 83 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const plugin = require('tailwindcss/plugin'); 2 | const _ = require('lodash'); 3 | 4 | module.exports = plugin(function({ theme, variants, e, addUtilities }) { 5 | const aspectRatioUtilities = _.fromPairs( 6 | _.map(theme('aspectRatio'), (value, modifier) => { 7 | const aspectRatio = _.isArray(value) ? value[0] / value[1] : value; 8 | return [ 9 | `.${e(`aspect-ratio-${modifier}`)}`, 10 | { 11 | paddingBottom: aspectRatio == 0 ? '0' : `${1 / aspectRatio * 100}%`, 12 | }, 13 | ]; 14 | }) 15 | ); 16 | 17 | addUtilities(aspectRatioUtilities, variants('aspectRatio')); 18 | }, { 19 | theme: { 20 | aspectRatio: {}, 21 | }, 22 | variants: { 23 | aspectRatio: ['responsive'], 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tailwindcss-aspect-ratio", 3 | "version": "3.0.0", 4 | "description": "Tailwind CSS plugin to generate aspect ratio utilities", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/webdna/tailwindcss-aspect-ratio.git" 8 | }, 9 | "keywords": [ 10 | "tailwind", 11 | "tailwindcss", 12 | "plugin", 13 | "tailwindcss-plugin" 14 | ], 15 | "author": "webdna", 16 | "license": "MIT", 17 | "bugs": "https://github.com/webdna/tailwindcss-aspect-ratio/issues", 18 | "homepage": "https://github.com/webdna/tailwindcss-aspect-ratio", 19 | "scripts": { 20 | "test": "jest", 21 | "release": "f(){ release-it $1 && github-release-from-changelog ;};f" 22 | }, 23 | "devDependencies": { 24 | "github-release-from-changelog": "^2.1.1", 25 | "jest": "^26.1.0", 26 | "jest-matcher-css": "^1.1.0", 27 | "postcss": "^7.0.32", 28 | "release-it": "^13.6.5", 29 | "tailwindcss": "^1.5.1" 30 | }, 31 | "dependencies": { 32 | "lodash": "^4.17.19" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash'); 2 | const cssMatcher = require('jest-matcher-css'); 3 | const postcss = require('postcss'); 4 | const tailwindcss = require('tailwindcss'); 5 | const aspectRatioPlugin = require('./index.js'); 6 | 7 | const generatePluginCss = (config) => { 8 | return postcss( 9 | tailwindcss( 10 | _.merge({ 11 | theme: { 12 | screens: { 13 | 'sm': '640px', 14 | }, 15 | }, 16 | corePlugins: false, 17 | plugins: [ 18 | aspectRatioPlugin, 19 | ], 20 | }, config) 21 | ) 22 | ) 23 | .process('@tailwind utilities', { 24 | from: undefined, 25 | }) 26 | .then(result => { 27 | return result.css; 28 | }); 29 | }; 30 | 31 | expect.extend({ 32 | toMatchCss: cssMatcher, 33 | }); 34 | 35 | test('there is no output by default', () => { 36 | return generatePluginCss().then(css => { 37 | expect(css).toMatchCss(` 38 | @media (min-width: 640px) { 39 | } 40 | `); 41 | }); 42 | }); 43 | 44 | test('ratios can be customized', () => { 45 | return generatePluginCss({ 46 | theme: { 47 | aspectRatio: { 48 | '2/1': [2, 1], 49 | '16/9': [16, 9], 50 | }, 51 | }, 52 | }).then(css => { 53 | expect(css).toMatchCss(` 54 | .aspect-ratio-2\\/1 { 55 | padding-bottom: 50%; 56 | } 57 | .aspect-ratio-16\\/9 { 58 | padding-bottom: 56.25%; 59 | } 60 | @media (min-width: 640px) { 61 | .sm\\:aspect-ratio-2\\/1 { 62 | padding-bottom: 50%; 63 | } 64 | .sm\\:aspect-ratio-16\\/9 { 65 | padding-bottom: 56.25%; 66 | } 67 | } 68 | `); 69 | }); 70 | }); 71 | 72 | test('ratios can be arrays or fractions', () => { 73 | return generatePluginCss({ 74 | theme: { 75 | aspectRatio: { 76 | '5/2': [5, 2], 77 | '16/9': 16 / 9, 78 | }, 79 | }, 80 | variants: { 81 | aspectRatio: [], 82 | }, 83 | }).then(css => { 84 | expect(css).toMatchCss(` 85 | .aspect-ratio-5\\/2 { 86 | padding-bottom: 40%; 87 | } 88 | .aspect-ratio-16\\/9 { 89 | padding-bottom: 56.25%; 90 | } 91 | `); 92 | }); 93 | }); 94 | 95 | test('ratio can be 0', () => { 96 | return generatePluginCss({ 97 | theme: { 98 | aspectRatio: { 99 | 'none': 0, 100 | }, 101 | }, 102 | variants: { 103 | aspectRatio: [], 104 | }, 105 | }).then(css => { 106 | expect(css).toMatchCss(` 107 | .aspect-ratio-none { 108 | padding-bottom: 0; 109 | } 110 | `); 111 | }); 112 | }); 113 | 114 | test('variants can be customized', () => { 115 | return generatePluginCss({ 116 | theme: { 117 | aspectRatio: { 118 | '2/1': [2, 1], 119 | }, 120 | }, 121 | variants: { 122 | aspectRatio: ['hover'], 123 | }, 124 | }).then(css => { 125 | expect(css).toMatchCss(` 126 | .aspect-ratio-2\\/1 { 127 | padding-bottom: 50%; 128 | } 129 | .hover\\:aspect-ratio-2\\/1:hover { 130 | padding-bottom: 50%; 131 | } 132 | `); 133 | }); 134 | }); 135 | --------------------------------------------------------------------------------