@anydigital/bricks 1.0.0-alpha.10
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/LICENSE +20 -0
- package/README.md +258 -0
- package/bricks/__html.css +21 -0
- package/bricks/__html.njk +17 -0
- package/bricks/_gtm.njk +18 -0
- package/bricks/_nav.njk +10 -0
- package/bricks/_prose.css +111 -0
- package/bricks/bricks.css +8 -0
- package/dist/bricks.css +199 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2013 Anton Staroverov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
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, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# *Any*bricks
|
|
2
|
+
|
|
3
|
+
Framework-agnostic CSS utilities and single-file Nunjucks 'bricks' for modern web development.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### Via CDN
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@anydigital/bricks@1/dist/bricks.css">
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Via npm
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install @anydigital/bricks
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then import in your CSS:
|
|
20
|
+
|
|
21
|
+
```css
|
|
22
|
+
@import '@anydigital/bricks';
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
### Overflow Control
|
|
28
|
+
|
|
29
|
+
Prevents horizontal overflow and scrolling on the entire page:
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
html, body {
|
|
33
|
+
overflow-x: clip;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This is automatically applied when you include the stylesheet.
|
|
38
|
+
|
|
39
|
+
### Full Viewport Height
|
|
40
|
+
|
|
41
|
+
Ensures the body element takes at least the full height of the viewport using dynamic viewport height for better mobile support:
|
|
42
|
+
|
|
43
|
+
```css
|
|
44
|
+
body {
|
|
45
|
+
min-height: 100dvh;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
This is automatically applied when you include the stylesheet.
|
|
50
|
+
|
|
51
|
+
### Typography Enhancements
|
|
52
|
+
|
|
53
|
+
Improves text rendering and readability:
|
|
54
|
+
|
|
55
|
+
```css
|
|
56
|
+
body {
|
|
57
|
+
hyphens: auto;
|
|
58
|
+
-webkit-font-smoothing: antialiased;
|
|
59
|
+
-moz-osx-font-smoothing: grayscale;
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- Automatic hyphenation for better text flow
|
|
64
|
+
- Font smoothing for cleaner text rendering across browsers
|
|
65
|
+
|
|
66
|
+
This is automatically applied when you include the stylesheet.
|
|
67
|
+
|
|
68
|
+
### Prose Styling
|
|
69
|
+
|
|
70
|
+
The `.prose` class provides enhanced typography for article content and long-form text with container-like behavior:
|
|
71
|
+
|
|
72
|
+
**Container:**
|
|
73
|
+
- Full width with `1rem` padding
|
|
74
|
+
- Centered with automatic inline margins
|
|
75
|
+
|
|
76
|
+
**Links:**
|
|
77
|
+
- Custom underline offset (`0.1em`) and thickness (`1px` default, `2px` on hover)
|
|
78
|
+
- Anchor links (starting with `#`) have no text decoration
|
|
79
|
+
- Special handling for `small`, `sup`, or `sub` elements: lighter weight (`300`) and displayed as `inline-block` to prevent underline decoration
|
|
80
|
+
|
|
81
|
+
**Headings:**
|
|
82
|
+
- `h1` with `small`, `sup`, or `sub` elements get reduced font size (`0.5em`) and lighter weight (`300`)
|
|
83
|
+
- `h2` headings (without classes) get a full-width decorative bar above them (`0.4em` height, positioned `1em` above, with `2em` top margin)
|
|
84
|
+
- `h3` headings (without classes) get a decorative gradient bar to the left (`10em` width, `0.3em` height, fading from 10% to 5% to transparent opacity)
|
|
85
|
+
- `h4` headings (without classes) get a similar decorative gradient bar but thinner (`0.2em` height)
|
|
86
|
+
|
|
87
|
+
**Tables:**
|
|
88
|
+
- Tables are displayed as blocks with horizontal scrolling
|
|
89
|
+
- On mobile (max-width: 767px), tables get `1.5em` horizontal padding
|
|
90
|
+
- Table cells have `1em` vertical padding (top and bottom)
|
|
91
|
+
- Workaround for widening columns using hidden `hr` elements (minimum width: `25ch`)
|
|
92
|
+
- Support for headings in Markdown tables using `big` elements (styled as bold italic)
|
|
93
|
+
|
|
94
|
+
**Blockquotes:**
|
|
95
|
+
- Lighter font weight (`300`)
|
|
96
|
+
- Adjacent `figcaption` elements are styled with italic text, right alignment, lighter weight (`300`), negative top margin (`-1em`), and an em dash prefix
|
|
97
|
+
|
|
98
|
+
**Usage:**
|
|
99
|
+
|
|
100
|
+
```html
|
|
101
|
+
<article class="prose">
|
|
102
|
+
<h1>Article Title</h1>
|
|
103
|
+
<p>Your content here...</p>
|
|
104
|
+
</article>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
This is automatically included when you import the stylesheet.
|
|
108
|
+
|
|
109
|
+
### Flexbox Layout
|
|
110
|
+
|
|
111
|
+
Sets up a flexible column layout structure:
|
|
112
|
+
|
|
113
|
+
```css
|
|
114
|
+
body {
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-direction: column;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
body > main {
|
|
120
|
+
flex-grow: 1;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The body becomes a flex container with column direction, and `main` elements automatically grow to fill available space. This is useful for creating sticky footers and full-height layouts.
|
|
125
|
+
|
|
126
|
+
This is automatically applied when you include the stylesheet.
|
|
127
|
+
|
|
128
|
+
### Breakout CSS
|
|
129
|
+
|
|
130
|
+
Includes [breakout-css](https://github.com/anydigital/breakout-css) utilities for breaking out images and figures beyond their container width. Use the `.breakout` class to allow elements to extend beyond their parent container:
|
|
131
|
+
|
|
132
|
+
```html
|
|
133
|
+
<div class="breakout">
|
|
134
|
+
<img src="image.jpg" alt="Description">
|
|
135
|
+
</div>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The breakout utilities support images, pictures, figures, canvas, audio, video, tables, pre, iframe, and other media elements. This is automatically included when you import the stylesheet.
|
|
139
|
+
|
|
140
|
+
## Bricks (Template Components)
|
|
141
|
+
|
|
142
|
+
The package includes reusable Nunjucks template macros in the `bricks/` directory. These are useful for common web development patterns.
|
|
143
|
+
|
|
144
|
+
### Base HTML Template (`__html.njk`)
|
|
145
|
+
|
|
146
|
+
A base HTML template that provides the essential document structure with built-in support for modern web best practices.
|
|
147
|
+
|
|
148
|
+
**Features:**
|
|
149
|
+
- HTML5 DOCTYPE with language attribute
|
|
150
|
+
- UTF-8 charset and comprehensive viewport meta tag with `viewport-fit=cover` for notched devices
|
|
151
|
+
- Dynamic title generation with site title suffix
|
|
152
|
+
- Favicon link
|
|
153
|
+
- Google Tag Manager integration (conditional on production environment)
|
|
154
|
+
- Head and body content blocks for template extension
|
|
155
|
+
|
|
156
|
+
**Usage:**
|
|
157
|
+
|
|
158
|
+
```njk
|
|
159
|
+
{% extends 'bricks/__html.njk' %}
|
|
160
|
+
|
|
161
|
+
{% block head %}
|
|
162
|
+
<!-- Additional head elements (optional) -->
|
|
163
|
+
{% endblock %}
|
|
164
|
+
|
|
165
|
+
{% block body %}
|
|
166
|
+
<!-- Your page content -->
|
|
167
|
+
{% endblock %}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Required Variables:**
|
|
171
|
+
- `title` - Page title (optional, will be stripped of HTML tags)
|
|
172
|
+
- `site.title` - Site title for the title suffix
|
|
173
|
+
- `site.gtmId` - Google Tag Manager ID (optional)
|
|
174
|
+
- `site.isProd` - Boolean flag for production environment (optional)
|
|
175
|
+
- `fromBricks` - Path to the bricks directory (optional, defaults to `'bricks/'`)
|
|
176
|
+
|
|
177
|
+
### Navigation (`_nav.njk`)
|
|
178
|
+
|
|
179
|
+
A navigation macro that renders a list of navigation links with proper accessibility attributes.
|
|
180
|
+
|
|
181
|
+
**Parameters:**
|
|
182
|
+
- `navPages` - Array of navigation page objects with `url` and `title` properties
|
|
183
|
+
- `curPageUrl` - The URL of the current page (used to set `aria-current="page"`)
|
|
184
|
+
|
|
185
|
+
**Usage:**
|
|
186
|
+
|
|
187
|
+
```njk
|
|
188
|
+
{% from "bricks/_nav.njk" import render %}
|
|
189
|
+
{{ render(navPages, page.url) }}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Example:**
|
|
193
|
+
|
|
194
|
+
```njk
|
|
195
|
+
{% set navPages = [
|
|
196
|
+
{ url: '/', title: 'Home' },
|
|
197
|
+
{ url: '/about', title: 'About' },
|
|
198
|
+
{ url: '/contact', title: 'Contact' }
|
|
199
|
+
] %}
|
|
200
|
+
{% from "bricks/_nav.njk" import render %}
|
|
201
|
+
{{ render(navPages, '/about') }}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Output:**
|
|
205
|
+
|
|
206
|
+
```html
|
|
207
|
+
<nav>
|
|
208
|
+
<a href="/">Home</a>
|
|
209
|
+
<a href="/about" aria-current="page">About</a>
|
|
210
|
+
<a href="/contact">Contact</a>
|
|
211
|
+
</nav>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Compatibility:** Compatible with [Eleventy Navigation plugin](https://www.11ty.dev/docs/plugins/navigation/#bring-your-own-html-render-the-menu-items-manually).
|
|
215
|
+
|
|
216
|
+
### Google Tag Manager (`_gtm.njk`)
|
|
217
|
+
|
|
218
|
+
A macro for embedding Google Tag Manager scripts in your pages.
|
|
219
|
+
|
|
220
|
+
**Parameters:**
|
|
221
|
+
- `gtmId` - Your Google Tag Manager container ID (e.g., `GTM-XXXXXXX`)
|
|
222
|
+
- `bodyFallback` - Boolean flag (default: `false`). When `false`, renders the script tag for the `<head>`. When `true`, renders the noscript fallback for the `<body>`.
|
|
223
|
+
|
|
224
|
+
**Usage:**
|
|
225
|
+
|
|
226
|
+
In your base template's `<head>`:
|
|
227
|
+
|
|
228
|
+
```njk
|
|
229
|
+
{% import "bricks/_gtm.njk" as gtm %}
|
|
230
|
+
{{ gtm.render(site.gtmId) }}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
In your base template's `<body>` (right after the opening tag):
|
|
234
|
+
|
|
235
|
+
```njk
|
|
236
|
+
{{ gtm.render(site.gtmId, bodyFallback=true) }}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Example:**
|
|
240
|
+
|
|
241
|
+
```njk
|
|
242
|
+
<!DOCTYPE html>
|
|
243
|
+
<html>
|
|
244
|
+
<head>
|
|
245
|
+
{% import "bricks/_gtm.njk" as gtm %}
|
|
246
|
+
{{ gtm.render('GTM-XXXXXXX') }}
|
|
247
|
+
</head>
|
|
248
|
+
<body>
|
|
249
|
+
{{ gtm.render('GTM-XXXXXXX', bodyFallback=true) }}
|
|
250
|
+
<!-- Your content -->
|
|
251
|
+
</body>
|
|
252
|
+
</html>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## License
|
|
256
|
+
|
|
257
|
+
MIT
|
|
258
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* Prevent horizontal overflow and scrolling, modern way */
|
|
2
|
+
html, body {
|
|
3
|
+
overflow-x: clip;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
body {
|
|
7
|
+
/* Ensures body takes at least the full height of the viewport (using dynamic viewport height for better mobile support) */
|
|
8
|
+
min-height: 100dvh;
|
|
9
|
+
|
|
10
|
+
/* Enable hyphenation and font smoothing for better typography */
|
|
11
|
+
hyphens: auto;
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
-moz-osx-font-smoothing: grayscale;
|
|
14
|
+
|
|
15
|
+
/* Make the body a flex container with column layout; main fills space */
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
> main {
|
|
19
|
+
flex-grow: 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{%- set fromBricks = fromBricks | default('bricks/') -%}
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover">
|
|
7
|
+
<title>{{ title | striptags ~ ' | ' if title }}{{ site.title }}</title>
|
|
8
|
+
<link rel="icon" href="/favicon.ico">
|
|
9
|
+
{% block head %}{% endblock %}
|
|
10
|
+
{% import fromBricks ~ '_gtm.njk' as gtm %}
|
|
11
|
+
{{ gtm.render(site.gtmId) if site.gtmId and site.isProd }}
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
{{ gtm.render(site.gtmId, bodyFallback=true) if site.gtmId and site.isProd }}
|
|
15
|
+
{% block body %}{% endblock %}
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
package/bricks/_gtm.njk
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{% macro render(gtmId, bodyFallback=false) %}
|
|
2
|
+
|
|
3
|
+
{% if not bodyFallback %}
|
|
4
|
+
<!-- Google Tag Manager -->
|
|
5
|
+
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
6
|
+
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
7
|
+
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
8
|
+
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
9
|
+
})(window,document,'script','dataLayer','{{ gtmId }}');</script>
|
|
10
|
+
<!-- End Google Tag Manager -->
|
|
11
|
+
{% else %}
|
|
12
|
+
<!-- Google Tag Manager (noscript) -->
|
|
13
|
+
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{ gtmId }}"
|
|
14
|
+
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
|
15
|
+
<!-- End Google Tag Manager (noscript) -->
|
|
16
|
+
{% endif %}
|
|
17
|
+
|
|
18
|
+
{% endmacro %}
|
package/bricks/_nav.njk
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{% macro render(navPages, curPageUrl) %}
|
|
2
|
+
<nav>
|
|
3
|
+
{%- for entry in navPages %}
|
|
4
|
+
<a href="{{ entry.url }}" {{ 'aria-current="page"' | safe if entry.url == curPageUrl }}>
|
|
5
|
+
{{- entry.title -}}
|
|
6
|
+
</a>
|
|
7
|
+
{%- endfor %}
|
|
8
|
+
</nav>
|
|
9
|
+
{% endmacro %}
|
|
10
|
+
{# Compatible with https://www.11ty.dev/docs/plugins/navigation/#bring-your-own-html-render-the-menu-items-manually #}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
.prose {
|
|
2
|
+
/* Container-like behavior with padding and auto margins */
|
|
3
|
+
width: 100%;
|
|
4
|
+
padding: 1rem;
|
|
5
|
+
margin-inline: auto;
|
|
6
|
+
|
|
7
|
+
a {
|
|
8
|
+
text-underline-offset: 0.1em;
|
|
9
|
+
text-decoration-thickness: 1px;
|
|
10
|
+
/* Don't underline links that point to anchors */
|
|
11
|
+
&[href^="#"] {
|
|
12
|
+
text-decoration: none;
|
|
13
|
+
}
|
|
14
|
+
&:hover {
|
|
15
|
+
text-decoration-thickness: 2px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
small, sup, sub {
|
|
19
|
+
font-weight: 300;
|
|
20
|
+
/* Workaround to prevent underline */
|
|
21
|
+
display: inline-block;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
h1 {
|
|
26
|
+
small, sup, sub {
|
|
27
|
+
font-size: 0.5em;
|
|
28
|
+
font-weight: 300;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
h2:not([class]),
|
|
33
|
+
h3:not([class]),
|
|
34
|
+
h4:not([class]) {
|
|
35
|
+
position: relative;
|
|
36
|
+
|
|
37
|
+
&::before {
|
|
38
|
+
content: '';
|
|
39
|
+
display: block;
|
|
40
|
+
position: absolute;
|
|
41
|
+
background-color: rgba(0,0,0,5%);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
h2:not([class]) {
|
|
45
|
+
margin-top: 2em;
|
|
46
|
+
|
|
47
|
+
&::before {
|
|
48
|
+
width: 100vw;
|
|
49
|
+
left: 50%;
|
|
50
|
+
height: 0.4em;
|
|
51
|
+
top: -1em;
|
|
52
|
+
transform: translateX(-50%);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
h3:not([class]),
|
|
56
|
+
h4:not([class]) {
|
|
57
|
+
&::before {
|
|
58
|
+
width: 10em;
|
|
59
|
+
right: 100%;
|
|
60
|
+
margin-right: 0.5em;
|
|
61
|
+
height: 0.3em;
|
|
62
|
+
top: 50%;
|
|
63
|
+
transform: translateY(-50%);
|
|
64
|
+
background: linear-gradient(to left, rgba(0,0,0,10%), rgba(0,0,0,5%) 10%, transparent);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
h4:not([class]) {
|
|
68
|
+
&::before {
|
|
69
|
+
height: 0.2em;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
table {
|
|
74
|
+
display: block;
|
|
75
|
+
overflow-x: auto;
|
|
76
|
+
@media (max-width: 767px) {
|
|
77
|
+
padding-inline: 1.5em;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
th, td {
|
|
81
|
+
padding-top: 1em;
|
|
82
|
+
padding-bottom: 1em;
|
|
83
|
+
/* Workaround to widen particular columns */
|
|
84
|
+
hr {
|
|
85
|
+
min-width: 25ch;
|
|
86
|
+
margin: 0;
|
|
87
|
+
visibility: hidden;
|
|
88
|
+
}
|
|
89
|
+
/* Workaround for headings in Markdown tables */
|
|
90
|
+
big {
|
|
91
|
+
font-weight: bold;
|
|
92
|
+
font-style: italic;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
blockquote {
|
|
97
|
+
font-weight: 300;
|
|
98
|
+
|
|
99
|
+
+ figcaption {
|
|
100
|
+
margin-top: -1em;
|
|
101
|
+
text-align: right;
|
|
102
|
+
font-style: italic;
|
|
103
|
+
font-weight: 300;
|
|
104
|
+
|
|
105
|
+
&::before {
|
|
106
|
+
content: '—';
|
|
107
|
+
margin-right: 0.25em;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
package/dist/bricks.css
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @anydigital/bricks
|
|
3
|
+
* Framework-agnostic CSS utility helpers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* Prevent horizontal overflow and scrolling, modern way */
|
|
7
|
+
|
|
8
|
+
html, body {
|
|
9
|
+
overflow-x: clip;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
body {
|
|
13
|
+
/* Ensures body takes at least the full height of the viewport (using dynamic viewport height for better mobile support) */
|
|
14
|
+
min-height: 100dvh;
|
|
15
|
+
|
|
16
|
+
/* Enable hyphenation and font smoothing for better typography */
|
|
17
|
+
hyphens: auto;
|
|
18
|
+
-webkit-font-smoothing: antialiased;
|
|
19
|
+
-moz-osx-font-smoothing: grayscale;
|
|
20
|
+
|
|
21
|
+
/* Make the body a flex container with column layout; main fills space */
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
body > main {
|
|
27
|
+
flex-grow: 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.prose {
|
|
31
|
+
/* Container-like behavior with padding and auto margins */
|
|
32
|
+
width: 100%;
|
|
33
|
+
padding: 1rem;
|
|
34
|
+
margin-inline: auto;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.prose a {
|
|
38
|
+
text-underline-offset: 0.1em;
|
|
39
|
+
text-decoration-thickness: 1px;
|
|
40
|
+
/* Don't underline links that point to anchors */
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.prose a[href^="#"] {
|
|
44
|
+
text-decoration: none;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.prose a:hover {
|
|
48
|
+
text-decoration-thickness: 2px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.prose a small,.prose a sup,.prose a sub {
|
|
52
|
+
font-weight: 300;
|
|
53
|
+
/* Workaround to prevent underline */
|
|
54
|
+
display: inline-block;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.prose h1 small,.prose h1 sup,.prose h1 sub {
|
|
58
|
+
font-size: 0.5em;
|
|
59
|
+
font-weight: 300;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.prose h2:not([class]),.prose h3:not([class]),.prose h4:not([class]) {
|
|
63
|
+
position: relative;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.prose h2:not([class])::before {
|
|
67
|
+
content: '';
|
|
68
|
+
display: block;
|
|
69
|
+
position: absolute;
|
|
70
|
+
background-color: rgba(0,0,0,5%);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.prose h3:not([class])::before {
|
|
74
|
+
content: '';
|
|
75
|
+
display: block;
|
|
76
|
+
position: absolute;
|
|
77
|
+
background-color: rgba(0,0,0,5%);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.prose h4:not([class])::before {
|
|
81
|
+
content: '';
|
|
82
|
+
display: block;
|
|
83
|
+
position: absolute;
|
|
84
|
+
background-color: rgba(0,0,0,5%);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.prose h2:not([class]) {
|
|
88
|
+
margin-top: 2em;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.prose h2:not([class])::before {
|
|
92
|
+
width: 100vw;
|
|
93
|
+
left: 50%;
|
|
94
|
+
height: 0.4em;
|
|
95
|
+
top: -1em;
|
|
96
|
+
transform: translateX(-50%);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.prose h3:not([class])::before {
|
|
100
|
+
width: 10em;
|
|
101
|
+
right: 100%;
|
|
102
|
+
margin-right: 0.5em;
|
|
103
|
+
height: 0.3em;
|
|
104
|
+
top: 50%;
|
|
105
|
+
transform: translateY(-50%);
|
|
106
|
+
background: linear-gradient(to left, rgba(0,0,0,10%), rgba(0,0,0,5%) 10%, transparent);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.prose h4:not([class])::before {
|
|
110
|
+
width: 10em;
|
|
111
|
+
right: 100%;
|
|
112
|
+
margin-right: 0.5em;
|
|
113
|
+
height: 0.3em;
|
|
114
|
+
top: 50%;
|
|
115
|
+
transform: translateY(-50%);
|
|
116
|
+
background: linear-gradient(to left, rgba(0,0,0,10%), rgba(0,0,0,5%) 10%, transparent);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.prose h4:not([class])::before {
|
|
120
|
+
height: 0.2em;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.prose table {
|
|
124
|
+
display: block;
|
|
125
|
+
overflow-x: auto;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@media (max-width: 767px) {
|
|
129
|
+
|
|
130
|
+
.prose table {
|
|
131
|
+
padding-inline: 1.5em;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.prose th,.prose td {
|
|
136
|
+
padding-top: 1em;
|
|
137
|
+
padding-bottom: 1em;
|
|
138
|
+
/* Workaround to widen particular columns */
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.prose th hr,.prose td hr {
|
|
142
|
+
min-width: 25ch;
|
|
143
|
+
margin: 0;
|
|
144
|
+
visibility: hidden;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* Workaround for headings in Markdown tables */
|
|
148
|
+
|
|
149
|
+
.prose th big,.prose td big {
|
|
150
|
+
font-weight: bold;
|
|
151
|
+
font-style: italic;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.prose blockquote {
|
|
155
|
+
font-weight: 300;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.prose blockquote + figcaption {
|
|
159
|
+
margin-top: -1em;
|
|
160
|
+
text-align: right;
|
|
161
|
+
font-style: italic;
|
|
162
|
+
font-weight: 300;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.prose blockquote + figcaption::before {
|
|
166
|
+
content: '—';
|
|
167
|
+
margin-right: 0.25em;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* Breakout CSS - Framework-agnostic utilities for breaking out images and figures */
|
|
171
|
+
|
|
172
|
+
.breakout {
|
|
173
|
+
padding-inline: 10%;
|
|
174
|
+
|
|
175
|
+
/* Direct children, or wrapped in <p> for Markdown support */
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.breakout > img:not(does-not-exist):not(.does-not-exist),.breakout > picture:not(does-not-exist):not(.does-not-exist),.breakout > figure:not(does-not-exist):not(.does-not-exist),.breakout > canvas:not(does-not-exist):not(.does-not-exist),.breakout > audio:not(does-not-exist):not(.does-not-exist),.breakout > table:not(does-not-exist):not(.does-not-exist),.breakout > pre:not(does-not-exist):not(.does-not-exist),.breakout > iframe:not(does-not-exist):not(.does-not-exist),.breakout > object:not(does-not-exist):not(.does-not-exist),.breakout > embed:not(does-not-exist):not(.does-not-exist),.breakout > video:not(does-not-exist):not(.does-not-exist),.breakout > .breakout-item:not(does-not-exist),.breakout > .breakout-item-max:not(does-not-exist),.breakout > p > img:not(.does-not-exist),.breakout > p > picture:not(.does-not-exist),.breakout > p > figure:not(.does-not-exist),.breakout > p > canvas:not(.does-not-exist),.breakout > p > audio:not(.does-not-exist),.breakout > p > table:not(.does-not-exist),.breakout > p > pre:not(.does-not-exist),.breakout > p > iframe:not(.does-not-exist),.breakout > p > object:not(.does-not-exist),.breakout > p > embed:not(.does-not-exist),.breakout > p > video:not(.does-not-exist),.breakout > p > .breakout-item,.breakout > p > .breakout-item-max {
|
|
179
|
+
width: -moz-fit-content;
|
|
180
|
+
width: fit-content;
|
|
181
|
+
min-width: 100%;
|
|
182
|
+
max-width: 125%;
|
|
183
|
+
margin-left: 50%;
|
|
184
|
+
transform: translateX(-50%);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Respect inline blocks' min-width */
|
|
188
|
+
|
|
189
|
+
.breakout > img:not(does-not-exist),.breakout > picture:not(does-not-exist),.breakout > figure:not(does-not-exist),.breakout > canvas:not(does-not-exist),.breakout > audio:not(does-not-exist),.breakout > p > img,.breakout > p > picture,.breakout > p > figure,.breakout > p > canvas,.breakout > p > audio {
|
|
190
|
+
min-width: auto;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/* Max out the width of the element */
|
|
194
|
+
|
|
195
|
+
.breakout > .breakout-item-max:not(does-not-exist),.breakout > p > .breakout-item-max {
|
|
196
|
+
width: 125% !important; /* @TODO: !important for cases like figure.breakout-item-max */
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* @TODO: Allow non-direct children. */
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@anydigital/bricks",
|
|
3
|
+
"version": "1.0.0-alpha.10",
|
|
4
|
+
"description": "Framework-agnostic CSS utilities and single-file Nunjucks 'bricks' for modern web development.",
|
|
5
|
+
"main": "dist/bricks.css",
|
|
6
|
+
"style": "dist/bricks.css",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"bricks"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"postcss": "postcss bricks/bricks.css -o dist/bricks.css",
|
|
13
|
+
"build": "npm run postcss -- --no-map",
|
|
14
|
+
"start": "npm run postcss -- --watch",
|
|
15
|
+
"prepublishOnly": "npm run build"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/anydigital/bricks.git"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"css",
|
|
23
|
+
"utilities",
|
|
24
|
+
"helpers",
|
|
25
|
+
"atomic",
|
|
26
|
+
"cdn"
|
|
27
|
+
],
|
|
28
|
+
"author": "Anton Staroverov",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@anydigital/breakout-css": "^1.0.0-alpha.7",
|
|
32
|
+
"postcss": "^8.4.33",
|
|
33
|
+
"postcss-cli": "^11.0.0",
|
|
34
|
+
"postcss-import": "^16.1.1",
|
|
35
|
+
"postcss-preset-env": "^10.6.0"
|
|
36
|
+
},
|
|
37
|
+
"jsdelivr": "dist/bricks.css",
|
|
38
|
+
"unpkg": "dist/bricks.css"
|
|
39
|
+
}
|