├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── build.yml │ └── npm-publish.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── _break-points.scss ├── _fluid-size.scss ├── _options.scss ├── _others.scss ├── _utils.scss ├── package.json ├── resource ├── Fluid-Size.afphoto ├── Fluid-Size.png ├── README.md ├── font.ods ├── samples │ ├── Fluid_1.afphoto │ ├── Fluid_1.png │ ├── Fluid_2.afphoto │ ├── Fluid_2.png │ ├── Fluid_3.afphoto │ ├── Fluid_3.png │ ├── Fluid_4.afphoto │ ├── Fluid_4.png │ ├── Fluid_5.afphoto │ ├── Fluid_5.png │ ├── Fluid_6.afphoto │ ├── Fluid_6.png │ ├── README.md │ ├── Size_1.afphoto │ ├── Size_1.png │ ├── Size_2.afphoto │ ├── Size_2.png │ ├── Size_3.afphoto │ ├── Size_3.png │ ├── Size_4.afphoto │ ├── Size_4.png │ ├── Size_5.afphoto │ ├── Size_5.png │ ├── Size_6.afphoto │ ├── Size_6.png │ ├── Size_7.afphoto │ ├── Size_7.png │ ├── Size_8.afphoto │ └── Size_8.png └── tables │ ├── Interval.csv │ ├── comparison.csv │ └── scale.csv └── scss-bundle.config.json /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment (please complete the following information):** 27 | General 28 | - OS: [e.g. Windows, Linux, Mac, iOS, Android] 29 | - Browser [e.g. Firefox, Chrome, Safari] 30 | - Version [e.g. Last-Release, Last-Commit, 1.5.0] 31 | 32 | Only when necessary 33 | - Resolution(px): [e.g. 480x854, 1280x720] 34 | - Screen Size(inch): [e.g 5, 10.2] 35 | 36 | **Additional context** 37 | Add any other context about the problem here. 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Do you have related issue? 2 | Ex) #ISSUE_NUMBER 3 | 4 | ### What does this PR do? 5 | **Docs** 6 | - [ ] Fix typos, alignments. 7 | - [ ] Correct awkward sentences. 8 | - [ ] Improve document readability. 9 | - [ ] Others: 10 | 11 | **Codes** 12 | - [ ] [API](https://github.com/black7375/fluid-size/wiki/API) or feature extension. 13 | - [ ] Doc updated? 14 | - [ ] Bug fixes. 15 | - [ ] Correct wrong implementation from theory. 16 | - [ ] Improved compatibility or accessibility. 17 | - [ ] Refactoring. 18 | - [ ] Others: 19 | 20 | ### Why are we doing this? 21 | Please tell me why you worked. 22 | 23 | ### Screenshots 24 | Put it in if necessary. 25 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages 3 | 4 | name: CI 5 | on: 6 | push: 7 | branches: [ master, dev ] 8 | pull_request: 9 | branches: [ master, dev ] 10 | 11 | jobs: 12 | build: 13 | name: build 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | - uses: actions/setup-node@v1 18 | - run: yarn install 19 | - run: yarn build 20 | 21 | sync-branch: 22 | needs: [ build ] 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/checkout@v2 26 | - name: Merge master -> github-repo 27 | uses: mtanzi/action-automerge@v1 28 | id: merge 29 | with: 30 | source: master 31 | target: github-repo 32 | github_token: ${{secrets.TOKEN_GITHUB}} 33 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages 3 | 4 | name: Publishing 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - uses: actions/setup-node@v1 16 | with: 17 | node-version: 12 18 | - run: npm install 19 | - run: npm ci 20 | - run: npm run build 21 | - run: npm test 22 | 23 | publish-npm: 24 | needs: build 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@v2 28 | - uses: actions/setup-node@v1 29 | with: 30 | node-version: 12 31 | registry-url: https://registry.npmjs.org/ 32 | - run: npm install 33 | - run: npm ci 34 | - run: npm run build 35 | - run: npm publish 36 | env: 37 | NODE_AUTH_TOKEN: ${{secrets.TOKEN_NPM}} 38 | 39 | publish-gpr: 40 | needs: build 41 | runs-on: ubuntu-latest 42 | steps: 43 | - uses: actions/checkout@v2 44 | with: 45 | ref: github-repo 46 | - uses: actions/setup-node@v1 47 | with: 48 | node-version: 12 49 | registry-url: https://npm.pkg.github.com/ 50 | - run: npm install 51 | - run: npm ci 52 | - run: npm run build 53 | - run: npm publish 54 | env: 55 | NODE_AUTH_TOKEN: ${{secrets.TOKEN_GITHUB}} 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | .sass-cache/ 5 | *.css.map 6 | *.sass.map 7 | *.scss.map 8 | 9 | /node_modules 10 | /.pnp 11 | .pnp.js 12 | 13 | # testing 14 | /coverage 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | .env.local 22 | .env.development.local 23 | .env.test.local 24 | .env.production.local 25 | 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at alstjr7375@daum.net. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | 4 | **Table of Contents** 5 | 6 | - [Introduce](#introduce) 7 | - [Code of Conduct](#code-of-conduct) 8 | - [We Develop with Github](#we-develop-with-github) 9 | - [Environment](#environment) 10 | - [Your First Contribution](#your-first-contribution) 11 | - [Contribution Targets](#contribution-targets) 12 | - [Rules](#rules) 13 | - [Issue](#issue) 14 | - [Coding style](#coding-style) 15 | - [Commit](#commit) 16 | - [Commit Message](#commit-message) 17 | - [Pull request](#pull-request) 18 | - [License](#license) 19 | - [References](#references) 20 | 21 | 22 | 23 | ## Introduce 24 | 25 | I'm really glad you're reading this, because we need volunteer developers to help this project come to fruition. 26 | 27 | Please note we have a code of conduct, please follow it in all your interactions with the project. 28 | 29 | ### Code of Conduct 30 | 31 | Refer to [CODE\_OF\_CONDUCT.md](https://github.com/black7375/Fluid-Size/blob/master/CODE_OF_CONDUCT.md). 32 | 33 | ### We Develop with Github 34 | 35 | We use [github](https://github.com/black7375/Fluid-Size) to host code, to track [issues](https://github.com/black7375/Fluid-Size/issues) and feature requests, as well as accept [pull requests](https://github.com/black7375/Fluid-Size/pulls). 36 | 37 | After feedback has been given we expect responses within two weeks. After two weeks we may close the issue and pull request if it isn't showing any activity. 38 | 39 | ### Environment 40 | 41 | You can configure it as follows: 42 | ```shell 43 | ## clone repository 44 | git clone https://github.com/black7375/Fluid-Size.git 45 | cd ./fluid-size 46 | 47 | ## install dependencies 48 | npm install 49 | ``` 50 | 51 | ### Your First Contribution 52 | 53 | **Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 54 | 55 | The following documents may be helpful: 56 | - [README](https://github.com/black7375/Fluid-Size/blob/master/README.md) 57 | - [Wiki:API](https://github.com/black7375/fluid-size/wiki/API) 58 | - [Wiki:Comparison](https://github.com/black7375/Fluid-Size/wiki/Comparison) 59 | - [Wiki:The theory of font size and readability](https://github.com/black7375/Fluid-Size/wiki/The-theory-of-font-size-and-readability) 60 | 61 | 62 | ### Contribution Targets 63 | 64 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: 65 | 66 | **Docs** 67 | - Fix typos, alignments. 68 | - Correct awkward sentences. 69 | - Improve document readability. 70 | 71 | **Issues** 72 | - Found an error in the [Wiki:The theory of font size and readability](https://github.com/black7375/fluid-size/wiki/The-theory-of-font-size-and-readability). 73 | - Report a bug. 74 | - Discussing the current state of the code. 75 | - Good theory or algorithm suggestion. 76 | - Tell us about related or relevant projects and documents. 77 | - Proposing others.. 78 | 79 | **Codes** 80 | - [API](https://github.com/black7375/fluid-size/wiki/API) or feature extension. 81 | - Bug fixes. 82 | - Correct wrong implementation from theory. 83 | - Improved compatibility or accessibility. 84 | - Refactoring. 85 | 86 | ## Rules 87 | 88 | ### Issue 89 | 90 | - **Versions:** 91 | - Make sure you’re on the latest version. 92 | - Try older versions. 93 | - Try switching up dependency versions. 94 | - **Search:** Search the project’s [issues](https://github.com/black7375/Fluid-Size/issues) to make sure it's not a known issue. 95 | 96 | ### Coding style 97 | 98 | - **Indent:** 2 spaces for indentation rather than tabs. 99 | - **Columns:** Fit `80`~`100` columns as much as possible. 100 | 101 | ### Commit 102 | 103 | - **Meaningfully:**: It doesn't make meaningless commits. 104 | - **One per task:** It's difficult to distinguish when various tasks are mixed. 105 | - **Often:** Codes may corrupt during large changes. 106 | - **Build Check:** Check if SCSS can be compiled with the `npm run build` command. 107 | 108 | ### Commit Message 109 | 110 | For intuitive recognition, I [put a **prefix**](https://github.com/black7375/Fluid-Size/commits/master). 111 | - `Add:` Add feature or enhanced. 112 | - `Fix:` Bug fix or change default values. 113 | - `Clean:` Refactoring. 114 | - `Doc:` Update docs. 115 | - `Feature:` Milestone, The versioning scheme we use is [SemVer](https://semver.org/). (Maintainer decides, do not pull request.) 116 | 117 | ### Pull request 118 | 119 | - **Doc:** Update the [README.md](https://github.com/black7375/Fluid-Size/blob/master/README.md) and [Wiki:API](https://github.com/black7375/fluid-size/wiki/API) with details of changes to the interface, this includes new environment variables, exposed ports, useful file locations and container parameters. 120 | - **Issue:** We recommend that you open the issue first to discuss the changes with the owner of this repository. 121 | 122 | ### License 123 | 124 | **Any contributions you make will be under the MIT Software License** 125 | 126 | In short, when you submit code changes, your submissions are understood to be under the same [MIT License](https://choosealicense.com/licenses/mit/) that covers the project. 127 | Feel free to contact the maintainers if that's a concern. 128 | 129 | **Reference specification** 130 | 131 | Even if you copy the code snippet, it is recommended that you leave a link. 132 | 133 | ## References 134 | 135 | - [Good-CONTRIBUTING.md-template](https://gist.github.com/PurpleBooth/b24679402957c63ec426) 136 | - [Contributing to Transcriptase](https://gist.github.com/briandk/3d2e8b3ec8daf5a27a62) 137 | - [contributing-template](https://github.com/nayafia/contributing-template/blob/master/CONTRIBUTING-template.md) 138 | - [Contributing to Open Source Projects](https://www.contribution-guide.org/) 139 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 BlaCk_Void 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fluid Size 2 | 3 | [![GitHub Workflow CI Status](https://img.shields.io/github/workflow/status/black7375/Fluid-Size/CI)](https://github.com/black7375/Fluid-Size/actions?query=workflow%3ACI) 4 | [![GitHub Workflow Publishing Status](https://img.shields.io/github/workflow/status/black7375/Fluid-Size/Publishing?label=Publishing)](https://github.com/black7375/Fluid-Size/actions?query=workflow%3APublishing) 5 | [![npm](https://img.shields.io/npm/v/fluid-size?color=%23CC3534&logo=npm)](https://www.npmjs.com/package/fluid-size) 6 | [![gpr](https://img.shields.io/github/v/release/black7375/Fluid-Size?color=%23117FFF&label=GPR&logo=github)](https://github.com/black7375/Fluid-Size/packages/336258) 7 | [![jsDelivr_Hits](https://img.shields.io/jsdelivr/npm/hm/fluid-size?color=FF5627&label=jsDelivr&logo=jsDelivr&logoColor=FF5627)](https://www.jsdelivr.com/package/npm/fluid-size) 8 | 9 | ![Fluid-Size](https://raw.githubusercontent.com/black7375/Fluid-Size/resource/resource/Fluid-Size.png) 10 | 11 | :triangular_ruler::iphone::computer::desktop_computer: A method of fluidly resizing in various devices based on [`visual angle`](https://en.wikipedia.org/wiki/Visual_angle). (with SASS) :revolving_hearts: :eyes: 12 | 13 | Get away from the effects of devices' ***distance***, ***size***, and ***resolution***!! 14 | 15 | ![fluid-font-size](https://user-images.githubusercontent.com/25581533/82766346-d8f63900-9e0d-11ea-9b3b-ceabd7832e4b.png) 16 | - [Demo(Codepen)](https://codepen.io/black7375/pen/xxZoyow?editors=1100) 17 | - [Demo(Simple ToDo App)](https://black7375.github.io/React-RxJS-Todo/) 18 | 19 | ## Advantages 20 | 21 | [Wiki:Comparison](https://github.com/black7375/Fluid-Size/wiki/Comparison) 22 | 23 | - Easy 24 | - Provides the `fit size` for each device 25 | - Resized `fluidly` between each device 26 | - Compatible with [include-media](https://github.com/eduardoboucas/include-media) 27 | 28 | ## How to Use? 29 | 30 | ### Install 31 | 32 | ```shell 33 | ## Yarn 34 | yarn add fluid-size 35 | 36 | ## NPM 37 | npm install fluid-size 38 | 39 | ## Github Repository 40 | npm install @black7375/fluid-size 41 | ``` 42 | 43 | ### Import 44 | 45 | ```scss 46 | @import '~fluid-size/fluid-size'; 47 | ``` 48 | 49 | ### Usage 50 | 51 | Just use the name of the [API](https://github.com/black7375/fluid-size/wiki/API) with `@include`!! 52 | 53 | ```scss 54 | tag { 55 | @include property($size); 56 | } 57 | ``` 58 | 59 | **Example** 60 | 61 | You can use the regular CSS as it is. 62 | There are no restrictions. [Ver 1.5.0 will patch for `%`, `num`] 63 | ```scss 64 | // Only Single Value 65 | body { 66 | @include font-size(16px); // Countable Value => Calculated 67 | @include text-indent(inherit); // Uncalculated Value => Passed 68 | } 69 | 70 | // List Value 71 | body { 72 | @include font-size(16px !important); // with Uncountable Value 73 | @include text-indent(5em hanging each-line); // with Multiple Uncountable Values 74 | @include margin(-3px 1% 0 auto); // with Mixed Value 75 | } 76 | ``` 77 | 78 | **Converted Sample** 79 | 80 | ```scss 81 | // Code 82 | body { 83 | @include font-size(16px); 84 | } 85 | 86 | /** Tentative Result 87 | * INFO 88 | * Basis Angle: min angle device(Tablet) 89 | * 90 | * SIZES 91 | * Default: 16px; 92 | * Phone: about 18.75px; 93 | * Tablet: about 16px; 94 | * Laptop: about 16.73px; 95 | * Desktop: about 17.56px; 96 | * High-Desktop: about 20.82px; 97 | */ 98 | 99 | // Result 100 | body { // Default 101 | font-size: 1rem; 102 | } 103 | 104 | @media (min-width: 480px) { // Phone ~ Tablet 105 | body { 106 | font-size: calc(-0.9504790795vw + 1.4567984055rem); 107 | } 108 | } 109 | 110 | @media (min-width: 768px) { // Tablet ~ Laptop 111 | body { 112 | font-size: calc(0.1404102228vw + 0.9331715404rem); 113 | } 114 | } 115 | 116 | @media (min-width: 1280px) { // Laptop ~ Desktop 117 | body { 118 | font-size: calc(0.1306874648vw + 0.9409497468rem); 119 | } 120 | } 121 | 122 | @media (min-width: 1920px) { // Desktop ~ High-Desktop, Keep going. 123 | body { 124 | font-size: calc(0.5082290299vw + 0.4878998687rem); 125 | } 126 | } 127 | ``` 128 | 129 | ### Options 130 | 131 | [Wiki:API(Options)](https://github.com/black7375/fluid-size/wiki/API#options) 132 | 133 | Options consist of global and scoped options. 134 | 135 | - **Global Option:** Setting it as a `variable` changes the default value of the whole. 136 | - **Scoped Option:** It is provided as an argument(`map` type) to the function, and when used, applies only to the current value. 137 | 138 | ```scss 139 | // Global Option 140 | $option1: value1; 141 | $option2: value2; 142 | 143 | // Scoped Option 144 | tag { 145 | @include property($size, $max-size); 146 | // or 147 | @include property($size, (option1: value1, option2: value2)); 148 | } 149 | ``` 150 | 151 | You can customize resizing method, result's unit, min or max size, ..etc. 152 | 153 | **Converted Sample** 154 | 155 | ```scss 156 | // Code 157 | body { 158 | @include font-size(16px !important, (unit: px, max: 25px)); 159 | } 160 | 161 | // Result 162 | body { // Default 163 | font-size: 16px !important; 164 | } 165 | 166 | @media (min-width: 480px) { // Phone ~ Tablet 167 | body { 168 | font-size: calc(-0.95048vw + 23.30877px) !important; 169 | } 170 | } 171 | 172 | @media (min-width: 768px) { // Tablet ~ Laptop 173 | body { 174 | font-size: calc(0.14041vw + 14.93074px) !important; 175 | } 176 | } 177 | 178 | @media (min-width: 1280px) { // Laptop ~ Desktop 179 | body { 180 | font-size: calc(0.13069vw + 15.0552px) !important; 181 | } 182 | } 183 | 184 | @media (min-width: 1920px) { // Desktop ~ High-Desktop, Keep going. 185 | body { 186 | font-size: calc(0.50823vw + 7.8064px) !important; 187 | } 188 | } 189 | 190 | @media (min-width: 3383px) { // Reach maximum size 191 | body { 192 | font-size: 25px !important; 193 | } 194 | } 195 | ``` 196 | 197 | ## Learn More 198 | [Wiki:The theory of font size and readability](https://github.com/black7375/fluid-size/wiki/The-theory-of-font-size-and-readability) 199 | 200 | ### Principle 201 | 202 | Use visual angles to determine the `fit size`(I called) for each device. 203 | 204 | ![view-distance](https://user-images.githubusercontent.com/25581533/82766340-cc71e080-9e0d-11ea-8268-7c965e6544c0.jpeg) 205 | source: [Legibility: how to make text convenient to read](https://uxdesign.cc/legibility-how-to-make-text-convenient-to-read-7f96b84bd8af) 206 | 207 | ### Calculation process 208 | 209 | 1. Size specification 210 | 2. Measure the `angle` to be viewed on the [reference device](https://github.com/black7375/Fluid-Size/wiki/API#2-device) 211 | 3. Generate a `fit size` for each device based on the `angle` 212 | 4. Provides **real-time resizing(fluidity)** for mid-range devices 213 | 214 | ## Browser Supports 215 | 216 | - [CSS3 Media Queries](https://caniuse.com/#feat=css-mediaqueries) 217 | - [`vw` unit](https://caniuse.com/#feat=mdn-css_types_length_vw)([Viewport units](https://caniuse.com/#feat=viewport-units)) 218 | - [`calc()`](https://caniuse.com/#feat=calc) 219 | 220 | ## F&A 221 | - CSS decimal place: [Are the decimal places in a CSS width respected?](https://stackoverflow.com/questions/4308989/are-the-decimal-places-in-a-css-width-respected) 222 | -------------------------------------------------------------------------------- /_break-points.scss: -------------------------------------------------------------------------------- 1 | // @import 'utils'; 2 | 3 | // ** Break Points ************************************************************* 4 | $small-phone-width: 320px !default; 5 | $small-phone-height: 586px !default; 6 | $phone-width: 360px !default; 7 | $phone-height: 640px !default; 8 | $high-phone-width: 414px !default; 9 | $high-phone-height: 896px !default; 10 | 11 | $tablet-width: 768px !default; 12 | $tablet-height: 1024px !default; 13 | $high-tablet-width: 1024px !default; 14 | $high-tablet-height: 1366px !default; 15 | 16 | $laptop-width: 1280px !default; 17 | $laptop-height: 720px !default; 18 | $high-laptop-width: 1600px !default; 19 | $high-laptop-height: 900px !default; 20 | 21 | $desktop-width: 1920px !default; 22 | $desktop-height: 1080px !default; 23 | $high-desktop-width: 3840px !default; 24 | $high-desktop-height: 2160px !default; 25 | 26 | $breakpoints: ( // px 27 | small-phone: $small-phone-width, 28 | phone: $phone-width, 29 | high-phone: $high-phone-width, 30 | tablet: $tablet-width, 31 | high-tablet: $high-tablet-width, 32 | laptop: $laptop-width, 33 | high-laptop: $high-laptop-width, 34 | desktop: $desktop-width, 35 | high-desktop: $high-desktop-width 36 | ) !default; 37 | 38 | $breakpoints-height: ( // px 39 | small-phone: $small-phone-height, 40 | phone: $phone-height, 41 | high-phone: $high-phone-height, 42 | tablet: $tablet-height, 43 | high-tablet: $high-tablet-height, 44 | laptop: $laptop-height, 45 | high-laptop: $high-laptop-height, 46 | desktop: $desktop-height, 47 | high-desktop: $high-desktop-height 48 | ) !default; 49 | 50 | $screen-sizes: ( // inch 51 | small-phone: 4, 52 | phone: 4.7, 53 | high-phone: 5.8, 54 | tablet: 9.7, 55 | high-tablet: 12.9, 56 | laptop: 13, 57 | high-laptop: 14, 58 | desktop: 24, 59 | high-desktop: 32 60 | ) !default; 61 | 62 | $screen-distances: ( // 10cm 63 | small-phone: 3, 64 | phone: 3, 65 | high-phone: 3, 66 | tablet: 4, 67 | high-tablet: 4, 68 | laptop: 5, 69 | high-laptop: 5, 70 | desktop: 6, 71 | high-desktop: 6 72 | ) !default; 73 | 74 | // Alias 75 | $small-phone: $small-phone-width !default; 76 | $phone: $phone-width !default; 77 | $high-phone: $high-phone-width !default; 78 | $tablet: $tablet-width !default; 79 | $high-tablet: $high-tablet-width !default; 80 | $laptop: $laptop-width !default; 81 | $high-laptop: $high-laptop-width !default; 82 | $desktop: $desktop-width !default; 83 | $high-desktop: $high-desktop-width !default; 84 | 85 | // == Validation =============================================================== 86 | $CACHED-BREAKPOINTS: $breakpoints !default; 87 | $CACHED-BREAKPOINTS-HEIGHT: $breakpoints-height !default; 88 | $CACHED-SCREEN-SIZES: $screen-sizes !default; 89 | $CACHED-SCREEN-DISTANCES: $screen-distances !default; 90 | 91 | @function check-breakpoints($criteria-name, $others-name, $criteria-keys, $others-keys) { 92 | $validate-breakpoints: true; 93 | 94 | $criteria-length: length($criteria-keys); 95 | $others-length: length($others-keys); 96 | @each $i in range($others-length) { 97 | $other-name: nth($others-name, $i); 98 | $other-keys: nth($others-keys, $i); 99 | $other-length: length($other-keys); 100 | 101 | // Length Check 102 | $validate-breakpoints: $validate-breakpoints and $criteria-length == $other-length; 103 | @if not $validate-breakpoints { 104 | @error "#{$criteria-name}'s length doesn't same #{$other-name}'s length"; 105 | } 106 | 107 | // Key Check 108 | $validate-breakpoints: $validate-breakpoints and $criteria-keys == $other-keys; 109 | @if not $validate-breakpoints { 110 | @error "#{$criteria-name}'s keys doesn't same #{$other-name}'s keys"; 111 | } 112 | } 113 | @return $validate-breakpoints; 114 | } 115 | 116 | // -- Interface -- 117 | @function validate-breakpoints() { 118 | $validate-breakpoints: true; 119 | 120 | // Check Cache 121 | @if not ($CACHED-BREAKPOINTS == $breakpoints and $CACHED-BREAKPOINTS-HEIGHT == $breakpoints-height and 122 | $CACHED-SCREEN-SIZES == $screen-sizes and $CACHED-SCREEN-DISTANCES == $screen-distances) { 123 | $break-keys: map($breakpoints $breakpoints-height $screen-sizes $screen-distances, 124 | map-keys list-sort); 125 | $breakpoints-keys: nth($break-keys, 1); 126 | $breakpoints-height-keys: nth($break-keys, 2); 127 | $screen-sizes-keys: nth($break-keys, 3); 128 | $screen-distances-keys: nth($break-keys, 4); 129 | 130 | // Check Validate 131 | $others-name: "$breakpoints-height" "$screen-sizes" "$screen-distances"; 132 | $others-keys: $breakpoints-height-keys $screen-sizes-keys $screen-distances-keys; 133 | $validate-breakpoints: check-breakpoints("$breakpoints", $others-name, $breakpoints-keys, $others-keys); 134 | 135 | // Cache Update 136 | $CACHED-BREAKPOINTS: $breakpoints !global; 137 | $CACHED-BREAKPOINTS-HEIGHT: $breakpoints-height !global; 138 | $CACHED-SCREEN-SIZES: $screen-sizes !global; 139 | $CACHED-SCREEN-DISTANCES: $screen-distances !global; 140 | } 141 | 142 | @return $validate-breakpoints; 143 | } 144 | -------------------------------------------------------------------------------- /_fluid-size.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /*** 3 | * /$$$$$$ /$$ 4 | * /$$__ $$|__/ 5 | * ______ _ _ _ | $$ \__/ /$$ /$$$$$$$$ /$$$$$$ 6 | * | ____| | (_) | | | $$$$$$ | $$|____ /$$/ /$$__ $$ 7 | * | |___ | |_ _ _ __| | \____ $$| $$ /$$$$/ | $$$$$$$$ 8 | * | ___|| | | | | |/ _` | /$$ \ $$| $$ /$$__/ | $$_____/ 9 | * | | | | |_| | | (_| | | $$$$$$/| $$ /$$$$$$$$| $$$$$$$ 10 | * |_| |_|\__,_|_|\__,_| \______/ |__/|________/ \_______/ 11 | * 12 | **/ 13 | @import 'break-points'; 14 | @import '~include-media/dist/include-media'; 15 | @import '~mathsass/dist/math'; 16 | @import '~sass-unitconverter/unitconverter'; 17 | @import 'utils'; 18 | @import 'others'; 19 | @import 'options'; 20 | 21 | // ** Fluid Size *************************************************************** 22 | $FIRST-KEY: default !default; 23 | $FIRST-BREAK: 0px !default; 24 | 25 | @function zip-responsive() { 26 | @return zip( 27 | map-values($screen-distances), map-values($screen-sizes ), 28 | map-values($breakpoints ), map-values($breakpoints-height) 29 | ); 30 | } 31 | 32 | // == Fit Size ================================================================= 33 | // Based on Theory 34 | // https://github.com/black7375/Fluid-Size/wiki/The-theory-of-font-size-and-readability 35 | @function calc-ppi($screen-width, $screen-height, $screen-size) { 36 | @return sqrt(pow($screen-width, 2) + pow($screen-height, 2)) / $screen-size; 37 | } 38 | 39 | // -- Measure Angle ------------------------------------------------------------ 40 | @function calc-dependency($value) { 41 | $screen-distance: nth($value, 1) * 100; 42 | $screen-size: nth($value, 2); 43 | $screen-width: num(nth($value, 3)); 44 | $screen-height: num(nth($value, 4)); 45 | 46 | $ppi: calc-ppi($screen-width, $screen-height, $screen-size); 47 | $dependent-value: $screen-distance * $ppi; 48 | @return $dependent-value; 49 | } 50 | 51 | @function calc-angle($size, $options) { 52 | // String, Color value passing(Ex. !important, black, white, #111111 ...ETC) 53 | @if not is-calcable($size) { 54 | @return if(is-num($size), #{$size}num, $size); 55 | } 56 | 57 | $size: num(px($size)); 58 | $device: get-option($options, device); 59 | $target: null; 60 | 61 | @if contain('min' 'max', $device) { // Will look min/max 62 | $values: zip-responsive(); 63 | @each $value in $values { 64 | $dependent-value: calc-dependency($value); 65 | 66 | @if $device == 'min' { 67 | @if (($target == null) or ($target > $dependent-value)) { 68 | $target: $dependent-value; 69 | } 70 | } 71 | @if $device == 'max' { 72 | @if (($target == null) or ($target < $dependent-value)) { 73 | $target: $dependent-value; 74 | } 75 | } 76 | } 77 | } 78 | @else { // based on Device's Key 79 | $value: list(map-get($screen-distances, $device), map-get($screen-sizes, $device), 80 | map-get($breakpoints, $device), map-get($breakpoints-height, $device)); 81 | $target: calc-dependency($value); 82 | } 83 | 84 | $angle: $size * 54 / $target; 85 | $visual-angle: atan($angle) * (10800 / $PI); 86 | @return count-round($visual-angle, 2); 87 | } 88 | @function calc-angles($sizes, $options) { 89 | $angles: (); 90 | @each $size in $sizes { 91 | $angles: append($angles, calc-angle($size, $options)); 92 | } 93 | @return $angles; 94 | } 95 | 96 | // -- Generate Fit Size -------------------------------------------------------- 97 | @function convert-visual($visual-angle) { 98 | // if origin $size type is num 99 | // => ${$size}num 100 | // Return it to its original type. 101 | @if is-str($visual-angle) { 102 | $str-start: str-length($visual-angle) - 2; 103 | $is-number: str-slice($visual-angle, $str-start) == "num"; 104 | @return if($is-number, num($visual-angle), $visual-angle); 105 | } 106 | @else { 107 | @return $visual-angle; 108 | } 109 | } 110 | 111 | // Calc Fit Size 112 | @function calc-size($visual-angle) { 113 | $check: is-num($visual-angle); 114 | $values: zip-responsive(); 115 | $break-sizes: (); 116 | 117 | @each $value in $values { 118 | @if $check { // If Calc able 119 | $screen-distance: nth($value, 1) * 100; 120 | $screen-size: nth($value, 2); 121 | $screen-width: num(nth($value, 3)); 122 | $screen-height: num(nth($value, 4)); 123 | 124 | $ppi: calc-ppi($screen-width, $screen-height, $screen-size); 125 | $angle: tan($PI * $visual-angle / 10800); 126 | $size: $screen-distance * $angle * $ppi / 54; 127 | 128 | $size: px($size, (callback: null)); 129 | $break-sizes: append($break-sizes, ($size)); 130 | } 131 | @else { // Can't Calc: passed 132 | $visual-angle: convert-visual($visual-angle); 133 | $break-sizes: append($break-sizes, ($visual-angle)); 134 | } 135 | } 136 | 137 | @return $break-sizes; 138 | } 139 | 140 | @function fit-size($sizes, $options: empty-map()) { 141 | // Each Fit Size 142 | $visual-angle: calc-angles($sizes, $options); 143 | $scaled-sizes: map($visual-angle, calc-size, $separator: comma); 144 | 145 | @return if(is-list($sizes), call(zip, $scaled-sizes...), $scaled-sizes); 146 | } 147 | 148 | // == Fluid ==================================================================== 149 | @function size-break($function, $fluid-unit, $now-sizes, $next-sizes, 150 | $now-break, $next-break, $max-size: null) { 151 | // unit convert 152 | $now-sizes: to-unit-data($now-sizes, $fluid-unit); 153 | $next-sizes: to-unit-data($next-sizes, $fluid-unit); 154 | $now-break: to-unit-data($now-break, $fluid-unit); 155 | $next-break: to-unit-data($next-break, $fluid-unit); 156 | $max-size: to-unit-data($max-size, $fluid-unit); 157 | 158 | // Each function args 159 | $check-function: $function == 'fluid-size'; 160 | $args: if($check-function, 161 | list($now-sizes, $next-sizes, $now-break, $next-break), 162 | list($now-sizes, $next-sizes, $max-size, $now-break, $next-break)); 163 | 164 | // Mapping 165 | $results: (); 166 | $each-sizes: zip($now-sizes, $next-sizes); 167 | @each $start-size, $end-size in $each-sizes { 168 | $result: null; 169 | @if is-len($start-size) and is-len($end-size) { 170 | $args: replace-nth($args, 1, $start-size); 171 | $args: replace-nth($args, 2, $end-size ); 172 | 173 | $result: map($args, $function, 'list'); 174 | } 175 | @else { 176 | $result: if($check-function, $start-size, $next-break); 177 | } 178 | $results: append($results, $result); 179 | } 180 | @return $results; 181 | } 182 | 183 | // -- Option::Mode ------------------------------------------------------------- 184 | // -- Mode: Fluid -- 185 | // https://www.madebymike.com.au/writing/fluid-type-calc-examples/ 186 | @function fluid-rate($start-size, $end-size, $min-screen, $max-screen) { 187 | @return ($end-size - $start-size) / ($max-screen - $min-screen); 188 | } 189 | @function fluid-basic-size($start-size, $min-screen, $rate) { 190 | @return $start-size - $rate * $min-screen; 191 | } 192 | 193 | @function fluid-size($start-size, $end-size, $min-screen, $max-screen) { 194 | @if $start-size == $end-size { 195 | @return $start-size; 196 | } 197 | // Get based values 198 | $rate: fluid-rate($start-size, $end-size, $min-screen, $max-screen); 199 | $basic-size: fluid-basic-size($start-size, $min-screen, $rate); 200 | 201 | // Decide Sign 202 | $sign: "+"; 203 | @if ($basic-size < 0) { 204 | $sign: "-"; 205 | $basic-size: abs($basic-size); 206 | } 207 | 208 | // Conbine 209 | @return calc(#{$rate*100}vw #{$sign} #{$basic-size}); 210 | } 211 | @function fluid-sizes($now-sizes, $next-sizes, $now-break, $next-break, $fluid-unit: px) { 212 | $fluid-sizes: size-break(fluid-size, $fluid-unit, 213 | $now-sizes, $next-sizes, $now-break, $next-break); 214 | @return $fluid-sizes; 215 | } 216 | 217 | // -- Mode: VW-Only -- 218 | @function vw-sizes($now-sizes, $now-break) { 219 | @return to-unit-data($now-sizes, vw, (width: $now-break)); 220 | } 221 | 222 | // -- Option::Limit ------------------------------------------------------------ 223 | // -- Limit with Mode -- 224 | @function fluid-limit-break($start-size, $end-size, $max-size, 225 | $min-screen, $max-screen) { 226 | @if($start-size == $end-size) { 227 | @return $min-screen; 228 | } 229 | // Simulate Fluid Size 230 | $rate: fluid-rate($start-size, $end-size, $min-screen, $max-screen); 231 | $basic-size: fluid-basic-size($start-size, $min-screen, $rate); 232 | 233 | // Calc Limit Point 234 | $limit-break: ($max-size - $basic-size) / $rate; 235 | $limit-break: count-round($limit-break, 1); 236 | @return if($limit-break <= 0px, 0px, $limit-break); 237 | } 238 | @function fluid-limit-breaks($now-sizes, $next-sizes, $max-size, 239 | $now-break, $next-break, $fluid-unit: px) { 240 | $limit-breaks: size-break(fluid-limit-break, $fluid-unit, 241 | $now-sizes, $next-sizes, $now-break, $next-break, $max-size); 242 | @return $limit-breaks; 243 | } 244 | 245 | @function vw-limit-break($now-vw, $max-size) { 246 | $now-vw: num($now-vw); 247 | $max-size: px($max-size); 248 | 249 | // Calc Limit Point 250 | $limit-break: ($max-size / $now-vw) * 100; 251 | $limit-break: count-round($limit-break, 1); 252 | @return if($limit-break <= 0px, 0px, $limit-break); 253 | } 254 | @function vw-limit-breaks($now-sizes, $max-size, $now-break, $next-break) { 255 | $basic-sizes: vw-sizes($now-sizes, $now-break); 256 | $limit-breaks: (); 257 | 258 | @each $basic-size in $basic-sizes { 259 | $limit-break: if(is-vw($basic-size) and $basic-size != 0vw, 260 | vw-limit-break($basic-size, $max-size), 261 | $next-break); 262 | $limit-breaks: append($limit-breaks, $limit-break); 263 | } 264 | @return $limit-breaks; 265 | } 266 | 267 | // -- Get Limit Types -- 268 | @function fluid-limit-type($first, $last, $now-break, $next-break, 269 | $limit-break, $type: 'size') { 270 | @if $type == 'break' { // only Limit: break 271 | @if $first { 272 | @return 'pass'; 273 | } 274 | 275 | @if $limit-break <= $now-break { 276 | @return 'substitution'; 277 | } 278 | @if $now-break < $limit-break and $limit-break < $next-break { 279 | @return 'add'; 280 | } 281 | } 282 | 283 | @if $last and $now-break < $limit-break { // Reach Max Size 284 | @return 'add'; 285 | } 286 | @else { 287 | @return 'pass'; 288 | } 289 | } 290 | @function fluid-limit-types($now-key, $last-key, $now-break, $next-break, 291 | $limit-breaks, $type: 'size') { 292 | $first: $now-key == $FIRST-KEY; 293 | $last: $now-key == $last-key; 294 | 295 | $limit-types: (); 296 | @each $limit-break in $limit-breaks { 297 | $limit-type: fluid-limit-type($first, $last, $now-break, $next-break, $limit-break, $type); 298 | $limit-types: append($limit-types, $limit-type); 299 | } 300 | @return $limit-types; 301 | } 302 | 303 | // -- Limit -- 304 | @mixin fluid-add-break($property, $next-sizes, $fluid-sizes, $max-size, 305 | $now-break, $next-break, $limit-breaks, $limit-types, 306 | $class, $is-iframe, $sorted-index, $increase) { 307 | $decrease: not $increase; 308 | 309 | // now-break: increase => pass, decrease => subtitution 310 | @if $decrease { 311 | @each $i in range($limit-breaks) { 312 | $index: nth($sorted-index, $i); 313 | @if nth($limit-types, $index) == 'add' { 314 | $fluid-sizes: replace-size($fluid-sizes, $index, $max-size); 315 | } 316 | } 317 | } 318 | @include fluid-option-media($class, $now-break, $is-iframe) { 319 | #{$property}: $fluid-sizes; 320 | } 321 | 322 | // add-break: increase => subtitution, decrease => create fluid-size(max, next-size) 323 | $new-fluid-size: null; // only use decrease 324 | $prev-fluid-sizes: null; 325 | $break-size: length($limit-breaks); 326 | @each $i in range($limit-breaks) { 327 | $now-index: nth($sorted-index, $i); 328 | $next-index: if($i < $break-size, nth($sorted-index, $i + 1), null); 329 | 330 | $now-type: nth($limit-types, $now-index); 331 | $now-limit: nth($limit-breaks, $now-index); 332 | $next-size: if(is-null($next-sizes), null, nth($next-sizes, $now-index )); 333 | $next-limit: if(is-null($next-index), null, nth($limit-breaks, $next-index)); 334 | 335 | // now-limit == next-limit => only substitution 336 | // next-limit is null || now-limit != next-limit => substitution && apply 337 | @if $now-type == 'add' { 338 | $first: $i == 1; 339 | $last: is-null($next-limit); 340 | $continuous: $now-limit == $next-limit; 341 | 342 | @if $decrease and ($first or not $last or not $continuous) { 343 | $new-fluid-size: fluid-size($max-size, $next-size, $now-limit, $next-break); 344 | } 345 | 346 | @if $continuous { 347 | $subtitue-size: if($increase, $max-size, $new-fluid-size); 348 | $fluid-sizes: replace-size($fluid-sizes, $now-index, $subtitue-size); 349 | } 350 | @else { 351 | $prev-fluid-sizes: $fluid-sizes; 352 | $subtitue-size: if($increase, $max-size, $new-fluid-size); 353 | $fluid-sizes: replace-size($fluid-sizes, $now-index, $subtitue-size); 354 | 355 | @if $last or $fluid-sizes != $prev-fluid-sizes { 356 | @include fluid-option-media($class, $now-limit, $is-iframe) { 357 | #{$property}: $fluid-sizes; 358 | } 359 | } 360 | } 361 | } 362 | } 363 | } 364 | 365 | @mixin fluid-media-limit($property, $now-sizes, $next-sizes, $fluid-sizes, 366 | $max-size, $now-break, $next-break, $limit-breaks, 367 | $limit-types, $is-fluid, $class, $is-iframe) { 368 | $exist-sub: contain($limit-types, 'substitution'); 369 | $exist-add: contain($limit-types, 'add'); 370 | $sorted-index: null; 371 | @if (not $exist-sub) and (not $exist-add) { 372 | //all pass 373 | @include fluid-option-media($class, $now-break, $is-iframe) { 374 | #{$property}: $fluid-sizes; 375 | } 376 | } 377 | @else { 378 | $sorted-index: list-sort-index($limit-breaks); 379 | } 380 | 381 | // subtitution 382 | @if $exist-sub { 383 | @each $i in range($limit-breaks) { 384 | $index: nth($sorted-index, $i); 385 | @if nth($limit-types, $index) == 'substitution' { 386 | $fluid-sizes: replace-size($fluid-sizes, $index, $max-size); 387 | } 388 | } 389 | @include fluid-option-media($class, $now-break, $is-iframe) { 390 | #{$property}: $fluid-sizes; 391 | } 392 | } 393 | 394 | // add break 395 | @if $exist-add { 396 | $increase: not $is-fluid or check-sizes($now-sizes, $next-sizes); 397 | 398 | // increase: next-size > now-size > max-size 399 | // decrease: next-size > max-size > now-size 400 | 401 | // increase => now-break(pass), add-break(subtitution) 402 | // decrease => now-break(subtitution), add-break(create fluide-size) 403 | @include fluid-add-break($property, $next-sizes, $fluid-sizes, $max-size, 404 | $now-break, $next-break, $limit-breaks, $limit-types, 405 | $class, $is-iframe, $sorted-index, $increase); 406 | } 407 | } 408 | 409 | // -- Option::Class ------------------------------------------------------------ 410 | @mixin fluid-class-media($fls-class, $break) { 411 | @if $fls-class == true { 412 | @include media(">=#{$break}") { 413 | .fluid-class &, 414 | &.fluid-class { 415 | @content; 416 | } 417 | } 418 | } 419 | @else { 420 | @include media(">=#{$break}") { 421 | @content; 422 | } 423 | } 424 | } 425 | 426 | // -- Option ------------------------------------------------------------------- 427 | @mixin fluid-option-media($fls-class, $break, $is-iframe) { 428 | @include fluid-class-media($fls-class, $break) { 429 | @content; 430 | 431 | @if $is-iframe { 432 | @include safari-iframe-resize-fix; 433 | } 434 | } 435 | } 436 | 437 | 438 | // == Medias =================================================================== 439 | @mixin fluid-media-apply($property, $fit-sizes, $fluid-breakpoints, $i, $last-key, 440 | $fluid-mode, $fluid-unit, $breakunit, 441 | $min-size, $max-size, $limit, $class, $iframe-fix) { 442 | // Get key and Sizes 443 | $now-key: map-nth($fluid-breakpoints, $i); 444 | $next-key: map-nth($fluid-breakpoints, $i + 1); 445 | 446 | $now-sizes: map-get($fit-sizes, $now-key ); 447 | $next-sizes: map-get($fit-sizes, $next-key); 448 | $now-break: map-get($fluid-breakpoints, $now-key ); 449 | $next-break: map-get($fluid-breakpoints, $next-key); 450 | 451 | $first: $now-key == $FIRST-KEY; 452 | $prev-key: if($first, null, map-nth($fluid-breakpoints, $i - 1)); 453 | $prev-sizes: if(is-null($prev-key), null, map-get($fit-sizes, $prev-key)); 454 | 455 | // Apply Options 456 | $is-fit: $fluid-mode == 'fit'; 457 | $is-fluid: $fluid-mode == 'fluid'; 458 | $is-vw: $fluid-mode == 'vw-only'; 459 | $is-last: if($is-fluid, $now-key == $last-key, $next-key == $last-key); 460 | $is-iframe: (not $is-fit) and $iframe-fix; 461 | 462 | @if (not is-null($min-size) or not is-null($max-size)) and 463 | ($is-fit or $limit == 'size') { 464 | $now-sizes: limit-sizes($now-sizes, $min-size, $max-size); 465 | $next-sizes: limit-sizes($next-sizes, $min-size, $max-size); 466 | } 467 | 468 | // for fluid mode 469 | $limit-breaks: null; 470 | $limit-types: null; 471 | $fluid-sizes: null; 472 | @if not $is-fit and not is-null($max-size) { 473 | $limit-breaks: if($is-fluid, 474 | fluid-limit-breaks($now-sizes, $next-sizes, $max-size, 475 | $now-break, $next-break), 476 | vw-limit-breaks($now-sizes, $max-size, $now-break, $next-break)); 477 | $limit-types: fluid-limit-types($now-key, $last-key, $now-break, $next-break, 478 | $limit-breaks, $limit); 479 | $max-size: to-unit-data($max-size, $fluid-unit); 480 | } 481 | 482 | // Set size 483 | $now-sizes: to-unit-data($now-sizes, $fluid-unit); 484 | $next-sizes: to-unit-data($next-sizes, $fluid-unit); 485 | @if not $is-fit { 486 | $fluid-sizes: if($is-fluid, 487 | fluid-sizes($now-sizes, $next-sizes, $now-break, $next-break, $fluid-unit), 488 | vw-sizes($now-sizes, $now-break)); 489 | } 490 | 491 | // Set Break Units 492 | $now-break: to-unit-data($now-break, $breakunit); 493 | $next-break: to-unit-data($next-break, $breakunit); 494 | 495 | // Apply Media 496 | $not-continuous: $now-sizes != $prev-sizes; 497 | 498 | @if $first { 499 | #{$property}: $now-sizes; 500 | } 501 | @else if not $is-fit and not is-null($max-size) and $not-continuous { 502 | @include fluid-media-limit($property, $now-sizes, $next-sizes, $fluid-sizes, 503 | $max-size, $now-break, $next-break, $limit-breaks, 504 | $limit-types, $is-fluid, $class, $is-iframe); 505 | 506 | @if $is-vw and $is-last and $now-sizes != $next-sizes { 507 | $limit-breaks: vw-limit-breaks($next-sizes, $max-size, $next-break, $next-break); 508 | $limit-types: fluid-limit-types($next-key, $last-key, $next-break, $next-break, 509 | $limit-breaks, $limit); 510 | $fluid-sizes: vw-sizes($next-sizes, $next-break); 511 | $last-sizes: null; 512 | 513 | @include fluid-media-limit($property, $next-sizes, $last-sizes, $fluid-sizes, 514 | $max-size, $next-break, $next-break, $limit-breaks, 515 | $limit-types, $is-fluid, $class, $is-iframe); 516 | } 517 | } 518 | @else if $not-continuous { 519 | $now-values: if(not $is-fit, $fluid-sizes, $now-sizes); 520 | @include fluid-option-media($class, $now-break, $is-iframe) { 521 | #{$property}: $now-values; 522 | } 523 | 524 | // Last at fit, vw-only mode 525 | $next-values: if($is-fit, $next-sizes, vw-sizes($next-sizes, $next-break)); 526 | @if not $is-fluid and $is-last and $now-sizes != $next-sizes { 527 | @include fluid-option-media($class, $next-break, $is-iframe) { 528 | #{$property}: $next-values; 529 | } 530 | } 531 | } 532 | } 533 | 534 | @mixin fluid-media($property, $devices-sizes, $options: empty-map()) { 535 | // Basics 536 | $fit-sizes: to-unit-data($devices-sizes, px); 537 | $fluid-breakpoints: map-merge(($FIRST-KEY: $FIRST-BREAK), to-unit-map($breakpoints, px)); 538 | $fluid-breakpoints: map-sort-values($fluid-breakpoints); 539 | @if not map-has-key($fit-sizes, $FIRST-KEY) { 540 | $default-map: ($FIRST-KEY: $DEAFULT-SIZE); 541 | $fit-sizes: map-merge($default-map, $fit-sizes); 542 | } 543 | $fluid-basics: ($property, $fit-sizes, $fluid-breakpoints); 544 | 545 | // Get Options 546 | $fluid-mode: get-option($options, mode); 547 | $fluid-unit: get-option($options, unit); 548 | $breakunit: get-option($options, breakunit); 549 | $min-size: get-option($options, min); 550 | $max-size: get-option($options, max); 551 | $limit: get-option($options, limit); 552 | $class: get-option($options, class); 553 | $iframe-fix: get-option($options, iframe-fix); 554 | $fluid-options: ($fluid-mode, $fluid-unit, $breakunit, 555 | $min-size, $max-size, $limit, $class, $iframe-fix); 556 | 557 | // Apply media 558 | $last-size: length($fluid-breakpoints) - 1; 559 | $last-key: map-nth($fluid-breakpoints, if($fluid-mode == 'fluid', 560 | $last-size, $last-size + 1)); 561 | @each $i in range($last-size) { 562 | $fluid-context: ($i, $last-key); 563 | $args: flatten($fluid-basics, $fluid-context, $fluid-options); 564 | 565 | @include fluid-media-apply($args...); 566 | } 567 | } 568 | 569 | // -- Wrapper -- 570 | @mixin fluid($property, $sizes, $options: empty-map(), $type: 'font') { 571 | // Preprocessing for $options 572 | @if not is-map($options) { 573 | $options: (max-size: $options); 574 | } 575 | @if get-option($options, unit) == each and $type == 'font' { 576 | $options: map-merge($options, (unit: rem)); 577 | } 578 | @else if get-option($options, unit) == each and $type == 'box' { 579 | $options: map-merge($options, (unit: px)); 580 | } 581 | 582 | // Validate 583 | $validate-breakpoints: validate-breakpoints(); 584 | $validate-options: validate-options($options); 585 | 586 | // Set Unit Scoped Option 587 | $temp-root: $root-font-size; 588 | $temp-base: $base-font-size; 589 | $root-font-size: get-option($options, root-size) !global; 590 | $base-font-size: get-option($options, base-size) !global; 591 | 592 | // Single value to List processing 593 | @if not is-list($sizes) { 594 | $sizes: ($sizes, ); 595 | } 596 | 597 | $fit-sizes: fit-size($sizes, $options); 598 | $keys: join($FIRST-KEY, map-keys($breakpoints)); 599 | $values: join(($sizes,), $fit-sizes); 600 | $devices-sizes: to-map($keys, $values); 601 | 602 | @include fluid-media($property, $devices-sizes, $options); 603 | 604 | // Set to Original 605 | $root-font-size: $temp-root !global; 606 | $base-font-size: $temp-base !global; 607 | } 608 | 609 | // == Interface ================================================================ 610 | // -- Font -- 611 | @mixin font-size($sizes, $options: empty-map()) { 612 | @include fluid(font-size, $sizes, $options); 613 | } 614 | @mixin line-height($sizes, $options: empty-map()) { 615 | @include fluid(line-height, $sizes, $options); 616 | } 617 | @mixin text-indent($sizes, $options: empty-map()) { 618 | @include fluid(text-indent, $sizes, $options); 619 | } 620 | @mixin letter-spacing($sizes, $options: empty-map()) { 621 | @include fluid(letter-spacing, $sizes, $options); 622 | } 623 | @mixin word-spacing($sizes, $options: empty-map()) { 624 | @include fluid(word-spacing, $sizes, $options); 625 | } 626 | @mixin tab-size($sizes, $options: empty-map()) { 627 | @include fluid(tab-size, $sizes, $options); 628 | } 629 | 630 | // -- Box -- 631 | @mixin width($sizes, $options: empty-map()) { 632 | @include fluid(width, $sizes, $options, 'box'); 633 | } 634 | @mixin height($sizes, $options: empty-map()) { 635 | @include fluid(height, $sizes, $options, 'box'); 636 | } 637 | @mixin border-width($sizes, $options: empty-map()) { 638 | @include fluid(border-width, $sizes, $options, 'box'); 639 | } 640 | @mixin margin($sizes, $options: empty-map()) { 641 | @include fluid(margin, $sizes, $options, 'box'); 642 | } 643 | @mixin margin-top($sizes, $options: empty-map()) { 644 | @include fluid(margin-top, $sizes, $options, 'box'); 645 | } 646 | @mixin margin-bottom($sizes, $options: empty-map()) { 647 | @include fluid(margin-bottom, $sizes, $options, 'box'); 648 | } 649 | @mixin margin-left($sizes, $options: empty-map()) { 650 | @include fluid(margin-left, $sizes, $options, 'box'); 651 | } 652 | @mixin margin-right($sizes, $options: empty-map()) { 653 | @include fluid(margin-right, $sizes, $options, 'box'); 654 | } 655 | @mixin padding($sizes, $options: empty-map()) { 656 | @include fluid(padding, $sizes, $options, 'box'); 657 | } 658 | @mixin padding-top($sizes, $options: empty-map()) { 659 | @include fluid(padding-top, $sizes, $options, 'box'); 660 | } 661 | @mixin padding-bottom($sizes, $options: empty-map()) { 662 | @include fluid(padding-bottom, $sizes, $options, 'box'); 663 | } 664 | @mixin padding-left($sizes, $options: empty-map()) { 665 | @include fluid(padding-left, $sizes, $options, 'box'); 666 | } 667 | @mixin padding-right($sizes, $options: empty-map()) { 668 | @include fluid(padding-right, $sizes, $options, 'box'); 669 | } 670 | -------------------------------------------------------------------------------- /_options.scss: -------------------------------------------------------------------------------- 1 | // @import '~sass-unitconverter/unitconverter'; 2 | // @import 'utils'; 3 | // @import 'break-points'; 4 | 5 | // ** Options ****************************************************************** 6 | // == Global Options =========================================================== 7 | $fls-mode: fluid !default; // fluid or fit, vw-only 8 | $fls-device: min !default; // min or max, devices's key(Ex. phone, tablet, ...) 9 | $fls-unit: each !default; // each or units(Ex. px, em, rem, ...) 10 | $fls-breakunit: px !default; // units(Ex. px, em, rem, ...) 11 | $fls-min: null !default; // null or length(Ex. 20px, 20pt, ...) 12 | $fls-max: null !default; // null or length(Ex. 20px, 20pt, ...) 13 | $fls-limit: size !default; // size or break 14 | $fls-class: false !default; // false or true 15 | $fls-safari-iframe-fix: false !default; // false or true 16 | 17 | // == Mapping ================================================================== 18 | // -- Mapping with API Name -- 19 | @function global-options() { 20 | $global-options: ( 21 | // Global Name. Global Variable. 22 | mode: $fls-mode, 23 | device: $fls-device, 24 | unit: $fls-unit, 25 | breakunit: $fls-breakunit, 26 | min: $fls-min, 27 | max: $fls-max, 28 | limit: $fls-limit, 29 | class: $fls-class, 30 | iframe-fix: $fls-safari-iframe-fix, 31 | 32 | // Unit Converter 33 | root-size: $root-font-size, 34 | base-size: $base-font-size, 35 | ); 36 | @return $global-options; 37 | } 38 | 39 | // -- Mapping with Scoped Options -- 40 | $fluid-options-map: ( 41 | // Scoped Name. Global Name. 42 | mode: mode, 43 | device: device, 44 | unit: unit, 45 | breakunit: breakunit, 46 | min: min, 47 | min-size: min, 48 | max: max, 49 | max-size: max, 50 | limit: limit, 51 | class: class, 52 | iframe: iframe-fix, 53 | iframe-fix: iframe-fix, 54 | safari-iframe-fix: iframe-fix, 55 | 56 | // Unit Converter 57 | root: root-size, 58 | root-size: root-size, 59 | size-root: root-size, 60 | base: base-size, 61 | base-size: base-size, 62 | size-base: base-size, 63 | ); 64 | 65 | // -- Mapping with Types -- 66 | $unit-types: map-keys(n-units(0)) !default; 67 | $bool-types: true false; 68 | @function fluid-types() { 69 | $fluid-types: ( 70 | // Global Name. Types. 71 | mode: fluid fit vw-only, 72 | device: join(min max, map-keys($breakpoints)), 73 | unit: join(each, $unit-types), 74 | breakunit: $unit-types, 75 | min: join(null, $unit-types), 76 | max: join(null, $unit-types), 77 | limit: size break, 78 | class: $bool-types, 79 | iframe-fix: $bool-types, 80 | 81 | // Unit Converter 82 | root-size: $unit-types, 83 | base-size: $unit-types, 84 | ); 85 | @return $fluid-types; 86 | } 87 | 88 | // == Get ====================================================================== 89 | @function scoped-convert($scoped-options) { 90 | // Option Empty 91 | @if length($scoped-options) == 0 { 92 | @return (); 93 | } 94 | 95 | // Replace key to Global Name 96 | $result: (); 97 | @each $key, $value in $scoped-options { 98 | $global-key: map-get($fluid-options-map, $key); 99 | $result: map-merge($result, ($global-key: $value)); 100 | } 101 | @return $result; 102 | } 103 | 104 | @function name-convert($name) { 105 | $result: (); 106 | @if is-list($name) { 107 | @each $key in $name { 108 | $global-key: map-get($fluid-options-map, $key); 109 | $result: append($result, $global-key); 110 | } 111 | } 112 | @else { 113 | $result: map-get($fluid-options-map, $name); 114 | } 115 | @return $result; 116 | } 117 | 118 | @function get-option-value($scoped, $name) { 119 | @return if(map-has-key($scoped, $name), 120 | map-get($scoped, $name), 121 | map-get(global-options(), $name)); 122 | } 123 | 124 | // -- Interface -- 125 | @function get-option($options: (), $name: all) { 126 | $scoped: scoped-convert($options); 127 | $result: (); 128 | 129 | @if $name == all { 130 | $result: map-merge(global-options(), $scoped); 131 | } 132 | @else { 133 | $name: name-convert($name); 134 | 135 | @if is-list($name) { 136 | @each $option in $name { 137 | $value: get-option-value($scoped, $option); 138 | $result: append($result, $value); 139 | } 140 | } 141 | @else { 142 | $result: get-option-value($scoped, $name); 143 | } 144 | } 145 | @return $result; 146 | } 147 | 148 | // == Validation =============================================================== 149 | $CACHED-GLOBAL-OPTIONS: global-options() !default; 150 | $CACHED-FLUID-OPTIONS: $fluid-options-map !default; 151 | $CACHED-OPTIONS-KEYS: () !default; 152 | $CACHED-ALL-OPTIONS: global-options() !default; 153 | $CACHED-FLUID-TYPES: fluid-types() !default; 154 | 155 | @function check-option($criteria-name, $target-name, $target-type, $option-criteria, $options) { 156 | @each $option in $options { 157 | @if not contain($option-criteria, $option) { 158 | @error "#{$target-name}'s #{$target-type}, #{$option} doesn't exist at #{$criteria-name}"; 159 | @return false; 160 | } 161 | } 162 | @return true; 163 | } 164 | 165 | // -- Interface -- 166 | @function validate-options($options: ()) { 167 | $validate-mapping: false; 168 | $validate-keys: false; 169 | $validate-types: true; 170 | 171 | // - Check api name - 172 | // Mapping check 173 | $global-options: global-options(); 174 | $mapping-names: map-values($fluid-options-map); 175 | @if not ($CACHED-GLOBAL-OPTIONS == $global-options and 176 | $CACHED-FLUID-OPTIONS == $fluid-options-map) { 177 | $validate-mapping: check-option("global-options", "$fluid-options-map", "global name", 178 | $global-options, $mapping-names); 179 | 180 | $CACHED-GLOBAL-OPTIONS: $global-options !global; 181 | $CACHED-FLUID-OPTIONS: $fluid-options-map !global; 182 | } 183 | 184 | // Exist key check 185 | $options-keys: map-keys($options); 186 | @if not contain($CACHED-OPTIONS-KEYS, $options-keys) { 187 | $validate-keys: check-option("$fluid-options-map key", "$options", "key", 188 | $fluid-options-map, $options-keys); 189 | 190 | $CACHED-OPTIONS-KEYS: map-merge($CACHED-OPTIONS-KEYS, ($options-keys: true)) !global; 191 | } 192 | 193 | // - Check each type - 194 | $all-options: get-option($options); 195 | $all-options-keys: map-keys($all-options); 196 | 197 | $fluid-types: fluid-types(); 198 | @if not ($CACHED-ALL-OPTIONS == $all-options and $CACHED-FLUID-TYPES == $fluid-types) { 199 | @each $all-options-key in $all-options-keys { 200 | $fluid-type: map-get($fluid-types, $all-options-key); 201 | $option-value: map-get($all-options, $all-options-key); 202 | 203 | // Case min or max 204 | @if contain('min' 'max', $all-options-key) { 205 | $option-value: if(is-null($option-value), $option-value, get-unit($option-value)); 206 | } 207 | 208 | // Case root-size or base-size 209 | @if contain('root-size' 'base-size', $all-options-key) { 210 | $option-value: get-unit($option-value); 211 | } 212 | 213 | // Case not contain in types 214 | @if not contain($fluid-type, $option-value) { 215 | @error "$options's value #{$option-value} doesn't exist at fluid-types"; 216 | $validate-types: false; 217 | } 218 | } 219 | 220 | $CACHED-ALL-OPTIONS: $all-options !global; 221 | $CACHED-FLUID-TYPES: $fluid-types !global; 222 | } 223 | 224 | @return $validate-mapping and $validate-keys and $validate-types; 225 | } 226 | -------------------------------------------------------------------------------- /_others.scss: -------------------------------------------------------------------------------- 1 | // ** Others ******************************************************************* 2 | // -- Body Width Fix -- 3 | // Account for difference between 100vw and 100% when scroll bars are included on page. 4 | // Center and trims the offset caused in most browsers by scroll bars when true 5 | // https://github.com/jdillick/fluid-typography#vw-quirks--fixes 6 | @mixin body-width-fix() { 7 | @media screen { 8 | width: 100vw; 9 | margin-left: calc((100% - 100vw) / 2); 10 | overflow-x: hidden; 11 | } 12 | } 13 | 14 | $CACHED-BODY-WIDTH-FIX: false !default; // Don't change it!! 15 | @mixin fluid-width-fix($is-width-fix) { 16 | @if $is-width-fix and not $CACHED-BODY-WIDTH-FIX { 17 | $CACHED-BODY-WIDTH-FIX: true !global; // Only 1 apply 18 | 19 | html { 20 | @include body-width-fix(); 21 | } 22 | } 23 | } 24 | 25 | // -- Body Width Fix -- 26 | // Safari doesn't resize its values in an iframe if the iframe is resized. 27 | // https://github.com/twbs/rfs#class-boolean 28 | @mixin safari-iframe-resize-fix() { 29 | min-width: 0vw; 30 | } 31 | -------------------------------------------------------------------------------- /_utils.scss: -------------------------------------------------------------------------------- 1 | // @import '~mathsass/dist/math'; 2 | // @import '~sass-unitconverter/unitconverter'; 3 | 4 | // ** Utils ******************************************************************** 5 | // == Data Structure =========================================================== 6 | // -- List --------------------------------------------------------------------- 7 | // -- To List -- 8 | @function range($values) { 9 | $iter-num: 0; 10 | $range-list: (); 11 | 12 | // Get Length 13 | @if is-num($values) { 14 | $iter-num: $values; 15 | } 16 | @else { 17 | $iter-num: length($values); 18 | } 19 | 20 | // Append of count 21 | @for $i from 1 through $iter-num { 22 | $range-list: append($range-list, $i); 23 | } 24 | @return $range-list; 25 | } 26 | 27 | @function repeat($value, $size) { 28 | $repeat-list:(); 29 | @each $i in range($size) { 30 | $repeat-list: append($repeat-list, $value); 31 | } 32 | @return $repeat-list; 33 | } 34 | 35 | @function list($args...) { 36 | $list: (); 37 | @each $arg in $args { 38 | $list: append($list, $arg); 39 | } 40 | @return $list; 41 | } 42 | 43 | @function flatten($list...) { 44 | $newList: (); 45 | @each $value in $list { 46 | @if is-list($value) { 47 | // One Depth Flatten 48 | @each $deepV in $value { 49 | $newList: append($newList, $deepV); 50 | } 51 | } 52 | @else { 53 | $newList: append($newList, $value); 54 | } 55 | } 56 | @return $newList; 57 | } 58 | 59 | // -- At List -- 60 | @function contain($values, $item, $type: 'key') { 61 | @if is-list($values) { 62 | @return index($values, $item) != null; 63 | } 64 | @else if is-map($values) { 65 | @if $type == 'key' { 66 | @return map-has-key($values, $item); 67 | } 68 | @else if $type == 'value' { 69 | @return contain(map-values($values), $item); 70 | } 71 | @else if $type == 'map' { 72 | @return not is-null(map-index($values, $item, 'map')); 73 | } 74 | } 75 | } 76 | 77 | // https://hugogiraudel.com/2013/08/08/advanced-sass-list-functions/ 78 | @function replace-nth($list, $index, $value) { 79 | $result: null; 80 | 81 | @if not is-num($index) { 82 | @warn "$index: #{quote($index)} is not a number for `replace-nth`."; 83 | } @else if $index == 0 { 84 | @warn "List index 0 must be a non-zero integer for `replace-nth`."; 85 | } @else if abs($index) > length($list) { 86 | @warn "List index is #{$index} but list is only #{length($list)} item long for `replace-nth`."; 87 | } @else { 88 | $result: (); 89 | $index: if($index < 0, length($list) + $index + 1, $index); 90 | 91 | @for $i from 1 through length($list) { 92 | @if $i == $index { 93 | $result: append($result, $value); 94 | } @else { 95 | $result: append($result, nth($list, $i)); 96 | } 97 | } 98 | } 99 | 100 | @return $result; 101 | } 102 | 103 | // https://gist.github.com/Jakobud/ec056b52f3673cc369dc97f2c2428424 104 | @function list-remove($list, $index) { 105 | $newList: (); 106 | @for $i from 1 through length($list) { 107 | @if $i != $index { 108 | $newList: append($newList, nth($list,$i), 'space'); 109 | } 110 | } 111 | @return $newList; 112 | } 113 | 114 | // -- Map ---------------------------------------------------------------------- 115 | @function map-index($map, $key-value, $type: 'key') { 116 | @if $type == 'key' { 117 | @return index(map-keys($map), $key-value); 118 | } 119 | @else if $type == 'value' { 120 | @return index(map-values($map), $key-value); 121 | } 122 | @else if $type == 'map' { 123 | @return index($map, to-list($key-value)); 124 | } 125 | } 126 | 127 | @function map-nth($map, $n, $type: 'key') { 128 | @if $type == 'key' { 129 | @return nth(nth($map, $n), 1); 130 | } 131 | @else if $type == 'value' { 132 | @return nth(nth($map, $n), 2); 133 | } 134 | } 135 | 136 | // -- Convert ------------------------------------------------------------------ 137 | // https://hugogiraudel.com/2014/04/28/casting-map-into-list/ 138 | @function to-list($value, $keep: 'both') { 139 | $keep: if(index('keys' 'values', $keep), $keep, 'both'); 140 | 141 | @if is-map($value) { 142 | $keys: (); 143 | $values: (); 144 | 145 | // Each Sets 146 | @each $key, $val in $value { 147 | $keys: append($keys, $key); 148 | $values: append($values, $val); 149 | } 150 | 151 | // Types of list 152 | @if $keep == 'keys' { 153 | @return $keys; 154 | } @else if $keep == 'values' { 155 | @return $values; 156 | } @else { 157 | @return zip($keys, $values); 158 | } 159 | } 160 | 161 | @return if(not is-list($value), ($value,), $value); 162 | } 163 | 164 | @function to-map($keys, $values) { 165 | $map: (); 166 | 167 | @each $i in range($keys) { 168 | $map-value: (nth($keys, $i): nth($values, $i)); 169 | $map: map-merge($map, $map-value); 170 | } 171 | @return $map; 172 | } 173 | 174 | @function empty-map($x: x) { 175 | @return map-remove(($x:$x), $x); 176 | } 177 | 178 | // -- Sort --------------------------------------------------------------------- 179 | // https://gist.github.com/Jakobud/744b98b629abe018766f6d506a2e92ae 180 | // https://css-tricks.com/snippets/sass/sorting-function/ 181 | @function sort-compare($a, $b) { 182 | @if is-num($a, false) and is-num($b, false) { 183 | @return $a < $b; 184 | } 185 | 186 | // If string 187 | $order: "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" 188 | "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" 189 | "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" 190 | "u" "v" "w" "x" "y" "z"; 191 | 192 | $a: to-lower-case($a + unquote("")); 193 | $b: to-lower-case($b + unquote("")); 194 | 195 | @for $i from 1 through min(str-length($a), str-length($b)) { 196 | $char-a: str-slice($a, $i, $i); 197 | $char-b: str-slice($b, $i, $i); 198 | 199 | // Check 200 | @if $char-a and $char-b and index($order, $char-a) != index($order, $char-b) { 201 | @return index($order, $char-a) < index($order, $char-b); 202 | } 203 | } 204 | 205 | @return str-length($a) < str-length($b); 206 | } 207 | 208 | // -- List -- 209 | @function list-sort($list) { 210 | $sortedlist: (); 211 | @while length($list) > 0 { 212 | $value: nth($list,1); 213 | @each $item in $list { 214 | @if sort-compare($item, $value) { 215 | $value: $item; 216 | } 217 | } 218 | $sortedlist: append($sortedlist, $value, 'space'); 219 | $list: list-remove($list, index($list, $value)); 220 | } 221 | @return $sortedlist; 222 | } 223 | 224 | @function list-sort-index($list) { 225 | $sortedMap: (); 226 | @each $i in range($list) { 227 | $value: nth($list, $i); 228 | @if map-has-key($sortedMap, $value) { 229 | $other-i: map-get($sortedMap, $value); 230 | $i: if(is-list($other-i), append($other-i, $i), ($other-i, $i)); 231 | } 232 | $sortedMap: map-merge($sortedMap, ($value: $i)); 233 | } 234 | 235 | $sortedMap: map-sort($sortedMap); 236 | @return flatten(map-values($sortedMap)...); 237 | } 238 | 239 | // -- Map -- 240 | // https://gist.github.com/Jakobud/a0ac11e80a1de453cd86f0d3fc0a1410 241 | @function map-sort($map) { 242 | $keys: list-sort(map-keys($map)); 243 | $sortedMap: (); 244 | @each $key in $keys { 245 | $sortedMap: map-merge($sortedMap, ($key: map-get($map, $key))); 246 | } 247 | @return $sortedMap; 248 | } 249 | 250 | @function map-sort-values($map) { 251 | // Transform map to zipped list 252 | $keys: (); 253 | $values: (); 254 | 255 | @each $key, $val in $map { 256 | $keys: append($keys, $key); 257 | $values: append($values, $val); 258 | } 259 | 260 | $list: zip($keys, $values); 261 | 262 | $sortedMap: (); 263 | @while length($list) > 0 { 264 | 265 | // Find smallest pair 266 | $smallestPair: nth($list, 1); 267 | @each $pair in $list { 268 | $value: nth($pair, 2); 269 | $smallestValue: nth($smallestPair, 2); 270 | @if $value < $smallestValue { 271 | $smallestPair: $pair; 272 | } 273 | } 274 | 275 | // Add smallest pair to sorted map 276 | $key: nth($smallestPair, 1); 277 | $value: nth($smallestPair, 2); 278 | $sortedMap: map-merge($sortedMap, ($key: $value)); 279 | 280 | // Remove from list smallest pair 281 | $smallestPairIndex: index($list, $smallestPair); 282 | $newList: (); 283 | @for $i from 1 through length($list) { 284 | @if $i != $smallestPairIndex { 285 | $newList: append($newList, nth($list, $i), "space"); 286 | } 287 | } 288 | $list: $newList; 289 | } 290 | 291 | @return $sortedMap; 292 | } 293 | 294 | // == Math ===================================================================== 295 | @function count-round($number, $count: 1) { 296 | $digit: pow(10, $count - 1); 297 | 298 | $upper: $number * $digit; 299 | $round: floor($upper + 0.5); 300 | @return $round / $digit; 301 | } 302 | 303 | // == Other ==================================================================== 304 | // -- High Order --------------------------------------------------------------- 305 | @function do($value, $functions...) { 306 | $result: $value; 307 | $functions: flatten($functions...); 308 | // Call each functions 309 | @each $function in $functions { 310 | $result: call($function, $result); 311 | } 312 | @return $result; 313 | } 314 | 315 | @function do-list($value, $functions...) { 316 | $result: $value; 317 | $functions: flatten($functions...); 318 | // Call each functions with full args 319 | @each $function in $functions { 320 | $result: call($function, $result...); 321 | } 322 | @return $result; 323 | } 324 | 325 | @function map($values, $function, $type: 'value', $separator: auto) { 326 | @if is-list($values) { 327 | $newList: (); 328 | @if $type == 'list' { 329 | $newList: do-list($values, $function); 330 | } 331 | @else if $type == 'value' { 332 | @each $value in $values { 333 | $newList: append($newList, do($value, $function), $separator); 334 | } 335 | } 336 | @return $newList; 337 | } 338 | @else if is-map($values) { 339 | $newMap: (); 340 | @each $key, $value in $values { 341 | $newMap: map-merge($newMap, if($type == 'key', 342 | (do($key, $function): $value), 343 | ($key: do($value, $function)) 344 | )); 345 | } 346 | @return $newMap; 347 | } 348 | @else { 349 | @return do($values, $function); 350 | } 351 | } 352 | 353 | // -- Calcable ----------------------------------------------------------------- 354 | @function is-calcable($size) { 355 | // Pass Value 356 | // - String 357 | // font-size: 16px !important 358 | // text-indent: 5em hanging each-line 359 | // - Num 360 | // - Percent 361 | @return (is-len($size) and not is-pct($size)); 362 | } 363 | 364 | @function calcable-callback($input, $unit, $options) { 365 | @return is-calcable($input); 366 | } 367 | 368 | $check-callback: calcable-callback; 369 | 370 | // -- Size --------------------------------------------------------------------- 371 | @function limit-size($size, $min-size, $max-size) { 372 | @if not is-null($min-size) { 373 | $size: if($size < $min-size, $min-size, $size); 374 | } 375 | @if not is-null($max-size) { 376 | $size: if($size > $max-size, $max-size, $size); 377 | } 378 | 379 | @return $size; 380 | } 381 | @function limit-sizes($sizes, $min-size, $max-size) { 382 | $sizes: to-unit-data($sizes, px); 383 | $min-size: to-unit-data($min-size, px); 384 | $max-size: to-unit-data($max-size, px); 385 | 386 | $new-sizes: (); 387 | @each $size in $sizes { 388 | $new-size: if(is-calcable($size), limit-size($size, $min-size, $max-size), $size); 389 | $new-sizes: append($new-sizes, $new-size); 390 | } 391 | @return $new-sizes; 392 | } 393 | 394 | @function replace-size($sizes, $index, $subtitute-size) { 395 | $size: nth($sizes, $index); 396 | @return if(is-calcable($size) or is-calc($size), 397 | replace-nth($sizes, $index, $subtitute-size), $sizes); 398 | } 399 | 400 | @function check-sizes($sizesA, $sizesB) { 401 | $sizes: zip($sizesA, $sizesB); 402 | 403 | @each $sizeA, $sizeB in $sizes { 404 | @if is-calcable($sizeA) and is-calcable($sizeB) { 405 | @return $sizeA <= $sizeB; 406 | } 407 | } 408 | @return false; 409 | } 410 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluid-size", 3 | "description": "A method of fluidly resizing in response to various devices. (with SASS)", 4 | "version": "1.6.0", 5 | "author": "black7375", 6 | "license": "MIT", 7 | "keywords": [ 8 | "SASS", 9 | "SCSS", 10 | "Design", 11 | "Breakpoint", 12 | "Breakpoints", 13 | "Responsive", 14 | "media-queries" 15 | ], 16 | "main": "./_fluid-size.scss", 17 | "sass": "./_fluid-size.scss", 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/black7375/fluid-size.git" 21 | }, 22 | "bugs": { 23 | "url": "https://github.com/black7375/fluid-size/issues" 24 | }, 25 | "homepage": "https://github.com/black7375/fluid-size#readme", 26 | "scripts": { 27 | "build": "scss-bundle -c ./scss-bundle.config.json" 28 | }, 29 | "dependencies": { 30 | "include-media": "^1.4.9", 31 | "mathsass": "^0.11.0", 32 | "sass-unitconverter": "^2.5.2" 33 | }, 34 | "devDependencies": { 35 | "scss-bundle": "^3.1.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /resource/Fluid-Size.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/Fluid-Size.afphoto -------------------------------------------------------------------------------- /resource/Fluid-Size.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/Fluid-Size.png -------------------------------------------------------------------------------- /resource/README.md: -------------------------------------------------------------------------------- 1 | ## Icon 2 | 3 | ![Fluid-Size](https://raw.githubusercontent.com/black7375/Fluid-Size/resource/resource/Fluid-Size.png) 4 | 5 | ### Photo Editor Info 6 | 7 | - [Affity Photo](https://affinity.serif.com/en-gb/photo/): File extension `.afphoto` 8 | 9 | ### Font Info 10 | 11 | - `Fluid`: [Sandoll 청류](https://www.sandollcloud.com/font/Sandoll/505.html) `165pt` 12 | - `Size`: [Rix 프레임](https://www.sandollcloud.com/font/FontRix/1049.html) `210pt` 13 | 14 | ## Ascii Art Icon 15 | 16 | ```scss 17 | /*** 18 | * /$$$$$$ /$$ 19 | * /$$__ $$|__/ 20 | * ______ _ _ _ | $$ \__/ /$$ /$$$$$$$$ /$$$$$$ 21 | * | ____| | (_) | | | $$$$$$ | $$|____ /$$/ /$$__ $$ 22 | * | |___ | |_ _ _ __| | \____ $$| $$ /$$$$/ | $$$$$$$$ 23 | * | ___|| | | | | |/ _` | /$$ \ $$| $$ /$$__/ | $$_____/ 24 | * | | | | |_| | | (_| | | $$$$$$/| $$ /$$$$$$$$| $$$$$$$ 25 | * |_| |_|\__,_|_|\__,_| \______/ |__/|________/ \_______/ 26 | * 27 | **/ 28 | ``` 29 | 30 | ## Badges 31 | 32 | - ![GitHub Workflow CI Status](https://img.shields.io/github/workflow/status/black7375/Fluid-Size/CI): [Workflow CI](https://github.com/black7375/Fluid-Size/actions?query=workflow%3ACI) 33 | - ![GitHub Workflow Publishing Status](https://img.shields.io/github/workflow/status/black7375/Fluid-Size/Publishing?label=Publishing): [Workflow Publishing](https://github.com/black7375/Fluid-Size/actions?query=workflow%3APublishing) 34 | - ![NPM](https://img.shields.io/npm/v/fluid-size?color=%23CC3534&logo=npm): [NPM Registry](https://www.npmjs.com/package/fluid-size) 35 | - ![GPR](https://img.shields.io/github/v/release/black7375/Fluid-Size?color=%23117FFF&label=GPR&logo=github): [Github Package Registry](https://github.com/black7375/Fluid-Size/packages/336258) 36 | - ![jsDelivr_Hits](https://img.shields.io/jsdelivr/npm/hm/fluid-size?color=FF5627&label=jsDelivr&logo=jsDelivr&logoColor=FF5627): [jsDelivr](https://www.jsdelivr.com/package/npm/fluid-size) 37 | -------------------------------------------------------------------------------- /resource/font.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/font.ods -------------------------------------------------------------------------------- /resource/samples/Fluid_1.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_1.afphoto -------------------------------------------------------------------------------- /resource/samples/Fluid_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_1.png -------------------------------------------------------------------------------- /resource/samples/Fluid_2.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_2.afphoto -------------------------------------------------------------------------------- /resource/samples/Fluid_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_2.png -------------------------------------------------------------------------------- /resource/samples/Fluid_3.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_3.afphoto -------------------------------------------------------------------------------- /resource/samples/Fluid_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_3.png -------------------------------------------------------------------------------- /resource/samples/Fluid_4.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_4.afphoto -------------------------------------------------------------------------------- /resource/samples/Fluid_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_4.png -------------------------------------------------------------------------------- /resource/samples/Fluid_5.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_5.afphoto -------------------------------------------------------------------------------- /resource/samples/Fluid_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_5.png -------------------------------------------------------------------------------- /resource/samples/Fluid_6.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_6.afphoto -------------------------------------------------------------------------------- /resource/samples/Fluid_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Fluid_6.png -------------------------------------------------------------------------------- /resource/samples/README.md: -------------------------------------------------------------------------------- 1 | ## Fluid 2 | ### Sample1 3 | ![fluid1](https://raw.githubusercontent.com/black7375/Fluid-Size/master/resource/samples/Fluid_1.png) 4 | 5 | ### Sample2 6 | ![fluid2](https://raw.githubusercontent.com/black7375/Fluid-Size/master/resource/samples/Fluid_2.png) 7 | 8 | ### Sample3 9 | ![fluid3](https://raw.githubusercontent.com/black7375/Fluid-Size/master/resource/samples/Fluid_3.png) 10 | 11 | ### Sample4 12 | ![fluid4](https://raw.githubusercontent.com/black7375/Fluid-Size/master/resource/samples/Fluid_4.png) 13 | 14 | ### Sample5 15 | ![fluid5](https://raw.githubusercontent.com/black7375/Fluid-Size/master/resource/samples/Fluid_5.png) 16 | 17 | ### Sample6 18 | ![fluid6](https://raw.githubusercontent.com/black7375/Fluid-Size/master/resource/samples/Fluid_6.png) 19 | 20 | ## Size 21 | ### Sample1 22 | ![size1](https://raw.githubusercontent.com/black7375/Fluid-Size/resource/resource/samples/Size_1.png) 23 | 24 | ### Sample2 25 | ![size2](https://raw.githubusercontent.com/black7375/Fluid-Size/resource/resource/samples/Size_2.png) 26 | 27 | ### Sample3 28 | ![size3](https://raw.githubusercontent.com/black7375/Fluid-Size/resource/resource/samples/Size_3.png) 29 | 30 | ### Sample4 31 | ![size4](https://raw.githubusercontent.com/black7375/Fluid-Size/resource/resource/samples/Size_4.png) 32 | 33 | ### Sample5 34 | ![size5](https://raw.githubusercontent.com/black7375/Fluid-Size/resource/resource/samples/Size_5.png) 35 | 36 | ### Sample6 37 | ![size6](https://raw.githubusercontent.com/black7375/Fluid-Size/resource/resource/samples/Size_6.png) 38 | 39 | ### Sample7 40 | ![size7](https://raw.githubusercontent.com/black7375/Fluid-Size/resource/resource/samples/Size_7.png) 41 | 42 | ### Sample8 43 | ![size8](https://raw.githubusercontent.com/black7375/Fluid-Size/resource/resource/samples/Size_8.png) 44 | 45 | -------------------------------------------------------------------------------- /resource/samples/Size_1.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_1.afphoto -------------------------------------------------------------------------------- /resource/samples/Size_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_1.png -------------------------------------------------------------------------------- /resource/samples/Size_2.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_2.afphoto -------------------------------------------------------------------------------- /resource/samples/Size_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_2.png -------------------------------------------------------------------------------- /resource/samples/Size_3.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_3.afphoto -------------------------------------------------------------------------------- /resource/samples/Size_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_3.png -------------------------------------------------------------------------------- /resource/samples/Size_4.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_4.afphoto -------------------------------------------------------------------------------- /resource/samples/Size_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_4.png -------------------------------------------------------------------------------- /resource/samples/Size_5.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_5.afphoto -------------------------------------------------------------------------------- /resource/samples/Size_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_5.png -------------------------------------------------------------------------------- /resource/samples/Size_6.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_6.afphoto -------------------------------------------------------------------------------- /resource/samples/Size_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_6.png -------------------------------------------------------------------------------- /resource/samples/Size_7.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_7.afphoto -------------------------------------------------------------------------------- /resource/samples/Size_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_7.png -------------------------------------------------------------------------------- /resource/samples/Size_8.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_8.afphoto -------------------------------------------------------------------------------- /resource/samples/Size_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/black7375/Fluid-Size/d1a92be8063b3717ed1ebbe29a7e38f6f0f4b5a3/resource/samples/Size_8.png -------------------------------------------------------------------------------- /resource/tables/Interval.csv: -------------------------------------------------------------------------------- 1 | Number of semitones,"Intervals(Minor, Major, Perfect)",Short,Interval(Augmented or Diminished),Short,Alias,Short,Pitch Ratio(5-limit tuning),Decimal,Multiplier,Frequency(Hz) 2 | 0,Perfect unison,P1,Diminished second,d2,,,1:01,1,![2^{0 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{0%20\over%2012}),440 3 | 1,Minor second,m2,Augmented unison,A1,Semitone,S,16:15,1.067,![2^{1 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{1%20\over%2012}),466.16 4 | 2,Major second,M2,Diminished third,d3,Tone,T,9:08,1.125,![2^{2 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{2%20\over%2012}),493.88 5 | 3,Minor third,m3,Augmented second,A2,,,6:05,1.2,![2^{3 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{3%20\over%2012}),523.25 6 | 4,Major third,M3,Diminished fourth,d4,,,5:04,1.25,![2^{4 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{4%20\over%2012}),554.37 7 | 5,Perfect fourth,P4,Augmented third,A3,,,4:03,1.333,![2^{5 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{5%20\over%2012}),587.33 8 | 6,,,Diminished fifth / Augmented fourth,d5 / A4,Tritone,TT,45:32:00,1.414,![2^{6 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{6%20\over%2012}),622.25 9 | 7,Perfect fifth,P5,Diminished sixth,d6,,,3:02,1.5,![2^{7 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{7%20\over%2012}),659.26 10 | 8,Minor sixth,m6,Augmented fifth,A5,,,8:05,1.6,![2^{8 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{8%20\over%2012}),698.46 11 | 9,Major sixth,M6,Diminished seventh,d7,,,5:03,1.667,![2^{9 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{9%20\over%2012}),739.99 12 | 10,Minor seventh,m7,Augmented sixth,A6,,,16:09,1.778,![2^{10 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{10%20\over%2012}),783.99 13 | 11,Major seventh,M7,Diminished octave,d8,,,15:08,1.875,![2^{11 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{11%20\over%2012}),830.61 14 | 12,Perfect Octave,P8,Augmented seventh,A7,,,2:01,2,![2^{12 \over 12}](https://render.githubusercontent.com/render/math?math=\large%202^{12%20\over%2012}),880 15 | -------------------------------------------------------------------------------- /resource/tables/comparison.csv: -------------------------------------------------------------------------------- 1 | **Feature Group**,**Features**,**[Fluid Size](https://github.com/black7375/Fluid-Size)**,**[RFS](https://github.com/twbs/rfs)**,**[Fluid font-size](https://github.com/philippkuehn/fluid-font-size)**,**[Fluid Typography](https://github.com/jdillick/fluid-typography)**,**[FluidMS](https://github.com/csshugs/FluidMS)** 2 | **Main(3)**,**Fluid**,:heavy_check_mark:,:heavy_check_mark:,:heavy_check_mark:,:heavy_check_mark:,:heavy_check_mark: 3 | ,**Visual Angle**,:heavy_check_mark:,:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_multiplication_x: 4 | ,**Modular Scale**,:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_check_mark: 5 | **Option(16)**,**List Input**,:heavy_check_mark:,:warning: (Only `important`),:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_multiplication_x: 6 | ,**Global Options**,:heavy_check_mark:,:heavy_check_mark:,:warning: (Only `size ratio`),:heavy_check_mark:,:heavy_check_mark: 7 | ,**Scoped Options**,:heavy_check_mark:,:heavy_multiplication_x:,:heavy_check_mark:,:warning: (Only `max` size),":warning: (Only `line-height`, 'important')" 8 | ,**Device**,:heavy_check_mark:,":warning: (Use `size factor`, `max` width)",:warning: (Use `size ratio`),:heavy_check_mark:,":warning: (Only `min`, `max` width)" 9 | ,**Min Size**,:heavy_check_mark:,:heavy_check_mark:,:heavy_check_mark:,:heavy_multiplication_x:,:heavy_check_mark: 10 | ,**Max Size**,:heavy_check_mark:,:heavy_multiplication_x:,:heavy_check_mark:,:heavy_multiplication_x:,:heavy_check_mark: 11 | ,**Result Unit**,:heavy_check_mark:,:heavy_check_mark:,:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_multiplication_x: 12 | ,**Break Unit**,:heavy_multiplication_x:,:heavy_check_mark:,:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_multiplication_x: 13 | ,**Base Size**(`rem`),:warning: (Only global option),:heavy_check_mark:,:heavy_multiplication_x:,:heavy_check_mark:,:heavy_multiplication_x: 14 | ,**VW-Only**,:heavy_check_mark:,:heavy_multiplication_x:,:heavy_check_mark:,:heavy_multiplication_x:,:heavy_multiplication_x: 15 | ,**Size Limit**,:heavy_check_mark:,:warning: (Only `min` size),:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_multiplication_x: 16 | ,**Break Limit**,:heavy_check_mark:,:warning: (Only `max` width),:warning: (Only `max` width),:heavy_multiplication_x:,:warning: (Only `max` width) 17 | ,**Fallback**,:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_check_mark:,:warning: (Not static size),:heavy_multiplication_x: 18 | ,**Class**,:heavy_multiplication_x:,:heavy_check_mark:,:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_multiplication_x: 19 | ,**Multi Platform**,:heavy_multiplication_x:,":heavy_check_mark:(`sass`, `post css`, `less`, `stylus`)",:heavy_multiplication_x:,:heavy_multiplication_x:,:heavy_multiplication_x: 20 | ,**Miscellaneous**,**Count:** 1
- Fit Size Mode,"**Count:** 2
- Dimensional(`vw`, `vmin`)
- Safari Iframe Resize Fix",**Count:** 1
- [Polyfill](https://github.com/rodneyrehm/viewport-units-buggyfill) Fallback,**Count:** 3
- Body Width Fix
- Break Point To JSON
- Debug Layout,**Count:** 0 21 | -------------------------------------------------------------------------------- /resource/tables/scale.csv: -------------------------------------------------------------------------------- 1 | Scale,number of different pitch classes 2 | monotonic,1 3 | ditonic,2 4 | tritonic,3 5 | tetratonic,4 6 | pentatonic,5 7 | hexatonic,6 8 | heptatonic,7 9 | octatonic,8 10 | decatonic,10 11 | chromatic,12 12 | -------------------------------------------------------------------------------- /scss-bundle.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "bundlerOptions": { 3 | "entryFile": "./_fluid-size.scss", 4 | "rootDir": "./", 5 | "outFile": "./dist/_fluid-size.scss", 6 | "logLevel": "silent" 7 | } 8 | } --------------------------------------------------------------------------------