├── .github ├── CONTRIBUTING.md └── FUNDING.yml ├── CHANGELOG.txt ├── LICENSE.txt ├── README.md ├── custom.css ├── docs ├── CNAME ├── custom.css ├── examples │ ├── README.md │ ├── course │ │ ├── custom.css │ │ └── index.html │ ├── images │ │ ├── course-example.png │ │ └── product-example.png │ └── product │ │ ├── custom.css │ │ ├── example.png │ │ └── index.html ├── images │ └── neat-screenshot.png ├── index.html ├── neat.css └── neat.html ├── neat.css ├── neat.html ├── release.sh └── version.txt /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | If you want to contribute to _Neat_, please [create a new issue](https://github.com/codazoda/neatcss/issues/new). I do not accept direct contributions via PR. 4 | 5 | ## My Process 6 | 7 | When I work on _Neat_ I currently do the following: 8 | 9 | - New unreleased work goes into the `wip` branch 10 | - Multiple commits in an unreleased branch are great 11 | - These will be listed in the CHANGELOG.txt file 12 | - I can push my `wip` branch to master 13 | - Other fixes in a `wip:` branch are fine too 14 | - A branch is released by running `release.sh` 15 | - This merges to main, increments the version, etc. 16 | - I might need to delete the branch after release to prevent all the commits? 17 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: codazoda # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /CHANGELOG.txt: -------------------------------------------------------------------------------- 1 | 1.0.8 2 | - fix: add a v to the version so changelog output is correct 3 | - docs: update version number and docs css 4 | - doc: add a changelog to track version updates 5 | - doc: add a contributing document with some personal notes 6 | - feat: append commit messages to changelog 7 | - update: add commit messages to release script 8 | 9 | 1.0.9 10 | - fix: add previous (missed) changelog 11 | - fix: add a v to the version so changelog output is correct 12 | 13 | 1.0.10 14 | - doc: remove comment about website being behind 15 | - fix: update a simple typo on a previous commit message 16 | - fix: add changelog whitespace 17 | 18 | 1.0.11 19 | - fix: correct missing neat.html file from public site 20 | 21 | 1.0.12 22 | - doc: remove example link, another user added a section for this 23 | 24 | 1.0.13 25 | - Fix h1 line heights for long titles 26 | 27 | 1.0.14 28 | - Remove errant testing text 29 | 30 | 1.0.15 31 | - Update font to system-ui 32 | 33 | 1.0.16 34 | - Update active element to use a variable for color and adjust that color slightly 35 | - Remove link outline on click and add subtle hover color 36 | 37 | 1.0.17 38 | - Remove `only screen` from desktop sizes for better printing 39 | 40 | 1.1.1 41 | 42 | 1.1.2 43 | - docs: edit contribution instructions 44 | - fix: add the missing html opening tag 45 | - Update LICENSE.txt 46 | - add left border to blockquote 47 | 48 | 1.1.3 49 | - fix input button style 50 | 51 | 1.1.4 52 | - Add breathe class to give things breathing room 53 | 54 | 1.1.5 55 | - Fix the textarea font size 56 | - Fix minor typo in readme 57 | 58 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2025 by Joel Dare 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Neat CSS 2 | 3 | Rapidly build efficient sites with *Neat*, the minimalist css framework. See [neat.joeldare.com](https://neat.joeldare.com) for a demo, documentation and rationale. 4 | 5 | ![NeatCSS Screenshot](https://neat.joeldare.com/images/neat-screenshot.png) 6 | -------------------------------------------------------------------------------- /custom.css: -------------------------------------------------------------------------------- 1 | /* Put your custom CSS rules here */ 2 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | neat.joeldare.com -------------------------------------------------------------------------------- /docs/custom.css: -------------------------------------------------------------------------------- 1 | /* Put your custom CSS rules here */ 2 | -------------------------------------------------------------------------------- /docs/examples/README.md: -------------------------------------------------------------------------------- 1 | # Neat Examples 2 | 3 | These are example sites created with Neat, the minimalist CSS framework. 4 | 5 | ## Product 6 | 7 | ![Neat Product Example](images/product-example.png) 8 | 9 | ## Course 10 | 11 | ![Neat Course Example](images/course-example.png) 12 | -------------------------------------------------------------------------------- /docs/examples/course/custom.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --forest: seagreen; 3 | background: rgb(225, 225, 225); 4 | } 5 | 6 | /* Increase the body width */ 7 | body { 8 | max-width: 1024px; 9 | margin-top: 1em; 10 | background-color: transparent; 11 | } 12 | 13 | .card { 14 | border-radius: 25px; 15 | background-color: white; 16 | overflow: hidden; 17 | padding: 1em; 18 | box-shadow: 15px 15px 25px rgba(50, 50, 50, .25); 19 | } 20 | 21 | .price { 22 | color: gray; 23 | } 24 | 25 | .left { 26 | background-color: var(--forest); 27 | text-align: center; 28 | } 29 | 30 | .left * { 31 | color: white; 32 | } 33 | 34 | .left > h1 { 35 | padding-top: 4em; 36 | line-height: 1.2em; 37 | } 38 | 39 | .name { 40 | display: inline-block; 41 | margin: 4em auto 4em auto; 42 | border-top: 1px solid silver; 43 | border-bottom: 1px solid silver; 44 | padding: 1em; 45 | } 46 | 47 | .time { 48 | font-weight: bold; 49 | } 50 | 51 | .enroll { 52 | width: 100%; 53 | background-color: var(--forest); 54 | } 55 | 56 | /* Desktop sizes */ 57 | @media only screen and (min-height: 41em) and (min-width: 1024px) { 58 | 59 | body { 60 | margin-top: 5em; 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /docs/examples/course/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Neat Course 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 | 19 |
20 |

Some
Neat
Course

21 |

Joel Dare

22 |
23 | 24 |
25 |

Neat Course

26 |

🗓️ Monday, January 1st @ 11:00am ET (8:00am PT)

27 |

$19.00

28 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

29 |
    30 |
  • Lorem ipsum dolor
  • 31 |
  • Ut enim ad minim veniam
  • 32 |
  • Duis aute irure dolor
  • 33 |
34 |

Excepteur sint occaecat cupidatat non proident.

35 | Enroll Now 36 |
37 |
38 |
39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/examples/images/course-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codazoda/neatcss/89620874e859fcc18faa80623a707d5e1f9fa723/docs/examples/images/course-example.png -------------------------------------------------------------------------------- /docs/examples/images/product-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codazoda/neatcss/89620874e859fcc18faa80623a707d5e1f9fa723/docs/examples/images/product-example.png -------------------------------------------------------------------------------- /docs/examples/product/custom.css: -------------------------------------------------------------------------------- 1 | /* Add a little extra space at the top */ 2 | .hero { 3 | margin-top: 50px; 4 | } 5 | 6 | /* A fixed sized button */ 7 | .fixed { 8 | width: 10rem; 9 | white-space: nowrap; 10 | } 11 | 12 | /* A blue main button */ 13 | .main { 14 | background-color: #0066CC; 15 | } 16 | 17 | /* A lighter button */ 18 | .light { 19 | background-color: #999; 20 | } 21 | -------------------------------------------------------------------------------- /docs/examples/product/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codazoda/neatcss/89620874e859fcc18faa80623a707d5e1f9fa723/docs/examples/product/example.png -------------------------------------------------------------------------------- /docs/examples/product/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Neat Product 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

Neat Product

17 | 18 |

This is a product page built with Neat the mimalist CSS framework.

19 | 20 |
21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /docs/images/neat-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codazoda/neatcss/89620874e859fcc18faa80623a707d5e1f9fa723/docs/images/neat-screenshot.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Neat CSS 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |

Neat CSS

21 | 22 |

Rapidly build efficient sites with Neat, the minimalist css framework. Neat is about 3Kb and that's before it's minified and compressed.

23 | 24 |
    25 |
  1. About
  2. 26 |
  3. Getting Started
  4. 27 |
  5. Uses
  6. 28 |
  7. Customizing
  8. 29 |
  9. Design Decisions
  10. 30 |
  11. Examples
  12. 31 |
  13. Contributing
  14. 32 |
  15. GitHub
  16. 33 |
34 | 35 |

About

36 | 37 | 38 | 39 |

It's tiny, opinionated, and made to last. It's created by Joel Dare and heavily inspired by other minimalist sites like Hundred Rabbits and dozens of similar blogs.

40 | 41 |

"That's pretty neat!"

42 | 43 |

Getting Started

44 | 45 |

Grab the neat.css and neat.html files.

46 | 47 |
curl -O https://neat.joeldare.com/neat.css
 48 | curl -O https://neat.joeldare.com/neat.html
49 | 50 |

Then copy neat.html to index.html and make your changes. Use neat.html as a reference.

51 | 52 |

Uses

53 | 54 |

Neat was designed for:

55 | 56 | 64 | 65 |

Customizing

66 | 67 |

It's easy to customize Neat. The best way is to create a new custom.css file and then add the following line to the head of your page.

68 | 69 |
<link rel="stylesheet" type="text/css" href="custom.css">
70 | 71 |

That will give you the option of updating neat.css without losing any of your personalizations.

72 | 73 | 74 |

Design Decisions

75 | 76 |

Neat is opinionated and here are some of the design decisions and the rationale for each of them.

77 | 78 |

Small

79 | 80 |

In contrast with the majority of the modern web, Neat was designed to be tiny. A side-effect of being small is that it's also very fast.

81 | 82 |

Low Energy

83 | 84 |

Because it's small and fast it also consumes fewer resources. It should work well even on the slowest connections. Consuming less energy on both the client and the server.

85 | 86 |

Long-Lasting

87 | 88 |

The web is relatively young and technology changes fast but one of the technologies that has lasted as long as the Internet is HTML. There are lots of other interesting formats but plain HTML has a good chance of working well into the future.

89 | 90 |

Not Minified

91 | 92 |

Minified code requires the complexity of a transpiler and makes the site less open for inspection, learning, accessibility, and archive. The size trade-off isn't worth it for Neat.

93 | 94 |

Max Width

95 | 96 |

The body max-width is 800px by default. Research has shown that limiting the width can lead to better retention of the content itself, as well as a decrease in eye strain. A thinner column of text is more readable on very large monitors. This is simple to change by editing the max-width of the body element in your custom.css file.

97 | 98 |

Centered Body

99 | 100 |

The body is centered as of Neat 0.1.0. I use Neat as a starting point for most of my own projects and I found myself centering the body the majority of the time. As a result, the default is now centered. You can still left-align by adding margin-left and margin-right to your custom.css file.

101 | 102 |

Images

103 | 104 |

Images are 100% width by default. This works best with images that are wide and short. You can set manual sizes on individual images as it suits you or change the image width in your custom.css if you typically use a different aspect ratio.

105 | 106 |

Images have no border by default. This works well for dark colored images but light colored images can get lost. Add something like border: 3px solid #404040 if your image needs a border.

107 | 108 |

Left Gutter

109 | 110 |

If you don't center the page, the left gutter is wider at larger sizes, giving the page a little more breathing room at desktop and tablet sizes. You don't typically notice this because the default is now centered.

111 | 112 |

Buttons

113 | 114 |

There are multiple types of buttons. There are anchor tags (links) that should sometimes look like buttons, button tags, and submit style input tags.

115 | 116 |

It's best to use semantic web tags whenever possible. Buttons can be a unique case where you're often linking somewhere, but the button tag doesn't support the href attribute. So, buttons can be anchor tags with a class of button.

117 | 118 |

The html button tag is also styled in the same way. When buttons aren't links, for example when you're using JavaScript to trigger actions from button clicks, the button tag still works.

119 | 120 |

Input tags of type submit are also styled this way.

121 | 122 |
<a href="#" class="button">
123 | 124 |
<button>Button</button>
125 | 126 |
<input type="submit" value="Button">
127 | 128 |

Button

129 | 130 | 131 | 132 |

Input Fields

133 | 134 |

The input tag is styled to support light and dark themes.

135 | 136 |
<input>
137 | 138 |
139 | 140 |

No Header

141 | 142 |

Because of the complexity of the css and the distraction of navigation, there is no header and no navigation, other than the link back to the home page.

143 | 144 |

Responsive

145 | 146 |

Neat is designed to be responsive.

147 | 148 |

Grid

149 | 150 |

As of v0.1.0 Neat has a simple grid system. Each column is automatically sized. Put in four columns and you'll get four equally sized columns. All columns collapse to a single column on mobile. If you force something too large into one of the columns it will automatically grow to fit the content, shrinking the other columns. You can either avoid doing that or add something like overflow: hidden; to the .flow > * selector in your custom.css file.

151 | 152 |

Note: The column class has been removed as of v1.0.0 and all elements become columns by default. This should be backword compatible in most cases and is less code.

153 | 154 |
<div class="row">
155 |     <div>One</div>
156 |     <div>Two</div>
157 |     <div>Three</div>
158 |     <div>Four</div>
159 | </div>
160 | 161 |
162 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
163 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
164 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
165 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
166 |
167 | 168 |

Centering

169 | 170 |

You can throw the center class on almost anything you want to center, including a div tag.

171 | 172 |

Breathing Room

173 | 174 |

You can throw the breathe class on almost anything to add a bit of breathing room, including a div or p tag. This is useful for marketing page text on landing pages and footers that you want to move down a bit.

175 | 176 |

Quotes

177 | 178 |

Blockquotes now have a left border.

179 | 180 |
181 |

Hello World

182 |
183 | 184 |

Examples

185 | 186 |

Example uses of Neat can be found in the example repository.

187 | 188 |

Framework

189 | 190 |

Yes, Neat is a framework. The American Heritage Dictionary describes a framework as, "a skeletal support used as the basis for something being constructed". Wikipedia describes a CSS Framework as, "a library allowing for easier, more standards-compliant web design using the Cascading Style Sheets language." That's exactly what Neat is, a framework that I use on dozens of my own websites.

191 | 192 |

Contributing

193 | 194 |

Neat is distributed as open-source under the MIT license.

195 | 196 |

Anything related to Neat is fair game for discussion. Anyone who's interested is welcome to join in the conversation. If you find a problem or have a suggestion, feel free to create an issue on GitHub. I'm also happy to review code change requests. Feedback and discussions will lead to better ideas for future improvements.

197 | 198 |

GitHub

199 | 200 |

You'll find Neat CSS on GitHub.

201 | 202 | 203 | 204 | 205 | -------------------------------------------------------------------------------- /docs/neat.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | :root { 6 | color-scheme: light dark; 7 | --light: #fff; 8 | --lesslight: #efefef; 9 | --dark: #404040; 10 | --moredark: #000; 11 | --link: royalblue; 12 | border-top: 5px solid var(--dark); 13 | line-height: 1.5em; 14 | font-family: system-ui, sans-serif; 15 | font-size: 16px; 16 | color: var(--dark); 17 | } 18 | 19 | h1 { 20 | line-height: 1em; 21 | } 22 | 23 | button, input, textarea { 24 | font-size: 1em; /* Override browser default font shrinking*/ 25 | } 26 | 27 | input { 28 | border: 1px solid var(--dark); 29 | background-color: var(--lesslight); 30 | border-radius: .25em; 31 | padding: .5em; 32 | } 33 | 34 | pre { 35 | background-color: var(--lesslight); 36 | margin: 0.5em 0 0.5em 0; 37 | padding: 0.5em; 38 | overflow: auto; 39 | } 40 | 41 | code { 42 | background-color: var(--lesslight); 43 | } 44 | 45 | blockquote { 46 | border-left: 0.25rem solid var(--dark); 47 | padding-left: 1rem; 48 | } 49 | 50 | body { 51 | background-color: var(--light); 52 | margin: 0; 53 | max-width: 800px; 54 | padding: 0 20px 20px 20px; 55 | margin-left: auto; 56 | margin-right: auto; 57 | } 58 | 59 | a { 60 | outline: none; 61 | color: var(--dark); 62 | } 63 | 64 | a:hover { 65 | text-decoration-color: var(--link); 66 | } 67 | 68 | img { 69 | max-width: 100%; 70 | height: auto; 71 | } 72 | 73 | button, .button, input[type=submit] { 74 | display: inline-block; 75 | background-color: var(--dark); 76 | color: var(--light); 77 | text-align: center; 78 | padding: .5em; 79 | border-radius: .25em; 80 | text-decoration: none; 81 | border: none; 82 | cursor: pointer; 83 | } 84 | 85 | .button a { 86 | text-decoration: none; 87 | } 88 | 89 | button:hover, .button:hover, input[type=submit]:hover { 90 | color: var(--lesslight); 91 | background-color: var(--moredark); 92 | } 93 | 94 | /* Add a margin between side-by-side buttons */ 95 | button + button, .button + .button, input[type=submit] + input[type=submit] { 96 | margin-left: 1em; 97 | } 98 | 99 | .center { 100 | display: block; 101 | margin-left: auto; 102 | margin-right: auto; 103 | text-align: center; 104 | } 105 | 106 | .breathe { 107 | margin-top: 3em; 108 | } 109 | 110 | input.center { 111 | display: block; 112 | margin-top: 1em; 113 | } 114 | 115 | .bordered { 116 | border: 3px solid; 117 | } 118 | 119 | .home { 120 | display: inline-block; 121 | background-color: var(--dark); 122 | color: var(--light); 123 | margin-top: 20px; 124 | padding: 5px 10px 5px 10px; 125 | text-decoration: none; 126 | font-weight: bold; 127 | } 128 | 129 | 130 | /* Desktop sizes */ 131 | @media (min-width: 600px) { 132 | ol.twocol { 133 | column-count: 2; 134 | } 135 | 136 | .row { 137 | display: flex; 138 | flex-direction: row; 139 | padding: 0; 140 | width: 100%; 141 | } 142 | 143 | /* Make everything in a row a column */ 144 | .row > * { 145 | display: block; 146 | flex: 1 1 auto; 147 | max-width: 100%; 148 | width: 100%; 149 | } 150 | 151 | .row > *:not(:last-child) { 152 | margin-right: 10px; 153 | } 154 | } 155 | 156 | /* Dark mode overrides (confusingly inverse) */ 157 | @media (prefers-color-scheme: dark) { 158 | :root { 159 | --light: #222; 160 | --lesslight: #333; 161 | --dark: #eee; 162 | --moredark: #fefefe; 163 | } 164 | /* This fixes an odd blue then white shadow on FF in dark mode */ 165 | *:focus { 166 | outline: var(--light); 167 | box-shadow: 0 0 0 .25em var(--link); 168 | } 169 | .button a { 170 | color: var(--light); 171 | } 172 | } 173 | 174 | /* Printing */ 175 | @media print { 176 | .home { 177 | display: none; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /docs/neat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Neat CSS 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |

Neat CSS

21 | 22 |

Rapidly build efficient sites with Neat, the minimalist css framework. Neat is about 3Kb and that's before it's minified and compressed.

23 | 24 |
    25 |
  1. About
  2. 26 |
  3. Getting Started
  4. 27 |
  5. Uses
  6. 28 |
  7. Customizing
  8. 29 |
  9. Design Decisions
  10. 30 |
  11. Examples
  12. 31 |
  13. Contributing
  14. 32 |
  15. GitHub
  16. 33 |
34 | 35 |

About

36 | 37 | 38 | 39 |

It's tiny, opinionated, and made to last. It's created by Joel Dare and heavily inspired by other minimalist sites like Hundred Rabbits and dozens of similar blogs.

40 | 41 |

"That's pretty neat!"

42 | 43 |

Getting Started

44 | 45 |

Grab the neat.css and neat.html files.

46 | 47 |
curl -O https://neat.joeldare.com/neat.css
 48 | curl -O https://neat.joeldare.com/neat.html
49 | 50 |

Then copy neat.html to index.html and make your changes. Use neat.html as a reference.

51 | 52 |

Uses

53 | 54 |

Neat was designed for:

55 | 56 | 64 | 65 |

Customizing

66 | 67 |

It's easy to customize Neat. The best way is to create a new custom.css file and then add the following line to the head of your page.

68 | 69 |
<link rel="stylesheet" type="text/css" href="custom.css">
70 | 71 |

That will give you the option of updating neat.css without losing any of your personalizations.

72 | 73 | 74 |

Design Decisions

75 | 76 |

Neat is opinionated and here are some of the design decisions and the rationale for each of them.

77 | 78 |

Small

79 | 80 |

In contrast with the majority of the modern web, Neat was designed to be tiny. A side-effect of being small is that it's also very fast.

81 | 82 |

Low Energy

83 | 84 |

Because it's small and fast it also consumes fewer resources. It should work well even on the slowest connections. Consuming less energy on both the client and the server.

85 | 86 |

Long-Lasting

87 | 88 |

The web is relatively young and technology changes fast but one of the technologies that has lasted as long as the Internet is HTML. There are lots of other interesting formats but plain HTML has a good chance of working well into the future.

89 | 90 |

Not Minified

91 | 92 |

Minified code requires the complexity of a transpiler and makes the site less open for inspection, learning, accessibility, and archive. The size trade-off isn't worth it for Neat.

93 | 94 |

Max Width

95 | 96 |

The body max-width is 800px by default. Research has shown that limiting the width can lead to better retention of the content itself, as well as a decrease in eye strain. A thinner column of text is more readable on very large monitors. This is simple to change by editing the max-width of the body element in your custom.css file.

97 | 98 |

Centered Body

99 | 100 |

The body is centered as of Neat 0.1.0. I use Neat as a starting point for most of my own projects and I found myself centering the body the majority of the time. As a result, the default is now centered. You can still left-align by adding margin-left and margin-right to your custom.css file.

101 | 102 |

Images

103 | 104 |

Images are 100% width by default. This works best with images that are wide and short. You can set manual sizes on individual images as it suits you or change the image width in your custom.css if you typically use a different aspect ratio.

105 | 106 |

Images have no border by default. This works well for dark colored images but light colored images can get lost. Add something like border: 3px solid #404040 if your image needs a border.

107 | 108 |

Left Gutter

109 | 110 |

If you don't center the page, the left gutter is wider at larger sizes, giving the page a little more breathing room at desktop and tablet sizes. You don't typically notice this because the default is now centered.

111 | 112 |

Buttons

113 | 114 |

There are multiple types of buttons. There are anchor tags (links) that should sometimes look like buttons, button tags, and submit style input tags.

115 | 116 |

It's best to use semantic web tags whenever possible. Buttons can be a unique case where you're often linking somewhere, but the button tag doesn't support the href attribute. So, buttons can be anchor tags with a class of button.

117 | 118 |

The html button tag is also styled in the same way. When buttons aren't links, for example when you're using JavaScript to trigger actions from button clicks, the button tag still works.

119 | 120 |

Input tags of type submit are also styled this way.

121 | 122 |
<a href="#" class="button">
123 | 124 |
<button>Button</button>
125 | 126 |
<input type="submit" value="Button">
127 | 128 |

Button

129 | 130 | 131 | 132 |

Input Fields

133 | 134 |

The input tag is styled to support light and dark themes.

135 | 136 |
<input>
137 | 138 |
139 | 140 |

No Header

141 | 142 |

Because of the complexity of the css and the distraction of navigation, there is no header and no navigation, other than the link back to the home page.

143 | 144 |

Responsive

145 | 146 |

Neat is designed to be responsive.

147 | 148 |

Grid

149 | 150 |

As of v0.1.0 Neat has a simple grid system. Each column is automatically sized. Put in four columns and you'll get four equally sized columns. All columns collapse to a single column on mobile. If you force something too large into one of the columns it will automatically grow to fit the content, shrinking the other columns. You can either avoid doing that or add something like overflow: hidden; to the .flow > * selector in your custom.css file.

151 | 152 |

Note: The column class has been removed as of v1.0.0 and all elements become columns by default. This should be backword compatible in most cases and is less code.

153 | 154 |
<div class="row">
155 |     <div>One</div>
156 |     <div>Two</div>
157 |     <div>Three</div>
158 |     <div>Four</div>
159 | </div>
160 | 161 |
162 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
163 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
164 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
165 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
166 |
167 | 168 |

Centering

169 | 170 |

You can throw the center class on almost anything you want to center, including a div tag.

171 | 172 |

Breathing Room

173 | 174 |

You can throw the breathe class on almost anything to add a bit of breathing room, including a div or p tag. This is useful for marketing page text on landing pages and footers that you want to move down a bit.

175 | 176 |

Quotes

177 | 178 |

Blockquotes now have a left border.

179 | 180 |
181 |

Hello World

182 |
183 | 184 |

Examples

185 | 186 |

Example uses of Neat can be found in the example repository.

187 | 188 |

Framework

189 | 190 |

Yes, Neat is a framework. The American Heritage Dictionary describes a framework as, "a skeletal support used as the basis for something being constructed". Wikipedia describes a CSS Framework as, "a library allowing for easier, more standards-compliant web design using the Cascading Style Sheets language." That's exactly what Neat is, a framework that I use on dozens of my own websites.

191 | 192 |

Contributing

193 | 194 |

Neat is distributed as open-source under the MIT license.

195 | 196 |

Anything related to Neat is fair game for discussion. Anyone who's interested is welcome to join in the conversation. If you find a problem or have a suggestion, feel free to create an issue on GitHub. I'm also happy to review code change requests. Feedback and discussions will lead to better ideas for future improvements.

197 | 198 |

GitHub

199 | 200 |

You'll find Neat CSS on GitHub.

201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /neat.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | :root { 6 | color-scheme: light dark; 7 | --light: #fff; 8 | --lesslight: #efefef; 9 | --dark: #404040; 10 | --moredark: #000; 11 | --link: royalblue; 12 | border-top: 5px solid var(--dark); 13 | line-height: 1.5em; 14 | font-family: system-ui, sans-serif; 15 | font-size: 16px; 16 | color: var(--dark); 17 | } 18 | 19 | h1 { 20 | line-height: 1em; 21 | } 22 | 23 | button, input, textarea { 24 | font-size: 1em; /* Override browser default font shrinking*/ 25 | } 26 | 27 | input { 28 | border: 1px solid var(--dark); 29 | background-color: var(--lesslight); 30 | border-radius: .25em; 31 | padding: .5em; 32 | } 33 | 34 | pre { 35 | background-color: var(--lesslight); 36 | margin: 0.5em 0 0.5em 0; 37 | padding: 0.5em; 38 | overflow: auto; 39 | } 40 | 41 | code { 42 | background-color: var(--lesslight); 43 | } 44 | 45 | blockquote { 46 | border-left: 0.25rem solid var(--dark); 47 | padding-left: 1rem; 48 | } 49 | 50 | body { 51 | background-color: var(--light); 52 | margin: 0; 53 | max-width: 800px; 54 | padding: 0 20px 20px 20px; 55 | margin-left: auto; 56 | margin-right: auto; 57 | } 58 | 59 | a { 60 | outline: none; 61 | color: var(--dark); 62 | } 63 | 64 | a:hover { 65 | text-decoration-color: var(--link); 66 | } 67 | 68 | img { 69 | max-width: 100%; 70 | height: auto; 71 | } 72 | 73 | button, .button, input[type=submit] { 74 | display: inline-block; 75 | background-color: var(--dark); 76 | color: var(--light); 77 | text-align: center; 78 | padding: .5em; 79 | border-radius: .25em; 80 | text-decoration: none; 81 | border: none; 82 | cursor: pointer; 83 | } 84 | 85 | .button a { 86 | text-decoration: none; 87 | } 88 | 89 | button:hover, .button:hover, input[type=submit]:hover { 90 | color: var(--lesslight); 91 | background-color: var(--moredark); 92 | } 93 | 94 | /* Add a margin between side-by-side buttons */ 95 | button + button, .button + .button, input[type=submit] + input[type=submit] { 96 | margin-left: 1em; 97 | } 98 | 99 | .center { 100 | display: block; 101 | margin-left: auto; 102 | margin-right: auto; 103 | text-align: center; 104 | } 105 | 106 | .breathe { 107 | margin-top: 3em; 108 | } 109 | 110 | input.center { 111 | display: block; 112 | margin-top: 1em; 113 | } 114 | 115 | .bordered { 116 | border: 3px solid; 117 | } 118 | 119 | .home { 120 | display: inline-block; 121 | background-color: var(--dark); 122 | color: var(--light); 123 | margin-top: 20px; 124 | padding: 5px 10px 5px 10px; 125 | text-decoration: none; 126 | font-weight: bold; 127 | } 128 | 129 | 130 | /* Desktop sizes */ 131 | @media (min-width: 600px) { 132 | ol.twocol { 133 | column-count: 2; 134 | } 135 | 136 | .row { 137 | display: flex; 138 | flex-direction: row; 139 | padding: 0; 140 | width: 100%; 141 | } 142 | 143 | /* Make everything in a row a column */ 144 | .row > * { 145 | display: block; 146 | flex: 1 1 auto; 147 | max-width: 100%; 148 | width: 100%; 149 | } 150 | 151 | .row > *:not(:last-child) { 152 | margin-right: 10px; 153 | } 154 | } 155 | 156 | /* Dark mode overrides (confusingly inverse) */ 157 | @media (prefers-color-scheme: dark) { 158 | :root { 159 | --light: #222; 160 | --lesslight: #333; 161 | --dark: #eee; 162 | --moredark: #fefefe; 163 | } 164 | /* This fixes an odd blue then white shadow on FF in dark mode */ 165 | *:focus { 166 | outline: var(--light); 167 | box-shadow: 0 0 0 .25em var(--link); 168 | } 169 | .button a { 170 | color: var(--light); 171 | } 172 | } 173 | 174 | /* Printing */ 175 | @media print { 176 | .home { 177 | display: none; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /neat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Neat CSS 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |

Neat CSS

21 | 22 |

Rapidly build efficient sites with Neat, the minimalist css framework. Neat is about 3Kb and that's before it's minified and compressed.

23 | 24 |
    25 |
  1. About
  2. 26 |
  3. Getting Started
  4. 27 |
  5. Uses
  6. 28 |
  7. Customizing
  8. 29 |
  9. Design Decisions
  10. 30 |
  11. Examples
  12. 31 |
  13. Contributing
  14. 32 |
  15. GitHub
  16. 33 |
34 | 35 |

About

36 | 37 | 38 | 39 |

It's tiny, opinionated, and made to last. It's created by Joel Dare and heavily inspired by other minimalist sites like Hundred Rabbits and dozens of similar blogs.

40 | 41 |

"That's pretty neat!"

42 | 43 |

Getting Started

44 | 45 |

Grab the neat.css and neat.html files.

46 | 47 |
curl -O https://neat.joeldare.com/neat.css
 48 | curl -O https://neat.joeldare.com/neat.html
49 | 50 |

Then copy neat.html to index.html and make your changes. Use neat.html as a reference.

51 | 52 |

Uses

53 | 54 |

Neat was designed for:

55 | 56 | 64 | 65 |

Customizing

66 | 67 |

It's easy to customize Neat. The best way is to create a new custom.css file and then add the following line to the head of your page.

68 | 69 |
<link rel="stylesheet" type="text/css" href="custom.css">
70 | 71 |

That will give you the option of updating neat.css without losing any of your personalizations.

72 | 73 | 74 |

Design Decisions

75 | 76 |

Neat is opinionated and here are some of the design decisions and the rationale for each of them.

77 | 78 |

Small

79 | 80 |

In contrast with the majority of the modern web, Neat was designed to be tiny. A side-effect of being small is that it's also very fast.

81 | 82 |

Low Energy

83 | 84 |

Because it's small and fast it also consumes fewer resources. It should work well even on the slowest connections. Consuming less energy on both the client and the server.

85 | 86 |

Long-Lasting

87 | 88 |

The web is relatively young and technology changes fast but one of the technologies that has lasted as long as the Internet is HTML. There are lots of other interesting formats but plain HTML has a good chance of working well into the future.

89 | 90 |

Not Minified

91 | 92 |

Minified code requires the complexity of a transpiler and makes the site less open for inspection, learning, accessibility, and archive. The size trade-off isn't worth it for Neat.

93 | 94 |

Max Width

95 | 96 |

The body max-width is 800px by default. Research has shown that limiting the width can lead to better retention of the content itself, as well as a decrease in eye strain. A thinner column of text is more readable on very large monitors. This is simple to change by editing the max-width of the body element in your custom.css file.

97 | 98 |

Centered Body

99 | 100 |

The body is centered as of Neat 0.1.0. I use Neat as a starting point for most of my own projects and I found myself centering the body the majority of the time. As a result, the default is now centered. You can still left-align by adding margin-left and margin-right to your custom.css file.

101 | 102 |

Images

103 | 104 |

Images are 100% width by default. This works best with images that are wide and short. You can set manual sizes on individual images as it suits you or change the image width in your custom.css if you typically use a different aspect ratio.

105 | 106 |

Images have no border by default. This works well for dark colored images but light colored images can get lost. Add something like border: 3px solid #404040 if your image needs a border.

107 | 108 |

Left Gutter

109 | 110 |

If you don't center the page, the left gutter is wider at larger sizes, giving the page a little more breathing room at desktop and tablet sizes. You don't typically notice this because the default is now centered.

111 | 112 |

Buttons

113 | 114 |

There are multiple types of buttons. There are anchor tags (links) that should sometimes look like buttons, button tags, and submit style input tags.

115 | 116 |

It's best to use semantic web tags whenever possible. Buttons can be a unique case where you're often linking somewhere, but the button tag doesn't support the href attribute. So, buttons can be anchor tags with a class of button.

117 | 118 |

The html button tag is also styled in the same way. When buttons aren't links, for example when you're using JavaScript to trigger actions from button clicks, the button tag still works.

119 | 120 |

Input tags of type submit are also styled this way.

121 | 122 |
<a href="#" class="button">
123 | 124 |
<button>Button</button>
125 | 126 |
<input type="submit" value="Button">
127 | 128 |

Button

129 | 130 | 131 | 132 |

Input Fields

133 | 134 |

The input tag is styled to support light and dark themes.

135 | 136 |
<input>
137 | 138 |
139 | 140 |

No Header

141 | 142 |

Because of the complexity of the css and the distraction of navigation, there is no header and no navigation, other than the link back to the home page.

143 | 144 |

Responsive

145 | 146 |

Neat is designed to be responsive.

147 | 148 |

Grid

149 | 150 |

As of v0.1.0 Neat has a simple grid system. Each column is automatically sized. Put in four columns and you'll get four equally sized columns. All columns collapse to a single column on mobile. If you force something too large into one of the columns it will automatically grow to fit the content, shrinking the other columns. You can either avoid doing that or add something like overflow: hidden; to the .flow > * selector in your custom.css file.

151 | 152 |

Note: The column class has been removed as of v1.0.0 and all elements become columns by default. This should be backword compatible in most cases and is less code.

153 | 154 |
<div class="row">
155 |     <div>One</div>
156 |     <div>Two</div>
157 |     <div>Three</div>
158 |     <div>Four</div>
159 | </div>
160 | 161 |
162 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
163 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
164 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
165 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
166 |
167 | 168 |

Centering

169 | 170 |

You can throw the center class on almost anything you want to center, including a div tag.

171 | 172 |

Breathing Room

173 | 174 |

You can throw the breathe class on almost anything to add a bit of breathing room, including a div or p tag. This is useful for marketing page text on landing pages and footers that you want to move down a bit.

175 | 176 |

Quotes

177 | 178 |

Blockquotes now have a left border.

179 | 180 |
181 |

Hello World

182 |
183 | 184 |

Examples

185 | 186 |

Example uses of Neat can be found in the example repository.

187 | 188 |

Framework

189 | 190 |

Yes, Neat is a framework. The American Heritage Dictionary describes a framework as, "a skeletal support used as the basis for something being constructed". Wikipedia describes a CSS Framework as, "a library allowing for easier, more standards-compliant web design using the Cascading Style Sheets language." That's exactly what Neat is, a framework that I use on dozens of my own websites.

191 | 192 |

Contributing

193 | 194 |

Neat is distributed as open-source under the MIT license.

195 | 196 |

Anything related to Neat is fair game for discussion. Anyone who's interested is welcome to join in the conversation. If you find a problem or have a suggestion, feel free to create an issue on GitHub. I'm also happy to review code change requests. Feedback and discussions will lead to better ideas for future improvements.

197 | 198 |

GitHub

199 | 200 |

You'll find Neat CSS on GitHub.

201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | # Describe this script 2 | echo This script releases a feature branch by merging the current branch into 3 | echo master, tagging a new version, and pushing master up to origin. 4 | echo 5 | 6 | # Grab the current version number 7 | CURRENT=`tail -1 version.txt` 8 | NEXT=`tail -1 version.txt | awk -F. -v OFS=. 'NF==1{print ++$NF}; NF>1{$NF=sprintf("%0*d", length($NF), ($NF+1)); print}'` 9 | FEAT=`git rev-parse --abbrev-ref HEAD` 10 | 11 | # Show additional detail and wait for confirmation 12 | echo Current version: $CURRENT 13 | echo 14 | echo To change the major or minor version number: 15 | echo " echo x.x.0 >> version.txt" 16 | echo 17 | echo Releasing $FEAT branch as v$NEXT 18 | echo 19 | read -p "Press Enter to continue or Ctrl-C to stop" 20 | 21 | # Verify we aren't on master 22 | if [ "$FEAT" != "master" ]; then 23 | 24 | # Verify we don't have uncommitted changes 25 | if [[ -n $(git status -s) ]]; then 26 | echo Error: There are uncommitted changes. 27 | exit 1 28 | fi 29 | 30 | # Append an incremented version number to the version.txt file 31 | echo $NEXT >> version.txt 32 | 33 | # Append commit messages to the CHANGELOG file 34 | echo $NEXT >> CHANGELOG.txt 35 | git log v$CURRENT..HEAD --pretty=" - %s" --no-merges >> CHANGELOG.txt 36 | echo >> CHANGELOG.txt 37 | 38 | # Copy the css files to the docs file (for GH Pages) 39 | cp neat.css ./docs/ 40 | cp custom.css ./docs/ 41 | cp neat.html ./docs 42 | cp neat.html ./docs/index.html 43 | echo "" >> ./docs/index.html 44 | 45 | # Commit the changes above 46 | if ! git add .; then 47 | echo ERROR: Unable to add version and css files. 48 | exit 1 49 | fi 50 | if ! git commit -m "docs: update version number and docs css"; then 51 | echo ERROR: Unable to commit version and css files. 52 | exit 1 53 | fi 54 | 55 | # Create a release tag and push it to GitHub 56 | if ! git checkout master; then 57 | echo ERROR: Failed to checkout master. 58 | exit 1 59 | fi 60 | if ! git merge $FEAT; then 61 | echo ERROR: Failed to merge the feature branch. 62 | exit 1 63 | fi 64 | if ! git tag -a v$NEXT -m "release: v$NEXT"; then 65 | echo ERROR: Failed to tag the new version. 66 | exit 1 67 | fi 68 | if ! git push; then 69 | echo ERROR: Failed to push all commited changes. 70 | exit 1 71 | fi 72 | if ! git push --tags; then 73 | echo ERROR: Failed to push the new tag. 74 | exit 1 75 | fi 76 | 77 | # Exit with a successful code 78 | exit 0 79 | 80 | fi 81 | 82 | # Exit with an error code 83 | echo "You should be on a feature branch." 84 | exit 1 85 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 0.1.1 2 | 0.1.2 3 | 0.1.3 4 | 0.1.4 5 | 0.1.5 6 | 0.1.6 7 | 1.0.0 8 | 1.0.1 9 | 1.0.2 10 | 1.0.3 11 | 1.0.4 12 | 1.0.5 13 | 1.0.6 14 | 1.0.7 15 | 1.0.8 16 | 1.0.9 17 | 1.0.10 18 | 1.0.11 19 | 1.0.12 20 | 1.0.13 21 | 1.0.14 22 | 1.0.15 23 | 1.0.16 24 | 1.0.17 25 | 1.1.0 26 | 1.1.1 27 | 1.1.2 28 | 1.1.3 29 | 1.1.4 30 | 1.1.5 31 | --------------------------------------------------------------------------------