Skip to content

Commit 8f1b769

Browse files
committed
Float support, and finalised the chosen unit.
1 parent 6eb1895 commit 8f1b769

20 files changed

+355
-182
lines changed

README.md

+3-5
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@
55
[![Code Climate](https://codeclimate.com/github/ZeeCoder/container-query/badges/gpa.svg)](https://codeclimate.com/github/ZeeCoder/container-query)
66
[![Coverage Status](https://coveralls.io/repos/github/ZeeCoder/container-query/badge.svg?branch=master)](https://coveralls.io/github/ZeeCoder/container-query?branch=master)
77

8+
A PostCSS plugin and Javascript runtime combination, which allows you to write @container queries in your CSS the same way you would write @media queries.
9+
810
# Milestones
911

1012
## 1.0.0
11-
- Support float container values
12-
- Think of a better unit for container values (instead of ch/cw)
1313
- Short description, also in package.json
1414
- Documented solutions for SASS / LESS and just PostCSS
1515
- Turn all milestone notes in the README to github issues and write a proper README
1616

1717
## 1.1.0
18+
- introduce vmin/vmax-like functionality
1819
- Optionally detect container resizing (polling solution?) instead of adjusting on window resize only
1920

2021
## 1.2.0
@@ -24,9 +25,6 @@
2425
- Allow for nested @container queries, like it's with @media queries in other preprocessors
2526

2627
## 1.4.0
27-
- Support units that translates to non px. (opacity, rgb, %, em-units, etc)
28-
29-
## 1.5.0
3028
- Ease usage with React, by hooking into Component refs
3129
- Webpack loader
3230
- compatibility with CSS-modules

demo/containers.css

+24-10
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,29 @@
88
width: 70%;
99
height: 70%;
1010

11-
border: calc(1ch + 1cw) solid;
11+
border: calc(1chpx + 1cwpx) solid;
1212
text-align: center;
1313
transition: background .3s;
1414
box-sizing: border-box;
1515
}
1616

17+
.user__tag {
18+
position: absolute;
19+
left: 50%;
20+
top: 0;
21+
transform: translateX(-50%);
22+
height: 1ch%;
23+
width: 5cw%;
24+
background: #ccc;
25+
border: 1px solid;
26+
display: flex;
27+
justify-content: center;
28+
align-items: center;
29+
}
30+
1731
.user__line1 {
1832
display: flex;
19-
height: 100ch;
33+
height: 100chpx;
2034
justify-content: center;
2135
align-items: center;
2236
}
@@ -33,7 +47,7 @@
3347
max-width: 100%;
3448
max-height: 80%;
3549
border-radius: 100%;
36-
border: calc(1ch + 1cw / 5) solid #ccc;
50+
border: calc(1chpx + 1cwpx / 5) solid #ccc;
3751
box-sizing: border-box;
3852
}
3953

@@ -44,7 +58,7 @@
4458
white-space: nowrap;
4559
flex: 1 0 0;
4660
text-align: left;
47-
font-size: calc(4ch + 4cw);
61+
font-size: calc(4chpx + 4cwpx);
4862
display: none;
4963
}
5064

@@ -66,28 +80,28 @@
6680

6781
@container (orientation: landscape) {
6882
.user__name {
69-
margin: 0 5cw;
70-
line-height: 100ch;
83+
margin: 0 5cwpx;
84+
line-height: 100chpx;
7185
}
7286
}
7387

7488
@container (orientation: portrait) {
7589
.user__line1 {
7690
flex-direction: column;
77-
height: 100ch;
91+
height: 100chpx;
7892
}
7993

8094
.user__image-wrapper {
8195
flex: 1 0 0;
8296
}
8397

8498
.user__image {
85-
max-height: 75ch;
99+
max-height: 75chpx;
86100
}
87101

88102
.user__name {
89-
flex: 0 0 20ch;
90-
line-height: 20ch;
103+
flex: 0 0 20chpx;
104+
line-height: 20chpx;
91105
text-align: center;
92106
}
93107
}

demo/containers.css.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{".user":{"selector":".user","queries":[{"elements":[{"selector":".user","styles":{"border":"calc(1ch + 1cw) solid","background":""}},{"selector":".user__line1","styles":{"height":"100ch","flexDirection":""}},{"selector":".user__image-wrapper","styles":{"flex":"","height":""}},{"selector":".user__image","styles":{"border":"calc(1ch + 1cw / 5) solid #ccc","maxWidth":"","maxHeight":""}},{"selector":".user__name","styles":{"fontSize":"calc(4ch + 4cw)","display":"","margin":"","lineHeight":"","flex":"","textAlign":""}}]},{"conditions":[["width",">=","250"],["height",">=","250"]],"elements":[{"selector":".user__image-wrapper","styles":{"flex":"0 0 40%","height":"auto"}},{"selector":".user__image","styles":{"maxWidth":"100%","maxHeight":"100ch"}},{"selector":".user__name","styles":{"display":"block"}}]},{"conditions":[["orientation",":","landscape"]],"elements":[{"selector":".user__name","styles":{"margin":"0 5cw","lineHeight":"100ch"}}]},{"conditions":[["orientation",":","portrait"]],"elements":[{"selector":".user__line1","styles":{"flexDirection":"column","height":"100ch"}},{"selector":".user__image-wrapper","styles":{"flex":"1 0 0"}},{"selector":".user__image","styles":{"maxHeight":"75ch"}},{"selector":".user__name","styles":{"flex":"0 0 20ch","lineHeight":"20ch","textAlign":"center"}}]},{"conditions":[["width",">","300"]],"elements":[{"selector":".user","styles":{"background":"#ccc"}}]},{"conditions":[["width",">","400"]],"elements":[{"selector":".user","styles":{"background":"#bbb"}}]},{"conditions":[["width",">","500"]],"elements":[{"selector":".user","styles":{"background":"#aaa"}}]},{"conditions":[["width",">","600"]],"elements":[{"selector":".user","styles":{"background":"#999"}}]},{"conditions":[["width",">","700"]],"elements":[{"selector":".user","styles":{"background":"#888"}}]},{"conditions":[["width",">","800"]],"elements":[{"selector":".user","styles":{"background":"#999"}}]}]}}
1+
{".user":{"selector":".user","queries":[{"elements":[{"selector":".user","styles":{"border":"calc(1chpx + 1cwpx) solid","background":""}},{"selector":".user__tag","styles":{"height":"1ch%","width":"5cw%"}},{"selector":".user__line1","styles":{"height":"100chpx","flexDirection":""}},{"selector":".user__image-wrapper","styles":{"flex":"","height":""}},{"selector":".user__image","styles":{"border":"calc(1chpx + 1cwpx / 5) solid #ccc","maxWidth":"","maxHeight":""}},{"selector":".user__name","styles":{"fontSize":"calc(4chpx + 4cwpx)","display":"","margin":"","lineHeight":"","flex":"","textAlign":""}}]},{"conditions":[["width",">=","250"],["height",">=","250"]],"elements":[{"selector":".user__image-wrapper","styles":{"flex":"0 0 40%","height":"auto"}},{"selector":".user__image","styles":{"maxWidth":"100%","maxHeight":"100ch"}},{"selector":".user__name","styles":{"display":"block"}}]},{"conditions":[["orientation",":","landscape"]],"elements":[{"selector":".user__name","styles":{"margin":"0 5cwpx","lineHeight":"100chpx"}}]},{"conditions":[["orientation",":","portrait"]],"elements":[{"selector":".user__line1","styles":{"flexDirection":"column","height":"100chpx"}},{"selector":".user__image-wrapper","styles":{"flex":"1 0 0"}},{"selector":".user__image","styles":{"maxHeight":"75chpx"}},{"selector":".user__name","styles":{"flex":"0 0 20chpx","lineHeight":"20chpx","textAlign":"center"}}]},{"conditions":[["width",">","300"]],"elements":[{"selector":".user","styles":{"background":"#ccc"}}]},{"conditions":[["width",">","400"]],"elements":[{"selector":".user","styles":{"background":"#bbb"}}]},{"conditions":[["width",">","500"]],"elements":[{"selector":".user","styles":{"background":"#aaa"}}]},{"conditions":[["width",">","600"]],"elements":[{"selector":".user","styles":{"background":"#999"}}]},{"conditions":[["width",">","700"]],"elements":[{"selector":".user","styles":{"background":"#888"}}]},{"conditions":[["width",">","800"]],"elements":[{"selector":".user","styles":{"background":"#999"}}]}]}}

demo/index.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
<title>Document</title>
66

77
<link rel="stylesheet" href="dist/styles.css">
8-
<link rel="stylesheet" href="dist/user.css">
8+
<link rel="stylesheet" href="dist/containers.css">
99
</head>
1010
<body>
1111

1212

1313
<div class="user">
14+
<div class="user__tag">tag</div>
1415
<div class="user__line1">
1516
<div class="user__image-wrapper">
1617
<img class="user__image" src="https://avatars3.githubusercontent.com/u/3679506?v=3&s=460">

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@zeecoder/container-query",
33
"version": "1.0.0",
4-
"description": "",
4+
"description": "A PostCSS plugin and Javascript runtime combination, which allows you to write @container queries in your CSS the same way you would write @media queries.",
55
"main": "index.js",
66
"author": "Viktor Hubert <[email protected]>",
77
"engines": {

src/postcss/containerQuery.spec.js

+16-16
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ test('proper json and css output', () => {
7171
.container {
7272
@${DEFINE_CONTAINER_NAME};
7373
border: none;
74-
font-size: 50${HEIGHT_UNIT};
74+
font-size: 50${HEIGHT_UNIT}px;
7575
/* Ignore this */
76-
line-height: 100${HEIGHT_UNIT};
76+
line-height: 100${HEIGHT_UNIT}px;
7777
}
7878
7979
@container (height >= 100) and (width >= 100) {
8080
.container {
81-
font-size: 70${HEIGHT_UNIT};
81+
font-size: 70${HEIGHT_UNIT}px;
8282
}
8383
}
8484
@@ -98,19 +98,19 @@ test('proper json and css output', () => {
9898
}
9999
100100
.container2__element {
101-
width: 50${WIDTH_UNIT};
102-
height: 50${HEIGHT_UNIT};
101+
width: 50${WIDTH_UNIT}px;
102+
height: 50${HEIGHT_UNIT}px;
103103
background: green;
104104
}
105105
106106
@container (orientation: portrait) {
107107
.container2 {
108-
font-size: 70${HEIGHT_UNIT};
108+
font-size: 70${HEIGHT_UNIT}px;
109109
}
110110
111111
.container2__element {
112-
width: 75${WIDTH_UNIT};
113-
height: 75${HEIGHT_UNIT};
112+
width: 75${WIDTH_UNIT}px;
113+
height: 75${HEIGHT_UNIT}px;
114114
background: red;
115115
}
116116
}
@@ -142,8 +142,8 @@ test('proper json and css output', () => {
142142
{
143143
"selector": ".container",
144144
"styles": {
145-
"fontSize": "50" + HEIGHT_UNIT,
146-
"lineHeight": "100" + HEIGHT_UNIT,
145+
"fontSize": `50${HEIGHT_UNIT}px`,
146+
"lineHeight": `100${HEIGHT_UNIT}px`,
147147
"background": "",
148148
}
149149
}
@@ -158,7 +158,7 @@ test('proper json and css output', () => {
158158
{
159159
"selector": ".container",
160160
"styles": {
161-
"fontSize": "70" + HEIGHT_UNIT
161+
"fontSize": `70${HEIGHT_UNIT}px`
162162
}
163163
}
164164
]
@@ -194,8 +194,8 @@ test('proper json and css output', () => {
194194
{
195195
"selector": ".container2__element",
196196
"styles": {
197-
"width": "50" + WIDTH_UNIT,
198-
"height": "50" + HEIGHT_UNIT,
197+
"width": `50${WIDTH_UNIT}px`,
198+
"height": `50${HEIGHT_UNIT}px`,
199199
"background": ""
200200
}
201201
}
@@ -213,14 +213,14 @@ test('proper json and css output', () => {
213213
{
214214
"selector": ".container2",
215215
"styles": {
216-
"fontSize": "70" + HEIGHT_UNIT
216+
"fontSize": `70${HEIGHT_UNIT}px`
217217
}
218218
},
219219
{
220220
"selector": ".container2__element",
221221
"styles": {
222-
"width": "75" + WIDTH_UNIT,
223-
"height": "75" + HEIGHT_UNIT,
222+
"width": `75${WIDTH_UNIT}px`,
223+
"height": `75${HEIGHT_UNIT}px`,
224224
"background": "red"
225225
}
226226
}

src/postcss/getStylesObjectFromNode.spec.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ test('should extract all styles', () => {
3232
.addNode(new Node({
3333
type: 'decl',
3434
prop: 'font-size',
35-
value: '5' + HEIGHT_UNIT,
35+
value: `5${HEIGHT_UNIT}px`,
3636
}))
3737
.addNode(new Node({
3838
type: 'decl',
3939
prop: 'line-height',
40-
value: '42' + WIDTH_UNIT,
40+
value: `42${WIDTH_UNIT}`,
4141
}))
4242
.addNode(new Node({
4343
type: 'decl',
@@ -48,8 +48,8 @@ test('should extract all styles', () => {
4848
).toEqual({
4949
height: '42px',
5050
width: '42px',
51-
fontSize: '5' + HEIGHT_UNIT,
52-
lineHeight: '42' + WIDTH_UNIT,
51+
fontSize: `5${HEIGHT_UNIT}px`,
52+
lineHeight: `42${WIDTH_UNIT}`,
5353
border: 'none',
5454
});
5555
});
@@ -70,7 +70,7 @@ test('should throw if container units are used on a container with width or heig
7070
.addNode(new Node({
7171
type: 'decl',
7272
prop: 'width',
73-
value: '42' + WIDTH_UNIT,
73+
value: `42${WIDTH_UNIT}px`,
7474
}))
7575
,
7676
true,
@@ -92,7 +92,7 @@ test('should throw if container units are used on a container with width or heig
9292
.addNode(new Node({
9393
type: 'decl',
9494
prop: 'height',
95-
value: '42' + HEIGHT_UNIT,
95+
value: `42${WIDTH_UNIT}px`,
9696
}))
9797
,
9898
true,
@@ -136,12 +136,12 @@ test('should extract all container unit styles', () => {
136136
.addNode(new Node({
137137
type: 'decl',
138138
prop: 'font-size',
139-
value: '5' + HEIGHT_UNIT,
139+
value: `5${HEIGHT_UNIT}px`,
140140
}))
141141
.addNode(new Node({
142142
type: 'decl',
143143
prop: 'line-height',
144-
value: '42' + WIDTH_UNIT,
144+
value: `42${WIDTH_UNIT}px`,
145145
}))
146146
.addNode(new Node({
147147
type: 'decl',
@@ -152,7 +152,7 @@ test('should extract all container unit styles', () => {
152152
true
153153
)
154154
).toEqual({
155-
lineHeight: '42' + WIDTH_UNIT,
156-
fontSize: '5' + HEIGHT_UNIT,
155+
fontSize: `5${HEIGHT_UNIT}px`,
156+
lineHeight: `42${WIDTH_UNIT}px`,
157157
});
158158
});

src/postcss/isValueUsingContainerUnits.js

+16-3
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,24 @@ import {
99
* @returns {boolean}
1010
*/
1111
export default function isValueUsingContainerUnits (value) {
12+
if (typeof value !== 'string') {
13+
return false;
14+
}
15+
16+
const match = value.toLowerCase().match(/(\d+(\.\d+)?)([a-z%]+)/i);
17+
18+
if (match === null) {
19+
return false;
20+
}
21+
22+
const unit = match[3];
23+
1224
return (
13-
typeof value === 'string' &&
25+
unit !== HEIGHT_UNIT &&
26+
unit !== WIDTH_UNIT &&
1427
(
15-
value.indexOf(HEIGHT_UNIT) !== -1 ||
16-
value.indexOf(WIDTH_UNIT) !== -1
28+
unit.indexOf(HEIGHT_UNIT) === 0 ||
29+
unit.indexOf(WIDTH_UNIT) === 0
1730
)
1831
);
1932
}

src/postcss/isValueUsingContainerUnits.spec.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ test('should report false for non-strings and string not containing container un
99
expect(isValueUsingContainerUnits({})).toBe(false);
1010
expect(isValueUsingContainerUnits([])).toBe(false);
1111
expect(isValueUsingContainerUnits('')).toBe(false);
12-
expect(isValueUsingContainerUnits('12px 23px')).toBe(false);
12+
expect(isValueUsingContainerUnits('12px 23px 33ch')).toBe(false);
13+
expect(isValueUsingContainerUnits('12ch 23vw 33%')).toBe(false);
1314
});
1415

1516
test('should report true for values using either or both container units', () => {
16-
expect(isValueUsingContainerUnits(`42${HEIGHT_UNIT}`)).toBe(true);
17-
expect(isValueUsingContainerUnits(`42${WIDTH_UNIT}`)).toBe(true);
18-
expect(isValueUsingContainerUnits(`42${WIDTH_UNIT} 42${HEIGHT_UNIT} 42${WIDTH_UNIT}`)).toBe(true);
17+
expect(isValueUsingContainerUnits(`42${HEIGHT_UNIT}px`)).toBe(true);
18+
expect(isValueUsingContainerUnits(`42${WIDTH_UNIT}px`)).toBe(true);
19+
expect(isValueUsingContainerUnits(`42${WIDTH_UNIT}px 42${HEIGHT_UNIT}px 42${WIDTH_UNIT}px`)).toBe(true);
1920
});

0 commit comments

Comments
 (0)