├── .gitignore ├── .prettierrc.yaml ├── .stylelintignore ├── .stylelintrc.yaml ├── README.md ├── package-lock.json ├── package.json └── src ├── index.html ├── js └── scripts.js └── sass ├── _buttons.scss ├── _card.scss ├── _layout.scss ├── _reset.scss ├── _theme.scss ├── _typography.scss ├── _utilities.scss └── style.scss /.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache 2 | .sass-cache/* 3 | *.scssc 4 | *.log 5 | .htaccess 6 | node_modules/ 7 | public/ 8 | src/css/style.css 9 | -------------------------------------------------------------------------------- /.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | printWidth: 100 2 | trailingComma: all 3 | arrowParens: always 4 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | _reset.scss 3 | _typography.scss 4 | public/ 5 | src/index.html -------------------------------------------------------------------------------- /.stylelintrc.yaml: -------------------------------------------------------------------------------- 1 | extends: 2 | - stylelint-config-standard 3 | - stylelint-config-prettier 4 | plugins: 5 | - stylelint-selector-bem-pattern 6 | - stylelint-scss 7 | - stylelint-order 8 | rules: 9 | # Wrap lines greater than 120 characters 10 | max-line-length: 120 11 | # Override stylelint-config-standard - we only use CSS comments for annotations that don't warrant an empty line 12 | comment-empty-line-before: null 13 | # Follow best practices 14 | font-family-name-quotes: always-where-recommended 15 | # https://stackoverflow.com/a/34383157/467582 16 | function-url-quotes: always 17 | # https://www.w3.org/TR/selectors/#attribute-selectors 18 | # http://stackoverflow.com/q/3851091 19 | selector-attribute-quotes: always 20 | # Double-quotes are our convention throughout our codebase within (S)CSS. They also reflect how 21 | # attribute strings are normally quoted within the DOM. 22 | string-quotes: double 23 | order/order: 24 | - - type: at-rule 25 | hasBlock: false 26 | - custom-properties 27 | - declarations 28 | - unspecified: ignore 29 | disableFix: true 30 | # https://github.com/sasstools/sass-lint/blob/develop/lib/config/property-sort-orders/smacss.yml 31 | order/properties-order: 32 | - display 33 | - position 34 | - top 35 | - right 36 | - bottom 37 | - left 38 | 39 | - flex 40 | - flex-basis 41 | - flex-direction 42 | - flex-flow 43 | - flex-grow 44 | - flex-shrink 45 | - flex-wrap 46 | - align-content 47 | - align-items 48 | - align-self 49 | - justify-content 50 | - order 51 | 52 | - box-sizing 53 | 54 | - width 55 | - min-width 56 | - max-width 57 | 58 | - height 59 | - min-height 60 | - max-height 61 | 62 | - margin 63 | - margin-top 64 | - margin-right 65 | - margin-bottom 66 | - margin-left 67 | 68 | - padding 69 | - padding-top 70 | - padding-right 71 | - padding-bottom 72 | - padding-left 73 | 74 | - float 75 | - clear 76 | 77 | - resize 78 | 79 | - columns 80 | - column-count 81 | - column-gap 82 | - column-fill 83 | - column-rule 84 | - column-span 85 | - column-width 86 | 87 | - grid-gap 88 | - grid-template-columns 89 | 90 | - animation 91 | - animation-name 92 | - animation-timing-function 93 | 94 | - transform 95 | - transform-box 96 | - transform-origin 97 | - transform-style 98 | 99 | - transition 100 | - transition-delay 101 | - transition-duration 102 | - transition-property 103 | - transition-timing-function 104 | 105 | # Border 106 | 107 | - border 108 | - border-top 109 | - border-right 110 | - border-bottom 111 | - border-left 112 | - border-width 113 | - border-top-width 114 | - border-right-width 115 | - border-bottom-width 116 | - border-left-width 117 | 118 | - border-style 119 | - border-top-style 120 | - border-right-style 121 | - border-bottom-style 122 | - border-left-style 123 | 124 | - border-radius 125 | - border-top-left-radius 126 | - border-top-right-radius 127 | - border-bottom-left-radius 128 | - border-bottom-right-radius 129 | 130 | - border-color 131 | - border-top-color 132 | - border-right-color 133 | - border-bottom-color 134 | - border-left-color 135 | 136 | - outline 137 | - outline-color 138 | - outline-offset 139 | - outline-style 140 | - outline-width 141 | 142 | # Background 143 | 144 | - background 145 | - background-attachment 146 | - background-clip 147 | - background-color 148 | - background-image 149 | - background-repeat 150 | - background-position 151 | - background-size 152 | 153 | - fill 154 | 155 | - opacity 156 | 157 | # Text 158 | 159 | - color 160 | 161 | - font 162 | - font-family 163 | - font-size 164 | - font-smoothing 165 | - font-style 166 | - font-variant 167 | - font-weight 168 | 169 | - letter-spacing 170 | - line-height 171 | - list-style 172 | 173 | - text-align 174 | - text-decoration 175 | - text-indent 176 | - text-overflow 177 | - text-rendering 178 | - text-shadow 179 | - text-transform 180 | - text-wrap 181 | 182 | - white-space 183 | - word-spacing 184 | 185 | # Cursor 186 | 187 | - cursor 188 | - pointer-events 189 | - user-select 190 | 191 | # Other 192 | 193 | - appearance 194 | - border-collapse 195 | - border-spacing 196 | - box-shadow 197 | - caption-side 198 | - content 199 | - empty-cells 200 | - overflow 201 | - overflow-x 202 | - overflow-y 203 | - quotes 204 | - speak 205 | - table-layout 206 | - vertical-align 207 | - visibility 208 | - will-change 209 | - z-index 210 | declaration-property-unit-allowed-list: 211 | font-size: 212 | - "rem" 213 | - "em" 214 | # The following prefix rules are enabled since we use autoprefixer 215 | at-rule-no-vendor-prefix: true 216 | media-feature-name-no-vendor-prefix: true 217 | selector-no-vendor-prefix: true 218 | value-no-vendor-prefix: true 219 | # Usually if you're nesting past 3 levels deep there's a problem 220 | max-nesting-depth: 3 221 | # Because we adhere to BEM we can limit the amount of necessary compound selectors. Most should 222 | # just be 1 level selector. However, modifiers can introduce an additional compound selector. 223 | # Furthermore, generic qualifying selectors (e.g. `[dir="rtl"]`) can introduce yet another level. 224 | selector-max-compound-selectors: 4 225 | # For specificity: disallow IDs (0). Allow for complex combinations of classes, pseudo-classes, 226 | # attribute modifiers based on selector-max-compound-selectors, plus an addition for 227 | # pseudo-classes (4). Allow for pseudo-elements (1). 228 | selector-max-specificity: 0,4,1 229 | at-rule-no-unknown: 230 | - true 231 | - ignoreAtRules: 232 | - at-root 233 | - content 234 | - each 235 | - else 236 | - error 237 | - for 238 | - function 239 | - include 240 | - if 241 | - mixin 242 | - return 243 | - warn 244 | # Disallow "@extend" in scss. 245 | # http://csswizardry.com/2016/02/mixins-better-for-performance/ 246 | # http://vanseodesign.com/css/sass-mixin-or-extend/ 247 | # Besides performance, @extend actually *changes* the selector precedence by creating a compound 248 | # selector, which can lead to ambiguous results. 249 | at-rule-disallowed-list: 250 | - extend 251 | # Extremely useful for typos, and anything emergent can be ignored by this rule 252 | property-no-unknown: 253 | - true 254 | - ignoreProperties: 255 | - contain 256 | # There is no reason that a specific ID would be needed for UI components 257 | selector-max-id: 0 258 | # Qualifying types are not needed when using a naming system like BEM 259 | selector-no-qualifying-type: true 260 | # In general, we should not be modifying elements within our components, since we can't 261 | # predict the use cases in which users would add a certain type of element into a component. 262 | selector-max-type: 263 | - 0 264 | - ignoreTypes: 265 | - /fieldset/ 266 | - /img/ 267 | # Styles for components should never need the universal selector. 268 | selector-max-universal: 0 269 | # Ensure any defined symbols are prefixed with "brand-" OR "u-" 270 | custom-media-pattern: ^tdbc-.+ 271 | custom-property-pattern: ^tdbc-.+ 272 | selector-class-pattern: 273 | - ^tdbc-.+ 274 | - resolveNestedSelectors: true 275 | selector-id-pattern: ^tdbc-.+ 276 | # Names are more semantic than numbers 277 | font-weight-notation: named-where-possible 278 | # http://www.paulirish.com/2010/the-protocol-relative-url/ 279 | function-url-no-scheme-relative: true 280 | # TODO: and FIXME: warnings are super useful because they remind us that we should address these 281 | # within our codebase 282 | comment-word-disallowed-list: 283 | - - /^TODO:/ 284 | - /^FIXME:/ 285 | - severity: warning 286 | # Part of google's style guide 287 | number-leading-zero: always 288 | at-rule-empty-line-before: 289 | - always 290 | - except: 291 | - blockless-after-blockless 292 | - first-nested 293 | ignore: 294 | - after-comment 295 | ignoreAtRules: 296 | - else 297 | declaration-empty-line-before: 298 | - always 299 | - except: 300 | - after-declaration 301 | - first-nested 302 | ignore: 303 | - after-comment 304 | block-closing-brace-newline-after: 305 | - always 306 | - ignoreAtRules: 307 | - if 308 | - else 309 | 310 | # We use Harry Roberts' BEM dialect as our preferred way to format classes. 311 | # See: http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/ 312 | # See: https://github.com/postcss/postcss-bem-linter/blob/c59db3f/lib/preset-patterns.js#L39 313 | plugin/selector-bem-pattern: 314 | componentName: ^[a-z]+(?:-[a-z]+)*$ 315 | # -__*--*[]* 316 | componentSelectors: ^\.tdbc-{componentName}(?:__[a-z]+(?:-[a-z]+)*)*(?:--[a-z]+(?:-[a-z]+)*)*(?:\[.+\])*$ 317 | ignoreSelectors: 318 | - ^fieldset 319 | - ^\[aria\-disabled=(?:.+)\] 320 | - ^img 321 | 322 | # SCSS naming patterns, just like our CSS conventions above. 323 | # (note for $-vars we use a leading underscore for "private" variables) 324 | scss/dollar-variable-pattern: 325 | - ^_?tdbc-.+ 326 | - ignore: local 327 | scss/at-function-pattern: ^tdbc-.+ 328 | scss/at-mixin-pattern: ^tdbc-.+ 329 | # Prevents unneeded nesting selectors 330 | scss/selector-no-redundant-nesting-selector: true 331 | # Since leading underscores are not needed, they can be omitted 332 | scss/at-import-no-partial-leading-underscore: true 333 | # Since mixins are explicit (`@include`) and parens are unnecessary for argumentless mixins, they 334 | # can be omitted. 335 | scss/at-else-closing-brace-newline-after: always-last-in-chain 336 | scss/at-else-closing-brace-space-after: always-intermediate 337 | scss/at-else-empty-line-before: never 338 | scss/at-if-closing-brace-newline-after: always-last-in-chain 339 | scss/at-if-closing-brace-space-after: always-intermediate 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HTML / Sass Jumpstart 2 | 3 | > dart sass powered, includes stylelint and prettier, and autoprefix upon build. develop script includes hot-reload via browsersync. 4 | 5 | ## Includes Minimal Theme and Components 6 | 7 | [**View the documentation >**](https://5t3ph.github.io/html-sass-jumpstart/) available on Github pages, as well as the `index.html` file once you load the project. 8 | 9 | ## Getting Started 10 | 11 | 1. Select "Use this template" to copy this project into your own new repo. 12 | 13 | 2. _Optional:_ Run a find/replace for `tdbc` to update to your preferred prefix (or adjust stylelint settings). 14 | 15 | 3. You can customize the `theme` Sass directly, or place overrides to variables at the top of the main `style.scss` file before the `theme` file is imported. 16 | 17 | 4. Then continue with the `develop` script and build something rad :) 18 | 19 | ## Development Scripts 20 | 21 | **`npm start`** 22 | 23 | > Serve with hot reload at localhost:1337 24 | 25 | **`npm run build`** 26 | 27 | > Generate minified, autoprefixed CSS for production 28 | 29 | Use this as the "Publish command" if needed by hosting such as Netlify. 30 | 31 | **`npm run serve`** 32 | 33 | > Serve latest build files at localhost:1337 34 | 35 | ## Linting 36 | 37 | Linting is provided by [Stylelint](https://stylelint.io/) and rules are extended from [stylelint-config-standard](https://github.com/stylelint/stylelint-config-standard) and [prettier-stylelint](https://github.com/hugomrdias/prettier-stylelint) 38 | 39 | ### Lint Script 40 | 41 | **`npm run lint`** 42 | 43 | > Run stylelint and review errors in terminal 44 | 45 | **`npm run lint:fix`** 46 | 47 | > Run stylelint with the fix flag to attempt to resolve found errors 48 | 49 | ## Feedback welcome! 50 | 51 | You can [file it as an issue](https://github.com/5t3ph/html-sass-jumpstart/issues). 52 | 53 | [![Buy me a coffee](https://cdn.buymeacoffee.com/buttons/default-violet.png)](https://www.buymeacoffee.com/moderncss) 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tdbc-html-sass-jumpstart", 3 | "description": "node-sass jumpstart with stylelint", 4 | "version": "0.4.0", 5 | "main": "public/index.html", 6 | "author": "5t3ph", 7 | "scripts": { 8 | "scss": "sass src/sass:public/css", 9 | "css": "postcss public/css/*.css -u autoprefixer cssnano -r -m", 10 | "copy:html": "copyfiles -u 1 ./src/*.html ./src/**/*.html public", 11 | "copy:js": "copyfiles -u 1 ./src/js/*.js public", 12 | "watch:html": "onchange 'src/*.html' 'src/**/*.html' -- npm run copy:html", 13 | "watch:sass": "sass --watch src/sass:public/css", 14 | "watch:js": "onchange 'src/js/*.js' -- npm run copy:js", 15 | "watch": "npm-run-all --parallel watch:*", 16 | "serve": "browser-sync start --server public --files public --port 1337", 17 | "start": "npm-run-all copy:* scss --parallel watch serve", 18 | "build": "npm-run-all copy:* scss css", 19 | "lint": "stylelint 'src/sass/**/*.scss' 'src/sass/**/**/*.scss' 'src/sass/**/**/**/*.scss'", 20 | "lint:fix": "stylelint --fix 'src/sass/**/*.scss' 'src/sass/**/**/*.scss' 'src/sass/**/**/**/*.scss'", 21 | "bump": "npm --no-git-tag-version version" 22 | }, 23 | "dependencies": { 24 | "autoprefixer": "^9.8.6", 25 | "browser-sync": "^2.26.12", 26 | "copyfiles": "^2.3.0", 27 | "cssnano": "^4.1.10", 28 | "npm-run-all": "^4.1.5", 29 | "onchange": "^7.0.2", 30 | "postcss-cli": "^7.1.2", 31 | "sass": "^1.26.10", 32 | "stylelint": "^13.7.0", 33 | "stylelint-config-prettier": "^8.0.2", 34 | "stylelint-config-standard": "^20.0.0", 35 | "stylelint-order": "^4.1.0", 36 | "stylelint-scss": "^3.18.0", 37 | "stylelint-selector-bem-pattern": "^2.1.0" 38 | }, 39 | "browserslist": [ 40 | "last 2 versions" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | HTML / Sass Jumpstart 8 | 9 | 13 | 17 | 18 | 19 | 20 | 21 |
22 |
23 | 30 | v0.4.0 - Updated 9.7.20 31 |

Minimal Sass / HTML Template Site

32 |

33 | dart sass powered, includes stylelint and prettier, and autoprefix upon build. Develop 34 | script includes hot-reload via browsersync. Themeable and scalable. 35 |

36 |

37 | Created by Stephanie Eckles 38 |

39 | 40 | 41 | Generate New Repo 42 | View Documentation 47 | 48 |
49 |
50 | 51 |
52 |
53 |

h2: This page shows a composite of available styles

54 |

h3: Gzipped minified styles - 2.2kb

55 |

h4: Base minimal theme with easy overrides

56 | 57 |

58 | lead: Use semantic HTML, and layer in a handful of classes as needed. 59 | Uses BEM class naming format, but reasonable element styles are also included. 60 |

61 | 62 | Jump to Documentation 65 | 66 |
67 |

Colophon

68 |

69 | Hi! I'm Stephanie Eckles - @5t3ph on Twitter, Github, CodePen, and DEV. You may know me as the author of ModernCSS.dev and creator of StyleStage.dev. I can also be found on egghead as an instructor. I've been a frontend developer for 13+ years, and this jumpstart is a mashup of things learned and tested. I hope you find it useful, and I'm happy to hear any feedback! 70 |

71 |
72 | 73 |

Pssst - there's an 11ty jumpstart, too! Check it out >

74 |
75 | 76 | 77 |
    78 |
  • 79 |
    80 | Review the Documentation 83 | 90 |
    91 |
  • 92 |
  • 93 |
    94 | Learn Web Development 95 |

    96 | Go from zero to website launch - no prior development experience required! Through 97 | this series of 4-14 minute videos, you will learn the essentials of web development. 98 |

    99 | 103 | 104 | 105 | Start Now 110 |
    111 |
  • 112 |
  • 113 | corgi 114 |
    115 | Upgrade Your CSS Game 116 |

    117 | Review my series "Modern CSS Solutions for Old CSS Problems" to bring your CSS skills 118 | up-to-date. 119 |

    120 |

    The site is built on this jumpstart!

    121 | Read the First Post 126 |
    127 |
  • 128 |
129 | 130 |
131 |

Initial Setup

132 | 133 |
    134 |
  1. Generate a repo from this template which will copy this project into your own new repo.
  2. 135 |
  3. Clone, and then optionally do a find/replace for tdbc to update to your preferred prefix (or adjust stylelint settings).
  4. 136 |
  5. Review the README for development and linting scripts.
  6. 137 |
138 | 139 |
140 | 141 |

Theme System

142 |

143 | The theme system includes base color values, typography sizes, and handful of other reusable 144 | utility variables. 145 |

146 | 147 |

Overriding Theme Variables

148 | 149 |

150 | The theme variables listed in each section, such as $tdbc-color-background, 151 | can easily be overridden. Simply redefine the variable with your new value prior the 152 | import of the theme file, which is the first import in the main 153 | style.scss file since the variables are used in the other imports. 154 |

155 | 156 |

157 | You can of course modify the theme file directly, but overrides are handy for 158 | testing the theme out or if you plan to reuse this template for multiple projects, or 159 | across multiple page templates. 160 |

161 | 162 |

Colors

163 | 164 |

Color Function

165 | 166 |

167 | You can access theme colors within your custom styles using the 168 | tdbc-color() function which takes the name of any colors and returns the 169 | defined value. This makes the colors extensible without copying color codes directly. 170 |

171 | 172 |

Color Options and Values

173 | 184 |
    185 |
  • 186 | #171392 187 | $tdbc-color-primary .tdbc-[ink|background]--primary 188 |
  • 189 |
  • 190 | #df2b7c 191 | $tdbc-color-secondary 192 | .tdbc-[ink|background]--secondary 193 |
  • 194 |
  • 195 | #f9f9f9 196 | $tdbc-color-background 197 | .tdbc-background 198 |
  • 199 |
  • 200 | * #252450 203 | $tdbc-color-body .tdbc-ink--text 204 |
  • 205 |
  • 206 | * #5e5d6b 209 | $tdbc-color-gray .tdbc-[ink|background]--gray 210 |
  • 211 |
  • 212 | #fff 215 | $tdbc-color-light .tdbc-[ink|background]--light 216 |
  • 217 |
  • 218 | rgba(black, 0.87) 223 | $tdbc-color-dark .tdbc-ink--dark 224 |
  • 225 |
  • 226 | Link default: 227 | $tdbc-link-color: tdbc-color("primary") 228 |
  • 229 |
230 | 231 |

232 | * These values are computed from the $tdbc-color-primary value unless 234 | overridden 236 |

237 | 238 |

Color Maps

239 |

240 | Maps are provided to selectively generate `ink` and `background` colors to allow you to 241 | reduce total generated classes if you aren't using some of them. 242 |

243 |

244 | Add/remove to selectively generate `ink` (text color) classes:
245 | $tdbc-ink-colors: "primary", "secondary", "text", "gray", "light", "dark"; 246 |

247 |

248 | Add/remove to selectively generate `background` classes:
249 | $tdbc-background-colors: "primary", "secondary", "background", "gray", "light"; 250 |

251 | 252 |

Typography

253 | 254 |

255 | Update the font family by removing or changing the Google font stylesheet 256 | link in the index, and then update the font stack on the 257 | $tdbc-font-family variable. The included font is 258 | Baloo 2. 259 |

260 |
    261 |
  • 262 | Headline h1 263 | $tdbc-h1-font-size h1 | .tdbc-h1 264 |
  • 265 |
  • 266 | Headline h2 267 | $tdbc-h2-font-size h2 | .tdbc-h2 268 |
  • 269 |
  • 270 | Headline h3 271 | $tdbc-h3-font-size h3 | .tdbc-h3 272 |
  • 273 |
  • 274 | Headline h4 275 | $tdbc-h4-font-size h4 | .tdbc-h4 276 |
  • 277 |
  • 278 | lead - utility 279 | $tdbc-lead-font-size .tdbc-lead 280 |
  • 281 |
  • 282 | text 283 | $tdbc-text-font-size p | li 284 |
  • 285 |
  • 286 | Text alignment: 287 | .tdbc-text-align--[left|center|right] 288 |
  • 289 |
290 | 291 |

Components

292 | 293 |

Buttons

294 | 295 |

296 | All buttons require the base .tdbc-button class, which by default is a 297 | filled-in button using the primary color as background. 298 |

299 | 300 |

301 | Add/remove to selectively generate button colors variants:
302 | $tdbc-button-variants: "primary", "secondary", "light", "gray"; 303 |

304 | 305 |

Apply a color with a class structured as .tdbc-button--[color] where `color` is one of the available variants from the map.

306 | 307 |
308 | default 309 | secondary 310 | light 311 | gray 312 |
313 | 314 |

A second variant of .tdbc-button-outlined is available.

315 | 316 |
317 | default 318 | secondary 323 | light 328 | gray 331 |
332 | 333 |

Reduce button size with .tdbc-button--small. Add icons (svg preferred) inside span.tdbc-button__icon, with added .tdbc-button__icon--end if it follows the button text.

334 | 335 | 360 | 361 |

Cards

362 | 363 |

It is recommended to use a ul to contain card items.

364 | 365 |

366 | Use of the class .tdbc-column-container on the containing element will enable a 367 | responsive grid layout. 368 |

369 | 370 |

Basic Card

371 | 372 |
373 |
374 |             
375 | <ul class="tdbc-column-container">
376 |   <li class="tdbc-card">
377 |     <div class="tdbc-card__content">
378 |       <span class="tdbc-card__title">
379 |         Card Title
380 |       </span>
381 |       <p>Any content here.</p>
382 |     </div>
383 |   </li>
384 | </ul>
385 |             
386 |           
387 |
    388 |
  • 389 |
    390 | 391 | Card Title 392 | 393 |

    Any content here.

    394 |
    395 |
  • 396 |
397 |
398 | 399 |

Image Header

400 | 401 |

Insert an image as the first element prior to the content and it will be auto-styled.

402 | 403 |
404 |
405 |             
406 | <ul class="tdbc-column-container">
407 |   <li class="tdbc-card">
408 |     <img src="https://source.unsplash.com/400x400/?corgi" alt="pupper" />
409 |     <div class="tdbc-card__content">
410 |       <span class="tdbc-card__title">
411 |         Card Title
412 |       </span>
413 |       <p>Any content here.</p>
414 |     </div>
415 |   </li>
416 | </ul>
417 |             
418 |           
419 |
    420 |
  • 421 | pupper 422 |
    423 | 424 | Card Title 425 | 426 |

    Any content here.

    427 |
    428 |
  • 429 |
430 |
431 | 432 |

Outlined Variant

433 | 434 |

435 | Include the .tdbc-card--outlined class to remove the `box-shadow` and 436 | `background-color`. 437 |

438 | 439 |
440 |
441 |             
442 | <ul class="tdbc-column-container">
443 |   <li class="tdbc-card tdbc-card--outlined">
444 |     <div class="tdbc-card__content">
445 |       <span class="tdbc-card__title">
446 |         Outlined Card
447 |       </span>
448 |       <p>Any content here.</p>
449 |     </div>
450 |   </li>
451 | </ul>
452 |             
453 |           
454 |
    455 |
  • 456 |
    457 | 458 | Outlined Card 459 | 460 |

    Any content here.

    461 |
    462 |
  • 463 |
464 |
465 | 466 |

Clickable Card

467 | 468 |

469 | Use of a link element for the title will expand the clickable area of the card while still 470 | allowing interaction on any paragraph content. 471 |

472 | 473 |
474 |
475 |             
476 | <ul class="tdbc-column-container">
477 |   <li class="tdbc-card">
478 |     <div class="tdbc-card__content">
479 |       <a class="tdbc-card__title">
480 |         Clickable Card
481 |       </a>
482 |       <p>Any content here.</p>
483 |     </div>
484 |   </li>
485 | </ul>
486 |             
487 |           
488 | 498 |
499 | 500 |

Layout

501 | 502 |

Inherited Element Styles

503 | 504 |

Minimal element styles are placed on the following:

505 | 506 |
    507 |
  • body: notably - display: flex; flex-direction: column;
  • 508 |
  • main: vertical padding
  • 509 |
  • 510 | footer: auto top margin 511 | to prevent floating up 514 |
  • 515 |
  • article: max-width: 80ch;
  • 516 |
  • typography elements: h1-h4, p, ul, li, code, pre, strong, blockquote
  • 517 |
  • hr
  • 518 |
519 | 520 |

Layout Containers

521 | 522 |

523 | A full-featured grid system is not provided, but a few container classes are given to help 524 | with common content layout scenarios. 525 |

526 | 527 |

.tdbc-container

528 | 529 |

530 | A flexbox container with column direction to wrap sections you wish to center within the viewport and limit the width 531 | (default 120ch). 532 |

533 | 534 |

.tdbc-column-container

535 | 536 |

537 | A grid container that responsively allows for 1+ responsive auto-fit columns with grid-gap: 1rem and min-width: 25ch. 538 |

539 | 540 |

If placed within .tdbc-container there will be up to four columns on large viewports. If not contained, there will be as many as the viewport allows.

541 | 542 |

.tdbc-section

543 | 544 |

545 | Given the body is flex layout, enforces a full-width section for when you 546 | want to apply a different background color, for instance. Also clears bottom margin from 547 | the last child. 548 |

549 | 550 |

551 | Use the .tdbc-section--padded modifier to add vertical space (default 552 | 10vh). 553 |

554 | 555 |

.tdbc-row

556 | 557 |

558 | Sets up grid layout for viewports of min-width: 80ch to 559 | grid-auto-flow: column; grid-auto-columns: max-content;. Essentially allows a 560 | row of side-by-side elements without width constraints, including a gap of `1rem`. 561 |

562 | 563 |

Modifiers available:

564 | 565 |
    566 |
  • .tdbc-row--center-content - horizontally centers content
  • 567 |
  • .tdbc-row--center-alignitems - vertically centers content
  • 568 |
569 | 570 |

.tdbc-hero

571 | 572 |

573 | A zippy utility that uses grid to vertically and horizontally center child elements, and 574 | adds min-height: 40vh. Suggested use is to wrap 575 | .tdbc-container.tdbc-content-maxlength 576 | 577 | 578 |

Layout Utilities

579 | 580 |

Available utilties primarily various spacing modifications.

581 | 582 |

.tdbc-content-maxlength

583 | 584 |

585 | While the article element is inherently limited, selectively apply this 586 | limitation to other elements (default 80ch). 587 |

588 | 589 |

Margin Spacing Classes

590 | 591 |

A select set of margin classes are available using "t-shirt sizing" on the following default scale which can be overridden:

592 | 593 |
594 |           
595 | $tdbc-spacing: (
596 |   "sm": 1rem,
597 |   "md": 3rem,
598 |   "lg": 6rem,
599 |   "xl": 10rem,
600 |   "auto": "auto",
601 | );
602 |           
603 |         
604 | 605 |

Available margin class structures:

606 | 607 |
    608 |
  • .tdbc-mx-auto - auto horizontal margin
  • 609 |
  • .tdbc-mt-[size] - top margin using value of size key
  • 610 |
  • .tdbc-mb-none - remove margin bottom
  • 611 |
612 | 613 |

Margin classes have been selectively created to be general use case without cluttering and bloating the final stylesheet. If you wish to alter them, they are generated in the utilities file.

614 | 615 |

Recommended Base Page Layout

616 | 617 |

Update colors as desired and layer in other elements as needed.

618 | 619 |

620 | <header class="tdbc-hero tdbc-background--gray tdbc-ink--light">
621 |   <h1>Page Hero</h1>
622 | </header>
623 | <main class="tdbc-container">
624 |   <article class="tdbc-mx-auto tdbc-section--padded">
625 |     <h2>Article title</h2>
626 |     <p>Cookie jelly-o sweet apple pie croissant tart croissant. Dragée biscuit sweet roll cake halvah chupa chups muffin gummies croissant. Chocolate bar candy pastry brownie powder. Macaroon icing fruitcake tootsie roll cotton candy chocolate sesame snaps pastry.</p>
627 |   </article>
628 | </main>
629 | <footer class="tdbc-section tdbc-background--gray">
630 |   <div class="tdbc-container tdbc-text-align--center">
631 |     <p class="tdbc-ink--light">
632 |       &copy; YYYY Name
633 |     </p>
634 | </footer>
635 |         
636 | 637 | 642 |
643 |
644 |

Page Hero

645 |
646 |
647 |
648 |

Article title

649 |

Cookie jelly-o sweet apple pie croissant tart croissant. Dragée biscuit sweet roll cake halvah chupa chups muffin gummies croissant. Chocolate bar candy pastry brownie powder. Macaroon icing fruitcake tootsie roll cotton candy chocolate sesame snaps pastry.

650 |
651 |
652 |
653 |
654 |

655 | © YYYY Name 656 |

657 |
658 |
659 | 660 | 661 |
662 |
663 | 673 | 674 | 675 | 676 | -------------------------------------------------------------------------------- /src/js/scripts.js: -------------------------------------------------------------------------------- 1 | // placeholder -------------------------------------------------------------------------------- /src/sass/_buttons.scss: -------------------------------------------------------------------------------- 1 | .tdbc-button { 2 | display: inline-flex; 3 | align-items: center; 4 | align-self: start; 5 | justify-content: center; 6 | min-width: 10ch; 7 | min-height: 44px; 8 | padding: 0.25em 1em; 9 | transition: 180ms ease-in-out; 10 | transition-property: background, border; 11 | border-radius: $tdbc-border-radius/2; 12 | background-color: tdbc-color("primary"); 13 | color: #fff; 14 | font-size: 1.125rem; 15 | line-height: 1.1; 16 | text-align: center; 17 | text-decoration: none; 18 | cursor: pointer; 19 | 20 | @media screen and (-ms-high-contrast: active) { 21 | border: 2px solid currentColor; 22 | } 23 | 24 | &:focus { 25 | outline-color: transparent; 26 | outline-style: solid; 27 | box-shadow: 0 0 0 3px scale-color(tdbc-color("primary"), $lightness: -30%); 28 | } 29 | 30 | &--small { 31 | min-height: 34px; 32 | font-size: 1rem; 33 | } 34 | 35 | &--center { 36 | align-self: center; 37 | margin-right: auto; 38 | margin-left: auto; 39 | } 40 | 41 | &__icon { 42 | width: 1.5em; 43 | height: 1.5em; 44 | margin-right: 0.25em; 45 | 46 | &--end { 47 | margin-right: 0; 48 | margin-left: 0.25em; 49 | } 50 | 51 | // stylelint-disable-next-line selector-max-type 52 | svg { 53 | width: 100%; 54 | height: 100%; 55 | fill: currentColor; 56 | } 57 | } 58 | 59 | &-outlined { 60 | border: 2px solid tdbc-color("primary"); 61 | background-color: transparent; 62 | color: tdbc-color("primary"); 63 | 64 | &:hover, 65 | &:focus { 66 | background-color: scale-color(tdbc-color("primary"), $lightness: 80%); 67 | } 68 | } 69 | 70 | // stylelint-disable max-nesting-depth 71 | @each $key in $tdbc-button-variants { 72 | $color: tdbc-color($key); 73 | 74 | @if ($key != "primary") { 75 | &--#{$key} { 76 | background-color: $color; 77 | 78 | @if ($key == "light") { 79 | color: tdbc-color("dark"); 80 | } 81 | 82 | &:focus { 83 | box-shadow: 0 0 0 3px scale-color($color, $lightness: -30%); 84 | } 85 | } 86 | 87 | &-outlined--#{$key} { 88 | border-color: scale-color($color, $lightness: 30%, $saturation: 15%); 89 | color: $color; 90 | 91 | &:focus { 92 | box-shadow: 0 0 0 3px scale-color($color, $lightness: -30%); 93 | } 94 | 95 | @if ($key == "light") { 96 | &:hover, 97 | &:focus { 98 | background-color: rgba($color, 0.15); 99 | } 100 | } @else { 101 | &:hover, 102 | &:focus { 103 | background-color: scale-color($color, $lightness: 90%); 104 | } 105 | } 106 | } 107 | } 108 | } 109 | // stylelint-enable 110 | } 111 | -------------------------------------------------------------------------------- /src/sass/_card.scss: -------------------------------------------------------------------------------- 1 | .tdbc-card { 2 | display: flex; 3 | position: relative; 4 | flex-direction: column; 5 | width: 100%; 6 | border-radius: $tdbc-border-radius; 7 | background-color: #fff; 8 | box-shadow: 0 3px 5px rgba(0, 0, 0, 0.18); 9 | 10 | &__title { 11 | margin-bottom: 1rem; 12 | font-size: $tdbc-h4-font-size; 13 | line-height: 1.15; 14 | text-decoration: none; 15 | } 16 | 17 | /* stylelint-disable selector-max-type, selector-no-qualifying-type */ 18 | a.tdbc-card__title { 19 | &::before { 20 | position: absolute; 21 | top: 0; 22 | left: 0; 23 | width: 100%; 24 | height: 100%; 25 | transition: 180ms box-shadow ease-in; 26 | border-radius: 8px; 27 | content: ""; 28 | } 29 | 30 | &:focus { 31 | outline: none; 32 | 33 | &::before { 34 | box-shadow: 0 0 0 3px tdbc-color("primary"); 35 | } 36 | } 37 | } 38 | 39 | &__content { 40 | display: flex; 41 | position: relative; 42 | flex-direction: column; 43 | flex-grow: 1; 44 | padding: 24px; 45 | 46 | a:last-child { 47 | align-self: start; 48 | margin-top: auto; 49 | } 50 | 51 | p { 52 | position: relative; 53 | margin: 0 0 1rem; 54 | z-index: 1; 55 | } 56 | 57 | > ul { 58 | list-style-type: disc; 59 | padding-left: 1rem; 60 | 61 | li + li { 62 | margin-top: 0.5rem; 63 | } 64 | } 65 | } 66 | 67 | &:hover a.tdbc-card__title::before { 68 | box-shadow: 0 0 0 3px tdbc-color("primary"); 69 | } 70 | 71 | img:first-child { 72 | object-fit: cover; 73 | max-height: 10em; 74 | border-radius: $tdbc-border-radius $tdbc-border-radius 0 0; 75 | } 76 | // stylelint-enable 77 | 78 | &--outlined { 79 | border: 1px solid scale-color($tdbc-color-gray, $lightness: 50%); 80 | background-color: transparent; 81 | box-shadow: none; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/sass/_layout.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable-next-line selector-max-type 2 | body { 3 | display: flex; 4 | flex-direction: column; 5 | min-height: 100vh; 6 | background-color: tdbc-color("background"); 7 | color: $tdbc-color-body; 8 | font-family: $tdbc-font-family; 9 | } 10 | 11 | // stylelint-disable selector-max-type, selector-no-qualifying-type 12 | main, 13 | main.tdbc-container { 14 | padding-top: 5vh; 15 | padding-bottom: 5vh; 16 | } 17 | 18 | footer { 19 | margin-top: auto; 20 | } 21 | 22 | article { 23 | max-width: 80ch; 24 | 25 | > img { 26 | margin-right: auto; 27 | margin-left: auto; 28 | } 29 | } 30 | // stylelint-enable 31 | 32 | .tdbc-container { 33 | display: flex; 34 | flex-direction: column; 35 | max-width: 120ch; 36 | margin-right: auto; 37 | margin-left: auto; 38 | padding: 1rem; 39 | } 40 | 41 | .tdbc-column-container { 42 | display: grid; 43 | grid-gap: 2em; 44 | grid-template-columns: repeat(auto-fit, minmax(25ch, 1fr)); 45 | } 46 | 47 | // stylelint-disable-next-line selector-no-qualifying-type, selector-max-type 48 | ul.tdbc-column-container { 49 | padding-left: 0; 50 | } 51 | 52 | .tdbc-section { 53 | width: 100%; 54 | 55 | &--padded { 56 | padding-top: 10vh; 57 | padding-bottom: 10vh; 58 | } 59 | 60 | // stylelint-disable-next-line selector-max-universal 61 | *:last-child { 62 | margin-bottom: 0; 63 | } 64 | } 65 | 66 | .tdbc-hero { 67 | display: grid; 68 | min-height: 40vh; 69 | place-content: center; 70 | padding-top: 10vh; 71 | padding-bottom: 10vh; 72 | text-align: center; 73 | } 74 | 75 | .tdbc-row { 76 | display: grid; 77 | grid-gap: 1rem; 78 | 79 | @media (min-width: 80ch) { 80 | grid-auto-flow: column; 81 | grid-auto-columns: max-content; 82 | } 83 | 84 | &--center-content { 85 | justify-content: center; 86 | } 87 | 88 | &--center-alignitems { 89 | align-items: center; 90 | } 91 | } 92 | 93 | // stylelint-disable-next-line selector-max-type 94 | hr { 95 | margin-top: 4rem; 96 | margin-bottom: 4rem; 97 | border: 1px solid tdbc-color("secondary"); 98 | } 99 | -------------------------------------------------------------------------------- /src/sass/_reset.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * [Modified] Modern CSS Reset 3 | * @link https://github.com/hankchizljaw/modern-css-reset 4 | */ 5 | 6 | /* Box sizing rules */ 7 | *, 8 | *::before, 9 | *::after { 10 | box-sizing: border-box; 11 | } 12 | 13 | /* Remove default margin */ 14 | body, 15 | h1, 16 | h2, 17 | h3, 18 | h4, 19 | h5, 20 | h6 { 21 | margin: 0; 22 | } 23 | 24 | p, 25 | li, 26 | h1, 27 | h2, 28 | h3, 29 | h4 { 30 | // Help prevent overflow of long words/names/URLs 31 | word-break: break-word; 32 | 33 | // Optional, not supported for all languages 34 | // hyphens: auto; 35 | } 36 | 37 | html, 38 | body { 39 | overflow-x: hidden; 40 | } 41 | 42 | html { 43 | scroll-behavior: smooth; 44 | } 45 | 46 | /* Set core body defaults */ 47 | body { 48 | min-height: 100vh; 49 | font-family: sans-serif; 50 | font-size: 100%; 51 | line-height: 1.5; 52 | text-rendering: optimizeSpeed; 53 | } 54 | 55 | /* Make images easier to work with */ 56 | img { 57 | display: block; 58 | max-width: 100%; 59 | } 60 | 61 | /* Inherit fonts for inputs and buttons */ 62 | input, 63 | button, 64 | textarea, 65 | select { 66 | font: inherit; 67 | } 68 | 69 | /* Remove all animations and transitions for people that prefer not to see them */ 70 | @media (prefers-reduced-motion: reduce) { 71 | *, 72 | *::before, 73 | *::after { 74 | animation-duration: 0.01ms !important; 75 | animation-iteration-count: 1 !important; 76 | transition-duration: 0.01ms !important; 77 | scroll-behavior: auto !important; 78 | } 79 | 80 | html { 81 | scroll-behavior: initial; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/sass/_theme.scss: -------------------------------------------------------------------------------- 1 | $tdbc-color-primary: #171392 !default; 2 | $tdbc-color-secondary: #db0a76 !default; 3 | $tdbc-color-background: #f9f9f9; 4 | 5 | $tdbc-brand-colors: ( 6 | "primary": $tdbc-color-primary, 7 | "secondary": $tdbc-color-secondary, 8 | ) !default; 9 | 10 | $tdbc-color-body: scale-color($tdbc-color-primary, $lightness: -30%, $saturation: -50%) !default; 11 | $tdbc-color-gray: mix(#767676, $tdbc-color-body, 70%) !default; 12 | 13 | $tdbc-colors: map-merge( 14 | $tdbc-brand-colors, 15 | ( 16 | "text": $tdbc-color-body, 17 | "background": $tdbc-color-background, 18 | "light": #fff, 19 | "dark": rgba(black, 0.87), 20 | "gray": $tdbc-color-gray, 21 | ) 22 | ); 23 | 24 | @function tdbc-color($key) { 25 | @return map-get($tdbc-colors, $key); 26 | } 27 | 28 | // Add/remove to selectively generate `ink` (text color) classes 29 | $tdbc-ink-colors: "primary", "secondary", "text", "gray", "light", "dark" !default; 30 | 31 | // Add/remove to selectively generate `background` (text color) classes 32 | $tdbc-background-colors: "primary", "secondary", "background", "gray", "light" !default; 33 | 34 | $tdbc-button-variants: "primary", "secondary", "light", "gray" !default; 35 | $tdbc-link-color: tdbc-color("primary") !default; 36 | $tdbc-border-radius: 8px !default; 37 | 38 | $tdbc-font-family: "Baloo 2", sans-serif; 39 | $tdbc-strong-font-weight: 500 !default; 40 | $tdbc-h1-font-size: 4.2rem !default; 41 | $tdbc-h2-font-size: 3.15rem !default; 42 | $tdbc-h3-font-size: 2rem !default; 43 | $tdbc-h4-font-size: 1.35rem !default; 44 | $tdbc-text-font-size: 1.15rem !default; 45 | $tdbc-lead-font-size: 1.35rem !default; 46 | 47 | $tdbc-spacing: ( 48 | sm: 1rem, 49 | md: 3rem, 50 | lg: 6rem, 51 | xl: 10rem, 52 | auto: "auto", 53 | ) !default; 54 | -------------------------------------------------------------------------------- /src/sass/_typography.scss: -------------------------------------------------------------------------------- 1 | $tdbc-typography-variants: h1, h2, h3, h4; 2 | 3 | @each $type in $tdbc-typography-variants { 4 | #{$type}, 5 | .tdbc-#{$type} { 6 | font-weight: $tdbc-strong-font-weight; 7 | line-height: 1.15; 8 | margin-bottom: 0.65em; 9 | } 10 | } 11 | 12 | // As of v0.3.0, `clamp` not well enough supported on mobile browsers for use 13 | // Due to build-in min/max Sass functions, requires `unquote()` to correctly 14 | // render as CSS min/max 15 | h1, 16 | .tdbc-h1 { 17 | font-size: $tdbc-h1-font-size; 18 | font-size: unquote("min(max(3rem, 5vw), #{$tdbc-h1-font-size})"); 19 | } 20 | 21 | h2, 22 | .tdbc-h2 { 23 | font-size: $tdbc-h2-font-size; 24 | font-size: unquote("min(max(2.5rem, 5vw), #{$tdbc-h2-font-size})"); 25 | } 26 | 27 | h3, 28 | .tdbc-h3 { 29 | font-size: $tdbc-h3-font-size; 30 | } 31 | 32 | h4, 33 | .tdbc-h4 { 34 | font-size: $tdbc-h4-font-size; 35 | color: tdbc-color("gray"); 36 | } 37 | 38 | p, 39 | li { 40 | font-size: $tdbc-text-font-size; 41 | } 42 | 43 | p { 44 | margin: 0 0 1rem; 45 | } 46 | 47 | article { 48 | > ul, 49 | > ol { 50 | > li + li { 51 | margin-top: 1rem; 52 | } 53 | } 54 | 55 | * { 56 | + h2 { 57 | margin-top: 4rem; 58 | } 59 | 60 | + h3 { 61 | margin-top: 2rem; 62 | } 63 | } 64 | } 65 | 66 | strong { 67 | font-weight: $tdbc-strong-font-weight; 68 | } 69 | 70 | a:not(.tdbc-button) { 71 | color: $tdbc-link-color; 72 | } 73 | 74 | pre, 75 | code { 76 | font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; 77 | font-weight: bold; 78 | } 79 | 80 | code { 81 | display: inline-flex; 82 | padding: 0.15em; 83 | background-color: tdbc-color("light"); 84 | font-size: 0.75em; 85 | color: tdbc-color("gray"); 86 | border: 1px solid scale-color(tdbc-color("gray"), $lightness: 50%); 87 | border-radius: 2px; 88 | line-height: 1.1; 89 | } 90 | 91 | pre { 92 | margin: 0; 93 | display: inline-block; 94 | 95 | code { 96 | display: block; 97 | padding: 0 1rem; 98 | white-space: pre-wrap; 99 | font-size: 0.85rem; 100 | line-height: 1.4; 101 | overflow-x: auto; 102 | } 103 | } 104 | 105 | blockquote { 106 | margin-left: 0; 107 | margin-right: 0; 108 | padding-left: 1.5rem; 109 | border-left: 2px solid tdbc-color("secondary"); 110 | color: tdbc-color("gray"); 111 | 112 | &, 113 | p { 114 | font-size: $tdbc-h4-font-size; 115 | } 116 | 117 | + * { 118 | margin-top: 3rem; 119 | } 120 | } 121 | 122 | .tdbc-lead { 123 | font-size: $tdbc-lead-font-size; 124 | letter-spacing: 0.01em; 125 | margin-bottom: 1em; 126 | line-height: 1.3; 127 | } 128 | 129 | .tdbc-list-unstyled { 130 | list-style: none; 131 | padding: 0; 132 | } 133 | -------------------------------------------------------------------------------- /src/sass/_utilities.scss: -------------------------------------------------------------------------------- 1 | .tdbc-content-maxlength { 2 | max-width: 80ch; 3 | } 4 | 5 | $tdbc-alignments: left, center, right !default; 6 | 7 | @each $alignment in $tdbc-alignments { 8 | .tdbc-text-align--#{$alignment} { 9 | text-align: #{$alignment}; 10 | 11 | @if ($alignment == "center") { 12 | > a { 13 | align-self: center !important; 14 | } 15 | } 16 | } 17 | } 18 | 19 | @each $key in $tdbc-background-colors { 20 | .tdbc-background--#{$key} { 21 | background-color: tdbc-color($key); 22 | } 23 | } 24 | 25 | @each $key in $tdbc-ink-colors { 26 | .tdbc-ink--#{$key}, 27 | a.tdbc-ink--#{$key} { 28 | color: tdbc-color(#{$key}); 29 | } 30 | 31 | .tdbc-ink--#{$key} > a:not(.tdbc-button) { 32 | color: inherit; 33 | } 34 | } 35 | 36 | .tdbc-mx-auto { 37 | margin-right: auto; 38 | margin-left: auto; 39 | } 40 | 41 | @each $key, $unit in $tdbc-spacing { 42 | .tdbc-mt-#{$key} { 43 | margin-top: $unit; 44 | } 45 | } 46 | 47 | .tdbc-mb-none { 48 | margin: 0; 49 | } 50 | -------------------------------------------------------------------------------- /src/sass/style.scss: -------------------------------------------------------------------------------- 1 | @import "theme"; 2 | @import "reset"; 3 | @import "layout"; 4 | @import "typography"; 5 | @import "buttons"; 6 | @import "card"; 7 | @import "utilities"; 8 | --------------------------------------------------------------------------------