@bitstack/ng-boundary 14.0.1-alpha.2 → 14.0.1-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +190 -36
- package/package.json +1 -1
- package/src/styles/_awd.scss +109 -0
- package/src/styles/_mixin.scss +107 -0
- package/src/styles/_responsive.scss +698 -0
- package/src/styles/_variables.scss +29 -0
- package/src/styles/index.scss +20 -0
- package/styles.scss +10 -0
package/README.md
CHANGED
|
@@ -1,63 +1,217 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @bitstack/ng-boundary
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A responsive boundary component for Angular applications with built-in orientation support and SCSS utilities for pixel-perfect responsive design.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- Responsive boundary container with automatic aspect ratio management
|
|
8
|
+
- Portrait and landscape orientation support with auto-detection
|
|
9
|
+
- CSS custom properties for responsive sizing
|
|
10
|
+
- Comprehensive SCSS utilities for responsive design
|
|
11
|
+
- Standalone component architecture (Angular 14+)
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
8
14
|
|
|
9
15
|
```bash
|
|
10
|
-
|
|
16
|
+
npm install @bitstack/ng-boundary
|
|
11
17
|
```
|
|
12
18
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### 1. Using the Component
|
|
22
|
+
|
|
23
|
+
Import and use the `BsBoundary` component in your Angular application:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { Component } from '@angular/core';
|
|
27
|
+
import { BsBoundary } from '@bitstack/ng-boundary';
|
|
28
|
+
|
|
29
|
+
@Component({
|
|
30
|
+
selector: 'app-root',
|
|
31
|
+
standalone: true,
|
|
32
|
+
imports: [BsBoundary],
|
|
33
|
+
template: `
|
|
34
|
+
<bs-boundary
|
|
35
|
+
[isDebug]="false"
|
|
36
|
+
[bgColor]="'transparent'"
|
|
37
|
+
[contentClickable]="true"
|
|
38
|
+
[orientationMode]="'auto'"
|
|
39
|
+
(afterBoundaryInit)="onBoundaryInit($event)"
|
|
40
|
+
(orientationChange)="onOrientationChange($event)">
|
|
41
|
+
<!-- Your content here -->
|
|
42
|
+
<div class="my-content">
|
|
43
|
+
Hello World
|
|
44
|
+
</div>
|
|
45
|
+
</bs-boundary>
|
|
46
|
+
`
|
|
47
|
+
})
|
|
48
|
+
export class AppComponent {
|
|
49
|
+
onBoundaryInit(boundary: ElementRef<HTMLDivElement>) {
|
|
50
|
+
console.log('Boundary initialized:', boundary);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
onOrientationChange(mode: 'portrait' | 'landscape') {
|
|
54
|
+
console.log('Orientation changed to:', mode);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
17
57
|
```
|
|
18
58
|
|
|
19
|
-
|
|
59
|
+
#### Component Inputs
|
|
20
60
|
|
|
21
|
-
|
|
61
|
+
- `isDebug`: (boolean) Enable debug mode with background color - default: `false`
|
|
62
|
+
- `bgColor`: (string) Background color for the boundary
|
|
63
|
+
- `contentClickable`: (boolean) Whether content is clickable - default: `true`
|
|
64
|
+
- `orientationMode`: ('auto' | 'portrait' | 'landscape') Orientation mode - default: `'auto'`
|
|
65
|
+
- `injectStyle`: (IInjectStyle) Custom styles to inject
|
|
22
66
|
|
|
23
|
-
|
|
24
|
-
ng build bitstack-ng-boundary
|
|
25
|
-
```
|
|
67
|
+
#### Component Outputs
|
|
26
68
|
|
|
27
|
-
|
|
69
|
+
- `afterBoundaryInit`: Emits after boundary initialization with ElementRef
|
|
70
|
+
- `orientationChange`: Emits when orientation changes
|
|
28
71
|
|
|
29
|
-
###
|
|
72
|
+
### 2. Using SCSS Utilities
|
|
30
73
|
|
|
31
|
-
|
|
74
|
+
The boundary component provides CSS custom properties that you can use with the included SCSS utilities:
|
|
32
75
|
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
cd dist/bitstack-ng-boundary
|
|
36
|
-
```
|
|
76
|
+
#### Import SCSS Utilities
|
|
37
77
|
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
npm publish
|
|
41
|
-
```
|
|
78
|
+
In your component SCSS file or global styles:
|
|
42
79
|
|
|
43
|
-
|
|
80
|
+
```scss
|
|
81
|
+
@use '@bitstack/ng-boundary/styles' as boundary;
|
|
44
82
|
|
|
45
|
-
|
|
83
|
+
.my-component {
|
|
84
|
+
// Use the px2vw function for responsive sizing
|
|
85
|
+
// This automatically adapts to portrait/landscape mode
|
|
86
|
+
width: boundary.px2vw(100);
|
|
87
|
+
height: boundary.px2vw(200);
|
|
88
|
+
padding: boundary.px2vw(20);
|
|
46
89
|
|
|
47
|
-
|
|
48
|
-
|
|
90
|
+
// Or use mixins for specific properties
|
|
91
|
+
@include boundary.width(100);
|
|
92
|
+
@include boundary.height(200);
|
|
93
|
+
@include boundary.padding-left(20);
|
|
94
|
+
}
|
|
49
95
|
```
|
|
50
96
|
|
|
51
|
-
|
|
97
|
+
#### Available SCSS Functions
|
|
98
|
+
|
|
99
|
+
- `px2vw($px)` - Converts px to responsive units based on boundary
|
|
100
|
+
- `px2vw-unbounded($px)` - Converts px to viewport units (not bounded)
|
|
101
|
+
- `vw($w)` - Returns viewport width unit (dvw or vw)
|
|
102
|
+
- `vh($h)` - Returns viewport height unit (dvh or vh)
|
|
103
|
+
|
|
104
|
+
#### Available SCSS Mixins
|
|
105
|
+
|
|
106
|
+
**Responsive sizing mixins:**
|
|
107
|
+
- `@include width($px)` - Set responsive width
|
|
108
|
+
- `@include height($px)` - Set responsive height
|
|
109
|
+
- `@include padding-left($px)` - Set responsive left padding
|
|
110
|
+
- `@include padding-right($px)` - Set responsive right padding
|
|
111
|
+
- `@include padding-top($px)` - Set responsive top padding
|
|
112
|
+
- `@include padding-bottom($px)` - Set responsive bottom padding
|
|
113
|
+
- `@include px2vw($property, $px)` - Set any property with responsive value
|
|
114
|
+
|
|
115
|
+
**Utility mixins:**
|
|
116
|
+
- `@include flexCenter` - Flex center alignment
|
|
117
|
+
- `@include hideScrollbar` - Hide scrollbars
|
|
118
|
+
- `@include bg-contain` - Background contain
|
|
119
|
+
- `@include bg-cover` - Background cover
|
|
120
|
+
- `@include text-center` - Center text
|
|
121
|
+
- `@include text-shadow($color)` - Text shadow
|
|
122
|
+
- `@include size($w, $h: $w)` - Set width and height
|
|
123
|
+
|
|
124
|
+
**Responsive breakpoint mixins:**
|
|
125
|
+
- `@include s { ... }` - Small devices and up
|
|
126
|
+
- `@include landscape { ... }` - Mobile landscape
|
|
127
|
+
- `@include portrait { ... }` - Mobile portrait
|
|
128
|
+
- `@include pc_landscape { ... }` - PC landscape
|
|
129
|
+
- `@include pc_portrait { ... }` - PC portrait
|
|
130
|
+
|
|
131
|
+
#### CSS Custom Properties
|
|
132
|
+
|
|
133
|
+
The boundary component sets these CSS variables that the SCSS utilities use:
|
|
134
|
+
|
|
135
|
+
- `--boundary-width` - Current boundary width
|
|
136
|
+
- `--boundary-height` - Current boundary height
|
|
137
|
+
- `--design-base-width` - Design base width (portrait: 540, landscape: 960)
|
|
138
|
+
- `--design-base-height` - Design base height (portrait: 960, landscape: 540)
|
|
139
|
+
- `--px2vw-ratio` - Ratio for px to responsive unit conversion
|
|
140
|
+
|
|
141
|
+
### 3. Complete Example
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// app.component.ts
|
|
145
|
+
import { Component } from '@angular/core';
|
|
146
|
+
import { BsBoundary } from '@bitstack/ng-boundary';
|
|
147
|
+
|
|
148
|
+
@Component({
|
|
149
|
+
selector: 'app-root',
|
|
150
|
+
standalone: true,
|
|
151
|
+
imports: [BsBoundary],
|
|
152
|
+
templateUrl: './app.component.html',
|
|
153
|
+
styleUrls: ['./app.component.scss']
|
|
154
|
+
})
|
|
155
|
+
export class AppComponent {}
|
|
156
|
+
```
|
|
52
157
|
|
|
53
|
-
|
|
158
|
+
```html
|
|
159
|
+
<!-- app.component.html -->
|
|
160
|
+
<bs-boundary [orientationMode]="'auto'">
|
|
161
|
+
<div class="game-container">
|
|
162
|
+
<h1 class="title">My Game</h1>
|
|
163
|
+
<button class="play-button">Play</button>
|
|
164
|
+
</div>
|
|
165
|
+
</bs-boundary>
|
|
166
|
+
```
|
|
54
167
|
|
|
55
|
-
```
|
|
56
|
-
|
|
168
|
+
```scss
|
|
169
|
+
// app.component.scss
|
|
170
|
+
@use '@bitstack/ng-boundary/styles' as boundary;
|
|
171
|
+
|
|
172
|
+
.game-container {
|
|
173
|
+
@include boundary.flexCenter;
|
|
174
|
+
flex-direction: column;
|
|
175
|
+
width: 100%;
|
|
176
|
+
height: 100%;
|
|
177
|
+
gap: boundary.px2vw(20);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.title {
|
|
181
|
+
font-size: boundary.px2vw(48);
|
|
182
|
+
@include boundary.padding-top(40);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.play-button {
|
|
186
|
+
@include boundary.width(200);
|
|
187
|
+
@include boundary.height(60);
|
|
188
|
+
font-size: boundary.px2vw(24);
|
|
189
|
+
border-radius: boundary.px2vw(12);
|
|
190
|
+
}
|
|
57
191
|
```
|
|
58
192
|
|
|
59
|
-
|
|
193
|
+
## Design System
|
|
194
|
+
|
|
195
|
+
The component is designed with these base dimensions:
|
|
196
|
+
- Portrait mode: 540px × 960px
|
|
197
|
+
- Landscape mode: 960px × 540px
|
|
198
|
+
|
|
199
|
+
The `px2vw()` function automatically scales your design to fit within the boundary while maintaining aspect ratio.
|
|
200
|
+
|
|
201
|
+
## Requirements
|
|
202
|
+
|
|
203
|
+
- Angular 14.0.0 or higher
|
|
204
|
+
- @angular/cdk 14.0.0 or higher
|
|
205
|
+
- SCSS support in your Angular project
|
|
206
|
+
|
|
207
|
+
## Building
|
|
208
|
+
|
|
209
|
+
To build the library:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
ng build bitstack-ng-boundary
|
|
213
|
+
```
|
|
60
214
|
|
|
61
|
-
##
|
|
215
|
+
## License
|
|
62
216
|
|
|
63
|
-
|
|
217
|
+
MIT
|
package/package.json
CHANGED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// check support device-vh
|
|
2
|
+
@use "sass:math";
|
|
3
|
+
@use "variables";
|
|
4
|
+
@use "responsive";
|
|
5
|
+
|
|
6
|
+
// Import required mixins from responsive
|
|
7
|
+
@mixin supports-dv {
|
|
8
|
+
@supports (width: 100dvh) {
|
|
9
|
+
@content;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
@mixin not-supports-dv {
|
|
13
|
+
@supports not (width: 100dvh) {
|
|
14
|
+
@content;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Import and re-export functions from responsive
|
|
19
|
+
@function responsive-size-by-px($px, $unit: 'v', $isLandscape: false, $isMax: false) {
|
|
20
|
+
$w: math.div($px, 5.4);
|
|
21
|
+
@return responsive.responsive-size-by-vw($w, $unit, $isLandscape, $isMax);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Note: responsive-size-by-vw is provided by the responsive module
|
|
25
|
+
// and should be accessed via @use "responsive"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
// use vw, vh or dvw, dvh
|
|
30
|
+
@function vw($w) {
|
|
31
|
+
@return #{$w}#{variables.$vw-unit};
|
|
32
|
+
}
|
|
33
|
+
@function vh($h) {
|
|
34
|
+
@return #{$h}#{variables.$vh-unit};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@mixin setProperty($property, $value) {
|
|
40
|
+
@include supports-dv {
|
|
41
|
+
#{$property}: responsive-size-by-px($value, 'dv');
|
|
42
|
+
}
|
|
43
|
+
@include not-supports-dv {
|
|
44
|
+
#{$property}: responsive-size-by-px($value, 'v');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 響應式尺寸 mixin 版本 (包含 supports-dv 判斷)
|
|
49
|
+
@mixin px2vw($property, $px) {
|
|
50
|
+
$layout-width-num: variables.$design-width; // 375
|
|
51
|
+
$layout-height-num: variables.$design-height; // 667
|
|
52
|
+
|
|
53
|
+
$vw-value: math.div($px, $layout-width-num) * 100; // 70/375*100
|
|
54
|
+
$vh-value: math.div($px, $layout-height-num) * 100; // 70/667*100
|
|
55
|
+
|
|
56
|
+
@include supports-dv {
|
|
57
|
+
#{$property}: min(#{$vw-value}dvw, #{$vh-value}dvh);
|
|
58
|
+
}
|
|
59
|
+
@include not-supports-dv {
|
|
60
|
+
#{$property}: min(#{$vw-value}vw, #{$vh-value}vh);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 單一屬性響應式 mixin (你想要的語法)
|
|
65
|
+
@mixin height($px) {
|
|
66
|
+
@include px2vw(height, $px);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@mixin width($px) {
|
|
70
|
+
@include px2vw(width, $px);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@mixin padding-left($px) {
|
|
74
|
+
@include px2vw(padding-left, $px);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@mixin padding-right($px) {
|
|
78
|
+
@include px2vw(padding-right, $px);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@mixin padding-top($px) {
|
|
82
|
+
@include px2vw(padding-top, $px);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@mixin padding-bottom($px) {
|
|
86
|
+
@include px2vw(padding-bottom, $px);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 響應式尺寸函數 (自動適應直式/橫式)
|
|
90
|
+
// 使用 CSS 變數來獲取當前模式下的設計基準寬度
|
|
91
|
+
// Portrait: --design-base-width = 375
|
|
92
|
+
// Landscape: --design-base-width = 667
|
|
93
|
+
@function px2vw($px) {
|
|
94
|
+
@return calc(#{$px} * var(--px2vw-ratio));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 原始的 px2vw 函數 (不受 boundary 限制,直接基於 viewport)
|
|
98
|
+
@function px2vw-unbounded($px) {
|
|
99
|
+
$layout-width-num: variables.$design-width; // 375
|
|
100
|
+
$layout-height-num: variables.$design-height; // 667
|
|
101
|
+
|
|
102
|
+
$vw-value: math.div($px, $layout-width-num) * 100; // 70/375*100 = 18.666667
|
|
103
|
+
$vh-value: math.div($px, $layout-height-num) * 100; // 70/667*100 = 10.494948
|
|
104
|
+
|
|
105
|
+
@return unquote("min(#{$vw-value}#{variables.$vw-unit}, #{$vh-value}#{variables.$vw-unit})");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
@use "responsive";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/* Small devices (portrait tablets and large phones, 376px and up) */
|
|
5
|
+
@mixin s {
|
|
6
|
+
@media only screen and (min-width: 481px) and (min-height: 746px) {
|
|
7
|
+
@content;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// only mobile
|
|
12
|
+
@mixin landscape {
|
|
13
|
+
@media only screen and (orientation: landscape) and (any-pointer: coarse) {
|
|
14
|
+
@content;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@mixin portrait {
|
|
19
|
+
@media only screen and (orientation: portrait) and (any-pointer: coarse) {
|
|
20
|
+
@content;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@mixin pc_landscape {
|
|
25
|
+
@media only screen and (orientation: landscape) {
|
|
26
|
+
@content;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@mixin pc_portrait {
|
|
31
|
+
@media only screen and (orientation: portrait) {
|
|
32
|
+
@content;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@mixin text-center {
|
|
38
|
+
text-align: center;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@mixin text-shadow($color) {
|
|
42
|
+
text-shadow: -1px 0 $color, 0 1px $color, 1px 0 $color, 0 -1px $color;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@mixin size($w, $h: $w) {
|
|
46
|
+
width: $w;
|
|
47
|
+
height: $h;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@mixin hideScrollbar {
|
|
51
|
+
-ms-overflow-style: -ms-autohiding-scrollbar;
|
|
52
|
+
scrollbar-width: none;
|
|
53
|
+
&::-webkit-scrollbar {
|
|
54
|
+
display: none;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@mixin flexCenter {
|
|
59
|
+
display: flex;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
align-items: center;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@mixin bg-contain {
|
|
65
|
+
background: center / contain no-repeat;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@mixin bg-cover {
|
|
69
|
+
background: center / cover no-repeat;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@mixin devBorder($color: aqua) {
|
|
73
|
+
box-shadow: inset 0 0 0 1px $color;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// WebP 圖片支持 mixin - 自動生成 WebP fallback
|
|
77
|
+
// 使用方法: @include bg-image-webp("/assets/images/_common/img-support/img.png");
|
|
78
|
+
@mixin bg-image-webp($png-path) {
|
|
79
|
+
$webp-path: str-replace($png-path, '.png', '.webp');
|
|
80
|
+
|
|
81
|
+
@supports (background-image: image-set(url("x.webp") type("image/webp"))){
|
|
82
|
+
background-image: image-set(
|
|
83
|
+
url($webp-path) type("image/webp"),
|
|
84
|
+
url($png-path) type("image/png")
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
@supports not (background-image: image-set(url("x.webp") type("image/webp"))){
|
|
88
|
+
background-image: url($png-path);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 辅助函数:字符串替换
|
|
93
|
+
@function str-replace($string, $search, $replace: '') {
|
|
94
|
+
$index: str-index($string, $search);
|
|
95
|
+
@if $index {
|
|
96
|
+
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
|
|
97
|
+
}
|
|
98
|
+
@return $string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.scale-btn {
|
|
102
|
+
cursor: pointer;
|
|
103
|
+
transition: transform 0.1s;
|
|
104
|
+
&:active {
|
|
105
|
+
transform: scale(0.9);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,698 @@
|
|
|
1
|
+
// check support device-vh
|
|
2
|
+
@use "sass:math";
|
|
3
|
+
@use "variables";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@mixin supports-dv {
|
|
8
|
+
@supports (width: 100dvh) {
|
|
9
|
+
@content;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
@mixin not-supports-dv {
|
|
13
|
+
@supports not (width: 100dvh) {
|
|
14
|
+
@content;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 主要尺寸轉換方法
|
|
22
|
+
* 將設計稿的 px 轉為AWD的 vw
|
|
23
|
+
*/
|
|
24
|
+
@function responsive-size-by-vw($w, $unit: 'v', $isLandscape: false, $isMax: false) {
|
|
25
|
+
@if ($isLandscape) {
|
|
26
|
+
@if ($isMax) {
|
|
27
|
+
@return max(vw($w, $unit), vh($w, $unit) * variables.$design-height / variables.$design-width);
|
|
28
|
+
} @else {
|
|
29
|
+
@return min(vw($w, $unit), vh($w, $unit) * variables.$design-height / variables.$design-width);
|
|
30
|
+
}
|
|
31
|
+
} @else {
|
|
32
|
+
@if ($isMax) {
|
|
33
|
+
@return max(vw($w, $unit), vh($w, $unit) * variables.$design-width / variables.$design-height);
|
|
34
|
+
} @else {
|
|
35
|
+
@return min(vw($w, $unit), vh($w, $unit) * variables.$design-width / variables.$design-height);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
@function responsive-size-by-vh($h, $unit: 'v', $isLandscape: false, $isMax: false) {
|
|
40
|
+
@if ($isLandscape) {
|
|
41
|
+
@if ($isMax) {
|
|
42
|
+
@return max(vw($h, $unit) * variables.$design-width / variables.$design-height, vh($h, $unit));
|
|
43
|
+
} @else {
|
|
44
|
+
@return min(vw($h, $unit) * variables.$design-width / variables.$design-height, vh($h, $unit));
|
|
45
|
+
}
|
|
46
|
+
} @else {
|
|
47
|
+
@if ($isMax) {
|
|
48
|
+
@return max(vw($h, $unit) * variables.$design-height / variables.$design-width, vh($h, $unit));
|
|
49
|
+
} @else {
|
|
50
|
+
@return min(vw($h, $unit) * variables.$design-height / variables.$design-width, vh($h, $unit));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
@function responsive-size-by-px($px, $unit: 'v', $isLandscape: false, $isMax: false) {
|
|
55
|
+
$w: math.div($px, 5.4);
|
|
56
|
+
@return responsive-size-by-vw($w, $unit, $isLandscape, $isMax);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// responsive width/height by vw
|
|
60
|
+
@mixin width-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
61
|
+
@include supports-dv {
|
|
62
|
+
width: responsive-size-by-vw($w, 'dv', $isLandscape, $isMax);
|
|
63
|
+
}
|
|
64
|
+
@include not-supports-dv {
|
|
65
|
+
width: responsive-size-by-vw($w, 'v', $isLandscape, $isMax);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
@mixin height-by-vw($h, $isLandscape: false, $isMax: false) {
|
|
69
|
+
@include supports-dv {
|
|
70
|
+
height: responsive-size-by-vw($h, 'dv', $isLandscape, $isMax);
|
|
71
|
+
}
|
|
72
|
+
@include not-supports-dv {
|
|
73
|
+
height: responsive-size-by-vw($h, 'v', $isLandscape, $isMax);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
@mixin size-by-vw($w, $h: $w, $isLandscape: false, $isMax: false) {
|
|
77
|
+
@include width-by-vw($w, $isLandscape, $isMax);
|
|
78
|
+
@include height-by-vw($h, $isLandscape, $isMax);
|
|
79
|
+
}
|
|
80
|
+
// responsive width/height by vh
|
|
81
|
+
@mixin width-by-vh($w, $isLandscape: false, $isMax: false) {
|
|
82
|
+
@include supports-dv {
|
|
83
|
+
width: responsive-size-by-vh($w, 'dv', $isLandscape, $isMax);
|
|
84
|
+
}
|
|
85
|
+
@include not-supports-dv {
|
|
86
|
+
width: responsive-size-by-vh($w, 'v', $isLandscape, $isMax);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
@mixin height-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
90
|
+
@include supports-dv {
|
|
91
|
+
height: responsive-size-by-vh($h, 'dv', $isLandscape, $isMax);
|
|
92
|
+
}
|
|
93
|
+
@include not-supports-dv {
|
|
94
|
+
height: responsive-size-by-vh($h, 'v', $isLandscape, $isMax);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
@mixin size-by-vh($w, $h: $w, $isLandscape: false, $isMax: false) {
|
|
98
|
+
@include width-by-vh($w, $isLandscape, $isMax);
|
|
99
|
+
@include height-by-vh($h, $isLandscape, $isMax);
|
|
100
|
+
}
|
|
101
|
+
// responsive width/height by px
|
|
102
|
+
@mixin width-by-px($w, $isLandscape: false, $isMax: false) {
|
|
103
|
+
@include supports-dv {
|
|
104
|
+
width: responsive-size-by-px($w, 'dv', $isLandscape, $isMax);
|
|
105
|
+
}
|
|
106
|
+
@include not-supports-dv {
|
|
107
|
+
width: responsive-size-by-px($w, 'v', $isLandscape, $isMax);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
@mixin height-by-px($h, $isLandscape: false, $isMax: false) {
|
|
111
|
+
@include supports-dv {
|
|
112
|
+
height: responsive-size-by-px($h, 'dv', $isLandscape, $isMax);
|
|
113
|
+
}
|
|
114
|
+
@include not-supports-dv {
|
|
115
|
+
height: responsive-size-by-px($h, 'v', $isLandscape, $isMax);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
@mixin size-by-px($w, $h: $w, $isLandscape: false, $isMax: false) {
|
|
119
|
+
@include width-by-px($w, $isLandscape, $isMax);
|
|
120
|
+
@include height-by-px($h, $isLandscape, $isMax);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@mixin responsive-min-height-by-px($px, $isLandscape: false, $isMax: false) {
|
|
124
|
+
@include supports-dv {
|
|
125
|
+
min-height: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
126
|
+
}
|
|
127
|
+
@include not-supports-dv {
|
|
128
|
+
min-height: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@mixin responsive-max-height-by-px($px, $isLandscape: false, $isMax: false) {
|
|
133
|
+
@include supports-dv {
|
|
134
|
+
max-height: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
135
|
+
}
|
|
136
|
+
@include not-supports-dv {
|
|
137
|
+
max-height: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// responsive font-size
|
|
142
|
+
@mixin responsive-font-size($w, $isLandscape: false, $isMax: false) {
|
|
143
|
+
@include supports-dv {
|
|
144
|
+
font-size: responsive-size-by-vw($w, 'dv', $isLandscape, $isMax);
|
|
145
|
+
}
|
|
146
|
+
@include not-supports-dv {
|
|
147
|
+
font-size: responsive-size-by-vw($w, 'v', $isLandscape, $isMax);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
@mixin responsive-font-size-by-vh($w, $isLandscape: false) {
|
|
151
|
+
@include supports-dv {
|
|
152
|
+
font-size: responsive-size-by-vh($w, 'dv', $isLandscape);
|
|
153
|
+
}
|
|
154
|
+
@include not-supports-dv {
|
|
155
|
+
font-size: responsive-size-by-vh($w, 'v', $isLandscape);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
@mixin responsive-font-size-by-px($px, $isLandscape: false, $isMax: false) {
|
|
159
|
+
@include supports-dv {
|
|
160
|
+
font-size: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
161
|
+
}
|
|
162
|
+
@include not-supports-dv {
|
|
163
|
+
font-size: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// responsive line-height
|
|
168
|
+
@mixin responsive-line-height($w) {
|
|
169
|
+
@include supports-dv {
|
|
170
|
+
line-height: responsive-size-by-vw($w, 'dv');
|
|
171
|
+
}
|
|
172
|
+
@include not-supports-dv {
|
|
173
|
+
line-height: responsive-size-by-vw($w, 'v');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
@mixin responsive-line-height-by-vh($h) {
|
|
177
|
+
@include supports-dv {
|
|
178
|
+
line-height: responsive-size-by-vh($h, 'dv');
|
|
179
|
+
}
|
|
180
|
+
@include not-supports-dv {
|
|
181
|
+
line-height: responsive-size-by-vh($h, 'v');
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
@mixin responsive-line-height-by-px($px) {
|
|
185
|
+
@include supports-dv {
|
|
186
|
+
line-height: responsive-size-by-px($px, 'dv');
|
|
187
|
+
}
|
|
188
|
+
@include not-supports-dv {
|
|
189
|
+
line-height: responsive-size-by-px($px, 'v');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// responsive letter-spacing
|
|
194
|
+
@mixin responsive-letter-spacing($w) {
|
|
195
|
+
@include supports-dv() {
|
|
196
|
+
letter-spacing: responsive-size-by-vw($w, 'dv');
|
|
197
|
+
}
|
|
198
|
+
@include not-supports-dv() {
|
|
199
|
+
letter-spacing: responsive-size-by-vw($w, 'v');
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
@mixin responsive-letter-spacing-by-vh($h) {
|
|
203
|
+
@include supports-dv() {
|
|
204
|
+
letter-spacing: responsive-size-by-vh($h, 'dv');
|
|
205
|
+
}
|
|
206
|
+
@include not-supports-dv() {
|
|
207
|
+
letter-spacing: responsive-size-by-vh($h, 'v');
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
@mixin responsive-letter-spacing-by-px($px) {
|
|
211
|
+
@include supports-dv() {
|
|
212
|
+
letter-spacing: responsive-size-by-px($px, 'dv');
|
|
213
|
+
}
|
|
214
|
+
@include not-supports-dv() {
|
|
215
|
+
letter-spacing: responsive-size-by-px($px, 'v');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// responsive stroke width
|
|
220
|
+
@mixin responsive-stroke-width-by-vw($w) {
|
|
221
|
+
@include supports-dv {
|
|
222
|
+
stroke-width: responsive-size-by-vw($w, 'dv');
|
|
223
|
+
}
|
|
224
|
+
@include not-supports-dv {
|
|
225
|
+
stroke-width: responsive-size-by-vw($w, 'v');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
@mixin responsive-stroke-width-by-vh($h) {
|
|
229
|
+
@include supports-dv {
|
|
230
|
+
stroke-width: responsive-size-by-vh($h, 'dv');
|
|
231
|
+
}
|
|
232
|
+
@include not-supports-dv {
|
|
233
|
+
stroke-width: responsive-size-by-vh($h, 'v');
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
@mixin responsive-stroke-width-by-px($px) {
|
|
237
|
+
@include supports-dv {
|
|
238
|
+
stroke-width: responsive-size-by-px($px, 'dv');
|
|
239
|
+
}
|
|
240
|
+
@include not-supports-dv {
|
|
241
|
+
stroke-width: responsive-size-by-px($px, 'v');
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// responsive text stroke
|
|
246
|
+
@mixin responsive-text-stroke-by-vw($w, $color) {
|
|
247
|
+
@include supports-dv {
|
|
248
|
+
-webkit-text-stroke: responsive-size-by-vw($w, 'dv') $color;
|
|
249
|
+
}
|
|
250
|
+
@include not-supports-dv {
|
|
251
|
+
-webkit-text-stroke: responsive-size-by-vw($w, 'v') $color;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
@mixin responsive-text-stroke-by-vh($w, $color) {
|
|
255
|
+
@include supports-dv {
|
|
256
|
+
-webkit-text-stroke: responsive-size-by-vh($w, 'dv') $color;
|
|
257
|
+
}
|
|
258
|
+
@include not-supports-dv {
|
|
259
|
+
-webkit-text-stroke: responsive-size-by-vh($w, 'v') $color;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
@mixin responsive-text-stroke-by-px($px, $color) {
|
|
263
|
+
@include supports-dv {
|
|
264
|
+
-webkit-text-stroke: responsive-size-by-px($px, 'dv') $color;
|
|
265
|
+
}
|
|
266
|
+
@include not-supports-dv {
|
|
267
|
+
-webkit-text-stroke: responsive-size-by-px($px, 'v') $color;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// responsive border-radius
|
|
272
|
+
@mixin responsive-border-radius-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
273
|
+
@include supports-dv {
|
|
274
|
+
border-radius: responsive-size-by-vw($w, 'dv', $isLandscape, $isMax);
|
|
275
|
+
}
|
|
276
|
+
@include not-supports-dv {
|
|
277
|
+
border-radius: responsive-size-by-vw($w, 'v', $isLandscape, $isMax);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
@mixin responsive-border-radius-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
281
|
+
@include supports-dv {
|
|
282
|
+
border-radius: responsive-size-by-vh($h, 'dv', $isLandscape, $isMax);
|
|
283
|
+
}
|
|
284
|
+
@include not-supports-dv {
|
|
285
|
+
border-radius: responsive-size-by-vh($h, 'v', $isLandscape, $isMax);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
@mixin responsive-border-radius-by-px($px, $isLandscape: false, $isMax: false) {
|
|
289
|
+
@include supports-dv {
|
|
290
|
+
border-radius: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
291
|
+
}
|
|
292
|
+
@include not-supports-dv {
|
|
293
|
+
border-radius: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// responsive margin
|
|
298
|
+
@mixin responsive-margin-top-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
299
|
+
@include supports-dv {
|
|
300
|
+
margin-top: responsive-size-by-vw($w, 'dv', $isLandscape, $isMax);
|
|
301
|
+
}
|
|
302
|
+
@include not-supports-dv {
|
|
303
|
+
margin-top: responsive-size-by-vw($w, 'v', $isLandscape, $isMax);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
@mixin responsive-margin-bottom-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
307
|
+
@include supports-dv {
|
|
308
|
+
margin-bottom: responsive-size-by-vw($w, 'dv', $isLandscape, $isMax);
|
|
309
|
+
}
|
|
310
|
+
@include not-supports-dv {
|
|
311
|
+
margin-bottom: responsive-size-by-vw($w, 'v', $isLandscape, $isMax);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
@mixin responsive-margin-left-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
315
|
+
@include supports-dv {
|
|
316
|
+
margin-left: responsive-size-by-vw($w, 'dv', $isLandscape, $isMax);
|
|
317
|
+
}
|
|
318
|
+
@include not-supports-dv {
|
|
319
|
+
margin-left: responsive-size-by-vw($w, 'v', $isLandscape, $isMax);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
@mixin responsive-margin-right-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
323
|
+
@include supports-dv {
|
|
324
|
+
margin-right: responsive-size-by-vw($w, 'dv', $isLandscape, $isMax);
|
|
325
|
+
}
|
|
326
|
+
@include not-supports-dv {
|
|
327
|
+
margin-right: responsive-size-by-vw($w, 'v', $isLandscape, $isMax);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
@mixin responsive-margin-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
331
|
+
@include responsive-margin-top-by-vw($w, $isLandscape, $isMax);
|
|
332
|
+
@include responsive-margin-bottom-by-vw($w, $isLandscape, $isMax);
|
|
333
|
+
@include responsive-margin-left-by-vw($w, $isLandscape, $isMax);
|
|
334
|
+
@include responsive-margin-right-by-vw($w, $isLandscape, $isMax);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
@mixin responsive-margin-top-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
338
|
+
@include supports-dv {
|
|
339
|
+
margin-top: responsive-size-by-vh($h, 'dv', $isLandscape, $isMax);
|
|
340
|
+
}
|
|
341
|
+
@include not-supports-dv {
|
|
342
|
+
margin-top: responsive-size-by-vh($h, 'v', $isLandscape, $isMax);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
@mixin responsive-margin-bottom-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
346
|
+
@include supports-dv {
|
|
347
|
+
margin-bottom: responsive-size-by-vh($h, 'dv', $isLandscape, $isMax);
|
|
348
|
+
}
|
|
349
|
+
@include not-supports-dv {
|
|
350
|
+
margin-bottom: responsive-size-by-vh($h, 'v', $isLandscape, $isMax);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
@mixin responsive-margin-left-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
354
|
+
@include supports-dv {
|
|
355
|
+
margin-left: responsive-size-by-vh($h, 'dv', $isLandscape, $isMax);
|
|
356
|
+
}
|
|
357
|
+
@include not-supports-dv {
|
|
358
|
+
margin-left: responsive-size-by-vh($h, 'v', $isLandscape, $isMax);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
@mixin responsive-margin-right-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
362
|
+
@include supports-dv {
|
|
363
|
+
margin-right: responsive-size-by-vh($h, 'dv', $isLandscape, $isMax);
|
|
364
|
+
}
|
|
365
|
+
@include not-supports-dv {
|
|
366
|
+
margin-right: responsive-size-by-vh($h, 'v', $isLandscape, $isMax);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
@mixin responsive-margin-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
370
|
+
@include responsive-margin-top-by-vh($h, $isLandscape, $isMax);
|
|
371
|
+
@include responsive-margin-bottom-by-vh($h, $isLandscape, $isMax);
|
|
372
|
+
@include responsive-margin-left-by-vh($h, $isLandscape, $isMax);
|
|
373
|
+
@include responsive-margin-right-by-vh($h, $isLandscape, $isMax);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
@mixin responsive-margin-top-by-px($px, $isLandscape: false, $isMax: false) {
|
|
377
|
+
@include supports-dv {
|
|
378
|
+
margin-top: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
379
|
+
}
|
|
380
|
+
@include not-supports-dv {
|
|
381
|
+
margin-top: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
@mixin responsive-margin-bottom-by-px($px, $isLandscape: false, $isMax: false) {
|
|
385
|
+
@include supports-dv {
|
|
386
|
+
margin-bottom: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
387
|
+
}
|
|
388
|
+
@include not-supports-dv {
|
|
389
|
+
margin-bottom: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
@mixin responsive-margin-left-by-px($px, $isLandscape: false, $isMax: false) {
|
|
393
|
+
@include supports-dv {
|
|
394
|
+
margin-left: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
395
|
+
}
|
|
396
|
+
@include not-supports-dv {
|
|
397
|
+
margin-left: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
@mixin responsive-margin-right-by-px($px, $isLandscape: false, $isMax: false) {
|
|
401
|
+
@include supports-dv {
|
|
402
|
+
margin-right: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
403
|
+
}
|
|
404
|
+
@include not-supports-dv {
|
|
405
|
+
right: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
@mixin responsive-margin-by-px($px, $isLandscape: false, $isMax: false) {
|
|
409
|
+
@include responsive-margin-top-by-px($px, $isLandscape, $isMax);
|
|
410
|
+
@include responsive-margin-bottom-by-px($px, $isLandscape, $isMax);
|
|
411
|
+
@include responsive-margin-left-by-px($px, $isLandscape, $isMax);
|
|
412
|
+
@include responsive-margin-right-by-px($px, $isLandscape, $isMax);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// responsive padding
|
|
416
|
+
@mixin responsive-padding-top-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
417
|
+
@include supports-dv {
|
|
418
|
+
padding-top: responsive-size-by-vw($w, 'dv', $isLandscape, $isMax);
|
|
419
|
+
}
|
|
420
|
+
@include not-supports-dv {
|
|
421
|
+
padding-top: responsive-size-by-vw($w, 'v', $isLandscape, $isMax);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
@mixin responsive-padding-bottom-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
425
|
+
@include supports-dv {
|
|
426
|
+
padding-bottom: responsive-size-by-vw($w, 'dv', $isLandscape, $isMax);
|
|
427
|
+
}
|
|
428
|
+
@include not-supports-dv {
|
|
429
|
+
padding-bottom: responsive-size-by-vw($w, 'v', $isLandscape, $isMax);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
@mixin responsive-padding-left-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
433
|
+
@include supports-dv {
|
|
434
|
+
padding-left: responsive-size-by-vw($w, 'dv', $isLandscape, $isMax);
|
|
435
|
+
}
|
|
436
|
+
@include not-supports-dv {
|
|
437
|
+
padding-left: responsive-size-by-vw($w, 'v', $isLandscape, $isMax);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
@mixin responsive-padding-right-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
441
|
+
@include supports-dv {
|
|
442
|
+
padding-right: responsive-size-by-vw($w, 'dv', $isLandscape, $isMax);
|
|
443
|
+
}
|
|
444
|
+
@include not-supports-dv {
|
|
445
|
+
padding-right: responsive-size-by-vw($w, 'v', $isLandscape, $isMax);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
@mixin responsive-padding-by-vw($w, $isLandscape: false, $isMax: false) {
|
|
449
|
+
@include responsive-padding-top-by-vw($w, $isLandscape, $isMax);
|
|
450
|
+
@include responsive-padding-bottom-by-vw($w, $isLandscape, $isMax);
|
|
451
|
+
@include responsive-padding-left-by-vw($w, $isLandscape, $isMax);
|
|
452
|
+
@include responsive-padding-right-by-vw($w, $isLandscape, $isMax);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
@mixin responsive-padding-top-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
456
|
+
@include supports-dv {
|
|
457
|
+
padding-top: responsive-size-by-vh($h, 'dv', $isLandscape, $isMax);
|
|
458
|
+
}
|
|
459
|
+
@include not-supports-dv {
|
|
460
|
+
padding-top: responsive-size-by-vh($h, 'v', $isLandscape, $isMax);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
@mixin responsive-padding-bottom-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
464
|
+
@include supports-dv {
|
|
465
|
+
padding-bottom: responsive-size-by-vh($h, 'dv', $isLandscape, $isMax);
|
|
466
|
+
}
|
|
467
|
+
@include not-supports-dv {
|
|
468
|
+
padding-bottom: responsive-size-by-vh($h, 'v', $isLandscape, $isMax);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
@mixin responsive-padding-left-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
472
|
+
@include supports-dv {
|
|
473
|
+
padding-left: responsive-size-by-vh($h, 'dv', $isLandscape, $isMax);
|
|
474
|
+
}
|
|
475
|
+
@include not-supports-dv {
|
|
476
|
+
padding-left: responsive-size-by-vh($h, 'v', $isLandscape, $isMax);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
@mixin responsive-padding-right-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
480
|
+
@include supports-dv {
|
|
481
|
+
padding-right: responsive-size-by-vh($h, 'dv', $isLandscape, $isMax);
|
|
482
|
+
}
|
|
483
|
+
@include not-supports-dv {
|
|
484
|
+
padding-right: responsive-size-by-vh($h, 'v', $isLandscape, $isMax);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
@mixin responsive-padding-by-vh($h, $isLandscape: false, $isMax: false) {
|
|
488
|
+
@include responsive-padding-top-by-vh($h, $isLandscape, $isMax);
|
|
489
|
+
@include responsive-padding-bottom-by-vh($h, $isLandscape, $isMax);
|
|
490
|
+
@include responsive-padding-left-by-vh($h, $isLandscape, $isMax);
|
|
491
|
+
@include responsive-padding-right-by-vh($h, $isLandscape, $isMax);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
@mixin responsive-padding-top-by-px($px, $isLandscape: false, $isMax: false) {
|
|
495
|
+
@include supports-dv {
|
|
496
|
+
padding-top: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
497
|
+
}
|
|
498
|
+
@include not-supports-dv {
|
|
499
|
+
padding-top: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
@mixin responsive-padding-bottom-by-px($px, $isLandscape: false, $isMax: false) {
|
|
503
|
+
@include supports-dv {
|
|
504
|
+
padding-bottom: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
505
|
+
}
|
|
506
|
+
@include not-supports-dv {
|
|
507
|
+
padding-bottom: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
@mixin responsive-padding-left-by-px($px, $isLandscape: false, $isMax: false) {
|
|
511
|
+
@include supports-dv {
|
|
512
|
+
padding-left: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
513
|
+
}
|
|
514
|
+
@include not-supports-dv {
|
|
515
|
+
padding-left: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
@mixin responsive-padding-right-by-px($px, $isLandscape: false, $isMax: false) {
|
|
519
|
+
@include supports-dv {
|
|
520
|
+
padding-right: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
521
|
+
}
|
|
522
|
+
@include not-supports-dv {
|
|
523
|
+
padding-right: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
@mixin responsive-padding-by-px($px, $isLandscape: false, $isMax: false) {
|
|
527
|
+
@include responsive-padding-top-by-px($px, $isLandscape, $isMax);
|
|
528
|
+
@include responsive-padding-bottom-by-px($px, $isLandscape, $isMax);
|
|
529
|
+
@include responsive-padding-left-by-px($px, $isLandscape, $isMax);
|
|
530
|
+
@include responsive-padding-right-by-px($px, $isLandscape, $isMax);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// responsive position
|
|
534
|
+
@mixin responsive-position-by-vw($vw: (top: "", right: "", bottom: "", left: ""), $isLandscape: false, $isMax: false) {
|
|
535
|
+
$top: if(map-has-key($vw, top), map-get($vw, top), "");
|
|
536
|
+
$right: if(map-has-key($vw, right), map-get($vw, right), "");
|
|
537
|
+
$bottom: if(map-has-key($vw, bottom), map-get($vw, bottom), "");
|
|
538
|
+
$left: if(map-has-key($vw, left), map-get($vw, left), "");
|
|
539
|
+
|
|
540
|
+
@include supports-dv {
|
|
541
|
+
@if ($top != "") {
|
|
542
|
+
top: responsive-size-by-vw($top, 'dv', $isLandscape, $isMax);
|
|
543
|
+
}
|
|
544
|
+
@if ($right != "") {
|
|
545
|
+
right: responsive-size-by-vw($right, 'dv', $isLandscape, $isMax);
|
|
546
|
+
}
|
|
547
|
+
@if ($bottom != "") {
|
|
548
|
+
bottom: responsive-size-by-vw($bottom, 'dv', $isLandscape, $isMax);
|
|
549
|
+
}
|
|
550
|
+
@if ($left != "") {
|
|
551
|
+
left: responsive-size-by-vw($left, 'dv', $isLandscape, $isMax);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
@include not-supports-dv {
|
|
555
|
+
@if ($top != "") {
|
|
556
|
+
top: responsive-size-by-vw($top, 'v', $isLandscape, $isMax);
|
|
557
|
+
}
|
|
558
|
+
@if ($right != "") {
|
|
559
|
+
right: responsive-size-by-vw($right, 'v', $isLandscape, $isMax);
|
|
560
|
+
}
|
|
561
|
+
@if ($bottom != "") {
|
|
562
|
+
bottom: responsive-size-by-vw($bottom, 'v', $isLandscape, $isMax);
|
|
563
|
+
}
|
|
564
|
+
@if ($left != "") {
|
|
565
|
+
left: responsive-size-by-vw($left, 'v', $isLandscape, $isMax);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
@mixin responsive-position-by-vh($vh: (top: "", right: "", bottom: "", left: ""), $isLandscape: false, $isMax: false) {
|
|
570
|
+
$top: if(map-has-key($vh, top), map-get($vh, top), "");
|
|
571
|
+
$right: if(map-has-key($vh, right), map-get($vh, right), "");
|
|
572
|
+
$bottom: if(map-has-key($vh, bottom), map-get($vh, bottom), "");
|
|
573
|
+
$left: if(map-has-key($vh, left), map-get($vh, left), "");
|
|
574
|
+
@include supports-dv {
|
|
575
|
+
@if ($top != "") {
|
|
576
|
+
top: responsive-size-by-vh($top, 'dv', $isLandscape, $isMax);
|
|
577
|
+
}
|
|
578
|
+
@if ($right != "") {
|
|
579
|
+
right: responsive-size-by-vh($right, 'dv', $isLandscape, $isMax);
|
|
580
|
+
}
|
|
581
|
+
@if ($bottom != "") {
|
|
582
|
+
bottom: responsive-size-by-vh($bottom, 'dv', $isLandscape, $isMax);
|
|
583
|
+
}
|
|
584
|
+
@if ($left != "") {
|
|
585
|
+
left: responsive-size-by-vh($left, 'dv', $isLandscape, $isMax);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
@include not-supports-dv {
|
|
589
|
+
@if ($top != "") {
|
|
590
|
+
top: responsive-size-by-vh($top, 'v', $isLandscape, $isMax);
|
|
591
|
+
}
|
|
592
|
+
@if ($right != "") {
|
|
593
|
+
right: responsive-size-by-vh($right, 'v', $isLandscape, $isMax);
|
|
594
|
+
}
|
|
595
|
+
@if ($bottom != "") {
|
|
596
|
+
bottom: responsive-size-by-vh($bottom, 'v', $isLandscape, $isMax);
|
|
597
|
+
}
|
|
598
|
+
@if ($left != "") {
|
|
599
|
+
left: responsive-size-by-vh($left, 'v', $isLandscape, $isMax);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
@mixin responsive-position-by-px($px: (top: "", right: "", bottom: "", left: ""), $isLandscape: false, $isMax: false) {
|
|
604
|
+
$top: if(map-has-key($px, top), map-get($px, top), "");
|
|
605
|
+
$right: if(map-has-key($px, right), map-get($px, right), "");
|
|
606
|
+
$bottom: if(map-has-key($px, bottom), map-get($px, bottom), "");
|
|
607
|
+
$left: if(map-has-key($px, left), map-get($px, left), "");
|
|
608
|
+
@include supports-dv {
|
|
609
|
+
@if ($top != "") {
|
|
610
|
+
top: responsive-size-by-px($top, 'dv', $isLandscape, $isMax);
|
|
611
|
+
}
|
|
612
|
+
@if ($right != "") {
|
|
613
|
+
right: responsive-size-by-px($right, 'dv', $isLandscape, $isMax);
|
|
614
|
+
}
|
|
615
|
+
@if ($bottom != "") {
|
|
616
|
+
bottom: responsive-size-by-px($bottom, 'dv', $isLandscape, $isMax);
|
|
617
|
+
}
|
|
618
|
+
@if ($left != "") {
|
|
619
|
+
left: responsive-size-by-px($left, 'dv', $isLandscape, $isMax);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
@include not-supports-dv {
|
|
623
|
+
@if ($top != "") {
|
|
624
|
+
top: responsive-size-by-px($top, 'v', $isLandscape, $isMax);
|
|
625
|
+
}
|
|
626
|
+
@if ($right != "") {
|
|
627
|
+
right: responsive-size-by-px($right, 'v', $isLandscape, $isMax);
|
|
628
|
+
}
|
|
629
|
+
@if ($bottom != "") {
|
|
630
|
+
bottom: responsive-size-by-px($bottom, 'v', $isLandscape, $isMax);
|
|
631
|
+
}
|
|
632
|
+
@if ($left != "") {
|
|
633
|
+
left: responsive-size-by-px($left, 'v', $isLandscape, $isMax);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
@mixin responsive-letter-border($color, $w, $h: $w) {
|
|
639
|
+
$vw: $w + 'vw';
|
|
640
|
+
$vh: $h + 'vh';
|
|
641
|
+
$unit: min(#{$vw}, #{$vh} * variables.$design-width / variables.$design-height);
|
|
642
|
+
$minusUnit: calc(-1 * $unit);
|
|
643
|
+
|
|
644
|
+
text-shadow:
|
|
645
|
+
$unit 0 $color, /* 筆畫顏色,水平偏移 */
|
|
646
|
+
$minusUnit 0 $color, /* 筆畫顏色,水平偏移 */
|
|
647
|
+
0 $unit $color, /* 筆畫顏色,垂直偏移 */
|
|
648
|
+
0 $minusUnit $color, /* 筆畫顏色,垂直偏移 */
|
|
649
|
+
$unit $unit $color, /* 斜向右下 */
|
|
650
|
+
$minusUnit $minusUnit $color, /* 斜向左上 */
|
|
651
|
+
$unit $minusUnit $color, /* 斜向右上 */
|
|
652
|
+
$minusUnit $unit $color; /* 斜向左下 */
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
@mixin responsive-letter-shadow($color, $w, $h: $w) {
|
|
656
|
+
$vw: $w + 'vw';
|
|
657
|
+
$vh: $h + 'vh';
|
|
658
|
+
$unit: min(#{$vw}, #{$vh} * variables.$design-width / variables.$design-height);
|
|
659
|
+
|
|
660
|
+
text-shadow: $unit $unit $unit $color; /* 陰影顏色 */
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
@mixin responsive-letter-border-shadow($colorBorder, $colorShadow, $w, $h: $w) {
|
|
664
|
+
$vw: $w + 'vw';
|
|
665
|
+
$vh: $h + 'vh';
|
|
666
|
+
$unit: min(#{$vw}, #{$vh} * variables.$design-width / variables.$design-height);
|
|
667
|
+
$minusUnit: calc(-1 * $unit);
|
|
668
|
+
$shadow: calc(2 * $unit);
|
|
669
|
+
|
|
670
|
+
text-shadow:
|
|
671
|
+
$unit 0 $colorBorder, /* 筆畫顏色,水平偏移 */
|
|
672
|
+
$minusUnit 0 $colorBorder, /* 筆畫顏色,水平偏移 */
|
|
673
|
+
0 $unit $colorBorder, /* 筆畫顏色,垂直偏移 */
|
|
674
|
+
0 $minusUnit $colorBorder, /* 筆畫顏色,垂直偏移 */
|
|
675
|
+
$unit $unit $colorBorder, /* 斜向右下 */
|
|
676
|
+
$minusUnit $minusUnit $colorBorder, /* 斜向左上 */
|
|
677
|
+
$unit $minusUnit $colorBorder, /* 斜向右上 */
|
|
678
|
+
$minusUnit $unit $colorBorder, /* 斜向左下 */
|
|
679
|
+
$shadow $shadow $shadow $colorShadow; /* 陰影顏色 */
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
@mixin responsive-border-by-px($px, $color, $isLandscape: false, $isMax: false) {
|
|
683
|
+
@include supports-dv {
|
|
684
|
+
border: responsive-size-by-px($px, 'dv', $isLandscape, $isMax) solid $color;
|
|
685
|
+
}
|
|
686
|
+
@include not-supports-dv {
|
|
687
|
+
border: responsive-size-by-px($px, 'v', $isLandscape, $isMax) solid $color;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
@mixin responsive-padding-inline-start-by-px($px, $isLandscape: false, $isMax: false) {
|
|
692
|
+
@include supports-dv {
|
|
693
|
+
padding-inline-start: responsive-size-by-px($px, 'dv', $isLandscape, $isMax);
|
|
694
|
+
}
|
|
695
|
+
@include not-supports-dv {
|
|
696
|
+
padding-inline-start: responsive-size-by-px($px, 'v', $isLandscape, $isMax);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
@use "sass:math";
|
|
2
|
+
|
|
3
|
+
// 基礎尺寸 (無單位數值)
|
|
4
|
+
$design-width: 540;
|
|
5
|
+
$design-height: 960;
|
|
6
|
+
|
|
7
|
+
// 帶單位的版本 (當需要 px 單位時使用)
|
|
8
|
+
$design-width-px: #{$design-width}px;
|
|
9
|
+
$design-height-px: #{$design-height}px;
|
|
10
|
+
|
|
11
|
+
$landscape-ratio: math.div($design-width, $design-height);
|
|
12
|
+
$portrait-ratio: math.div($design-height, $design-width);
|
|
13
|
+
|
|
14
|
+
// Portrait 模式的設計基準
|
|
15
|
+
$layout-portrait-width: $design-width; // 375
|
|
16
|
+
$layout-portrait-height: $design-height; // 667
|
|
17
|
+
|
|
18
|
+
// Landscape 模式的設計基準
|
|
19
|
+
$layout-landscape-width: $design-height; // 667
|
|
20
|
+
$layout-landscape-height: $design-width; // 375
|
|
21
|
+
|
|
22
|
+
$vw-unit: dvw !default;
|
|
23
|
+
$vh-unit: dvh !default;
|
|
24
|
+
|
|
25
|
+
@supports not (width: 100dvh) {
|
|
26
|
+
$vw-unit: vw;
|
|
27
|
+
$vh-unit: vh;
|
|
28
|
+
}
|
|
29
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public SCSS API for @bitstack/ng-boundary
|
|
3
|
+
*
|
|
4
|
+
* This file exports all SCSS utilities, functions, and mixins
|
|
5
|
+
* for use in consumer projects.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* @use '@bitstack/ng-boundary/styles' as boundary;
|
|
9
|
+
*
|
|
10
|
+
* .my-component {
|
|
11
|
+
* width: boundary.px2vw(100);
|
|
12
|
+
* height: boundary.px2vw(200);
|
|
13
|
+
* }
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// Export all utilities
|
|
17
|
+
// Note: _awd already includes _responsive internally, so we don't need to forward _responsive separately
|
|
18
|
+
@forward 'variables';
|
|
19
|
+
@forward 'awd';
|
|
20
|
+
@forward 'mixin';
|
package/styles.scss
ADDED