├── .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 | [](https://github.com/black7375/Fluid-Size/actions?query=workflow%3ACI)
4 | [](https://github.com/black7375/Fluid-Size/actions?query=workflow%3APublishing)
5 | [](https://www.npmjs.com/package/fluid-size)
6 | [](https://github.com/black7375/Fluid-Size/packages/336258)
7 | [](https://www.jsdelivr.com/package/npm/fluid-size)
8 |
9 | 
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 | 
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 | 
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 | 
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 | - : [Workflow CI](https://github.com/black7375/Fluid-Size/actions?query=workflow%3ACI)
33 | - : [Workflow Publishing](https://github.com/black7375/Fluid-Size/actions?query=workflow%3APublishing)
34 | - : [NPM Registry](https://www.npmjs.com/package/fluid-size)
35 | - : [Github Package Registry](https://github.com/black7375/Fluid-Size/packages/336258)
36 | - : [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 | 
4 |
5 | ### Sample2
6 | 
7 |
8 | ### Sample3
9 | 
10 |
11 | ### Sample4
12 | 
13 |
14 | ### Sample5
15 | 
16 |
17 | ### Sample6
18 | 
19 |
20 | ## Size
21 | ### Sample1
22 | 
23 |
24 | ### Sample2
25 | 
26 |
27 | ### Sample3
28 | 
29 |
30 | ### Sample4
31 | 
32 |
33 | ### Sample5
34 | 
35 |
36 | ### Sample6
37 | 
38 |
39 | ### Sample7
40 | 
41 |
42 | ### Sample8
43 | 
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,,440
3 | 1,Minor second,m2,Augmented unison,A1,Semitone,S,16:15,1.067,,466.16
4 | 2,Major second,M2,Diminished third,d3,Tone,T,9:08,1.125,,493.88
5 | 3,Minor third,m3,Augmented second,A2,,,6:05,1.2,,523.25
6 | 4,Major third,M3,Diminished fourth,d4,,,5:04,1.25,,554.37
7 | 5,Perfect fourth,P4,Augmented third,A3,,,4:03,1.333,,587.33
8 | 6,,,Diminished fifth / Augmented fourth,d5 / A4,Tritone,TT,45:32:00,1.414,,622.25
9 | 7,Perfect fifth,P5,Diminished sixth,d6,,,3:02,1.5,,659.26
10 | 8,Minor sixth,m6,Augmented fifth,A5,,,8:05,1.6,,698.46
11 | 9,Major sixth,M6,Diminished seventh,d7,,,5:03,1.667,,739.99
12 | 10,Minor seventh,m7,Augmented sixth,A6,,,16:09,1.778,,783.99
13 | 11,Major seventh,M7,Diminished octave,d8,,,15:08,1.875,,830.61
14 | 12,Perfect Octave,P8,Augmented seventh,A7,,,2:01,2,,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 | }
--------------------------------------------------------------------------------