├── .eleventy.js ├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── _11ty └── filters.js ├── _data └── site.json ├── _includes └── layouts │ ├── base.liquid │ └── post.liquid ├── about.md ├── contribute.md ├── index.njk ├── package-lock.json ├── package.json ├── plugins └── sass │ ├── index.js │ └── manifest.yml ├── posts ├── content-is-your-content.md ├── convenient-css-naming-conventions.md ├── font-everywhere.md ├── font-variation-misfortune.md ├── lets-talk-about-units.md ├── link-and-the-forgotten-accessibility.md ├── one-size-should-fit-all.md ├── overspecified-specificity.md ├── posts.json ├── prefix-mess.md ├── we-dont-float-down-here-anymore.md └── z-index-hell.md ├── rss └── feed.njk ├── sitemap.njk └── src ├── ads.txt ├── css ├── home.css ├── layout.css ├── main.css ├── normalize.css ├── post.css └── prism.css ├── images ├── csshell_logo.png ├── csshell_logo.svg ├── favicon-16x16.png ├── favicon-32x32.png ├── pentagram_icon.svg └── posts │ └── specificity.svg ├── js └── prism.js └── robots.txt /.eleventy.js: -------------------------------------------------------------------------------- 1 | const filters = require('./_11ty/filters.js'); 2 | const pluginRss = require("@11ty/eleventy-plugin-rss"); 3 | const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight"); 4 | 5 | module.exports = function (eleventyConfig) { 6 | eleventyConfig.addPassthroughCopy('src/css'); 7 | eleventyConfig.addPassthroughCopy('src/images'); 8 | eleventyConfig.addPassthroughCopy('src/js'); 9 | 10 | eleventyConfig.addPassthroughCopy({ 'src/ads.txt': '/ads.txt' }); 11 | eleventyConfig.addPassthroughCopy({ 'src/robots.txt': '/robots.txt' }); 12 | 13 | // Filters 14 | Object.keys(filters).forEach(filterName => { 15 | eleventyConfig.addFilter(filterName, filters[filterName]) 16 | }); 17 | 18 | // Plugins 19 | eleventyConfig.addPlugin(pluginRss); 20 | eleventyConfig.addPlugin(syntaxHighlight); 21 | 22 | return { 23 | passthroughFileCopy: true 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | ko_fi: cat_a_flame 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | _site/ 3 | dist/css/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Stefánia Péter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSS Hell - To Hell with bad CSS! 2 | 3 | Collection of common CSS mistakes, and how to fix them. 4 | 5 | https://csshell.dev 6 | 7 | ## What is this all about? 8 | 9 | Hi, I'm Stefánia, working with web since 2003. During my career I came across many lines of code, solutions, frameworks, mindsets. 10 | 11 | If you have been in this industry for some time, it should not be breaking news that CSS and HTML are those parts of an application 12 | people still underestimate. Because of that, some _interesting_ code pieces are born. I'd like to preserve these lines by showing you the bad 13 | example, explaining what's wrong with it and how to fix it. 14 | 15 | With this, I hope I can help you learn and improve. 16 | 17 | ## Why is it called CSS Hell? 18 | 19 | It's a ~~joke~~ idea I stole from [HTMLHell](https://www.htmhell.dev/). I hope adding some fun and sarcasm to learning might help raising awareness of 20 | how **!important** a good CSS code is. 21 | 22 | 23 | ## Got an issue, an idea? 24 | 25 | Please report it on [GitHub](https://github.com/cat-a-flame/CSSHell)! 26 | 27 | 28 | ## Would you like to support my work? 29 | 30 | CSS Hell is made with love and a lots of coffee. If you wish to buy me one, you can do it on [Ko-fi](https://ko-fi.com/cat_a_flame) ❤️ 31 | 32 | 33 | ## Credits 34 | 35 | The logo's font is [Chomsky](https://github.com/ctrlcctrlv/chomsky) by [Fredrick Brennan](https://github.com/ctrlcctrlv). 36 | 37 | The site is using [Eleventy](https://www.11ty.dev/). 38 | -------------------------------------------------------------------------------- /_11ty/filters.js: -------------------------------------------------------------------------------- 1 | const beautify_css = require('js-beautify').css; 2 | const beautify_html = require('js-beautify').html; 3 | const MarkdownIt = require('markdown-it'); 4 | 5 | module.exports = { 6 | prettyCSS: value => { 7 | return beautify_css(value, { 8 | "indent_size": 2 9 | }) 10 | }, 11 | pretty: value => { 12 | return beautify_html(value, { 13 | "indent_size": 2, 14 | "inline": "", 15 | "wrap_line_length": "70" 16 | }) 17 | }, 18 | md: value => { 19 | const md = new MarkdownIt(); 20 | return md.render(value); 21 | } 22 | } -------------------------------------------------------------------------------- /_data/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CSS Hell", 3 | "url": "https://csshell.dev" 4 | } -------------------------------------------------------------------------------- /_includes/layouts/base.liquid: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% if pageTitle %}{{pageTitle}} | {%endif%} CSS Hell 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 71 |
72 | {{ content }} 73 |
74 | 75 | 76 | 77 | 78 | 81 | 82 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /_includes/layouts/post.liquid: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/base.liquid 3 | --- 4 |
5 |

{{ pageTitle }}

6 |
7 | Posted on 8 | 9 | by 10 | {{ author }} 11 |
12 | 13 | {{ content }} 14 |
15 | 16 | -------------------------------------------------------------------------------- /about.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/base.liquid 3 | --- 4 | 5 | ## What is this all about? 6 | 7 | Hi, I'm Stefánia, working with web since 2003. During my career I came across many lines of code, solutions, frameworks, mindsets. 8 | 9 | If you have been in this industry for some time, it should not be breaking news that CSS and HTML are those parts of an application 10 | people still underestimate. Because of that, some _interesting_ code pieces are born. I'd like to preserve these lines by showing you the bad 11 | example, explaining what's wrong with it and how to fix it. 12 | 13 | With this, I hope I can help you learn and improve. 14 | 15 | 16 | ### Side note 17 | 18 | All of my examples are from real websites in production. Since I don't want to hurt anyone, I change the class names for harder identification. 19 | 20 | ## Why is it called CSS Hell? 21 | 22 | It's a ~~joke~~ idea I stole from [HTMHell](https://www.htmhell.dev/). I hope adding some fun and sarcasm to learning might help raising awareness of 23 | how **!important** a good CSS code is. 24 | 25 | 26 | ## Got an issue, an idea? 27 | 28 | Please report it on [GitHub](https://github.com/cat-a-flame/CSSHell)! 29 | 30 | 31 | ## Would you like to support my work? 32 | 33 | CSS Hell is made with love and a lots of coffee. If you wish to buy me one, you can do it on [Ko-fi](https://ko-fi.com/cat_a_flame) ❤️ -------------------------------------------------------------------------------- /contribute.md: -------------------------------------------------------------------------------- 1 | --- 2 | pageTitle: Contribute 3 | layout: layouts/base.liquid 4 | --- 5 | 6 |

{{ pageTitle }}

7 | 8 | Did you encounter a hellish CSS code that's worth preserving for the eternity? Go ahead and share it! 9 | 10 | ## Rules 11 | 12 | - All examples are must be copied from websites found in production. 13 | - Remove irrelevant parts of the code. 14 | - Modify the code (class names) for harder identification, we don't want to publicly shame anyone. 15 | - CSS code examples must be copied from new, modern websites, ones made years ago doesn't count. 16 | 17 | ## How to contribute 18 | 19 | 1. [Fork the CSSHell repository](https://github.com/cat-a-flame/CSSHell) and install the dependencies. 20 | 21 | ```html 22 | npm install 23 | ``` 24 | 25 | 2. Run the project: 26 | 27 | ```html 28 | eleventy --serve 29 | ``` 30 | 31 | 32 | 3. Add a submission in ./posts folder by copying any other markdown file. The file name must match with the title of the post! 33 | 34 | - Show the bad example 35 | - Explain how to fix it 36 | - Show the good example 37 | - Add resources for further reading 38 | 39 | 4. Push and create a pull request to CSSHell's `main` branch. 40 | 41 | If you got any questions, or not sure if your example worth sharing, feel free to DM me on [Twitter](https://twitter.com/cat_a_flame), or post at [GitHub Discussions](https://github.com/cat-a-flame/CSSHell/discussions). 42 | 43 | 44 | ## !important 45 | 46 | At the moment, the author link points to Twitter. I'm planning to change this and add GitHub and LinkedIn as an option. -------------------------------------------------------------------------------- /index.njk: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/base.liquid 3 | pageTitle: To Hell with bad CSS! 4 | pagination: 5 | data: collections.posts 6 | size: 5 7 | alias: entries 8 | reverse: true 9 | --- 10 | 11 |
    12 | {% for post in entries %} 13 |
  1. 14 |

    {{ post.data.pageTitle }}

    15 | 16 | {% if post.data.lead %} 17 |

    {{ post.data.lead | md | safe }}

    18 | {% endif %} 19 | 20 | {% highlight "css" %} 21 | {{ post.data.badcode | prettyCSS | safe }} 22 | {% endhighlight %} 23 | 24 |
    25 | Check out what is going on here 26 |
    27 |
  2. 28 | {% endfor %} 29 |
30 | 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CSSHell", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "eleventy", 8 | "serve": "eleventy --serve", 9 | "start": "netlify dev" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/cat-a-flame/CSSHell.git" 14 | }, 15 | "keywords": [], 16 | "author": "", 17 | "license": "ISC", 18 | "bugs": { 19 | "url": "https://github.com/cat-a-flame/CSSHell/issues" 20 | }, 21 | "homepage": "https://github.com/cat-a-flame/CSSHell#readme", 22 | "devDependencies": { 23 | "@11ty/eleventy": "^0.12.1", 24 | "@11ty/eleventy-plugin-rss": "^1.1.1", 25 | "@11ty/eleventy-plugin-syntaxhighlight": "^3.1.0", 26 | "js-beautify": "^1.14.7" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /plugins/sass/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | onPreBuild: async ({ utils: { run } }) => { 3 | await run.command( 4 | "node-sass src/sass/main.scss dist/css/main.css" 5 | ); 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /plugins/sass/manifest.yml: -------------------------------------------------------------------------------- 1 | name: sass -------------------------------------------------------------------------------- /posts/content-is-your-content.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/post.liquid 3 | author: cat_a_flame 4 | date: 2023-03-11T14:15:00 5 | pageTitle: content is your Content? 6 | lead: "I saw a developer using the `content` property for adding extra text to a label, because why not, he said. Sadly, this raises several issues." 7 | badcode: '.label::after { content: "My label"; }' 8 | goodcode: '@media print { 9 | a[href]::after { 10 | content: " (" attr(href) ")"; 11 | } 12 | }' 13 | --- 14 | 15 |
16 | 17 | {{ lead }} 18 | 19 | 20 | ## Bad example 21 | 22 | ```css 23 | {{ badcode | prettyCSS | safe }} 24 | ``` 25 | 26 |
27 |
28 | 29 | ## What is the problem and how to fix it 30 | 31 | - Accessibility: CSS content is not accessible to screen readers, which makes it difficult for users with visual impairments to access the content. Also, you can not select it because it doesn't behave as a text. 32 | - SEO: Search engines may not be able to read CSS content, which means that the content will not be indexed or displayed in search results. 33 | - Maintenance: If you need to update or change the content, you will have to go through the CSS file instead of the HTML file, which can be time-consuming and error-prone. 34 | - Structure: CSS content does not follow the semantic structure of HTML, which makes it difficult to maintain a consistent document structure and can lead to accessibility issues. 35 | - Styling: CSS content is limited in terms of styling options compared to HTML text. This can limit the design options for the webpage. If the user disables the stylesheet, the text won't be visible. 36 | - Separation of concerns: CSS content blurs the separation of concerns between HTML and CSS, which can make it more difficult to maintain and update the code. 37 | 38 | If you need to display any kind of text, always do it in the HTML code. `::before` and `::after` pseudo-elements are best used for decorative purposes. However, in print view, it is a good idea for using it to display URLs. If you happen to print an article or documentation, it can come in handy to make the link visible behind the keyword. Go on, check out the print preview of this post! 39 |
40 | 41 |
42 | 43 | ## Good example 44 | 45 | ```css 46 | {{ goodcode | prettyCSS | safe }} 47 | ``` 48 | 49 |
50 | 51 |
52 | 53 | ## Resources 54 | - [MDN CSS content](https://developer.mozilla.org/en-US/docs/Web/CSS/content) 55 | - [Accessibility support for CSS generated content](https://tink.uk/accessibility-support-for-css-generated-content/) 56 | - [How is CSS pseudo content treated by screen readers?](https://accessibleweb.com/question-answer/how-is-css-pseudo-content-treated-by-screen-readers/) 57 |
58 | -------------------------------------------------------------------------------- /posts/convenient-css-naming-conventions.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/post.liquid 3 | author: cat_a_flame 4 | date: 2021-06-05T14:45:00 5 | pageTitle: Convenient CSS naming conventions 6 | lead: "I often run into the problem where I see the same class name being reused on different parts and context of the website, but when 1 out of the 3 properties don't match with the design, developers just use inline styling to override the desired rule." 7 | badcode: '.primary-text { color: #000; font-family: "Open Sans"; line-height: 1.2; }' 8 | badcode2: ' 9 |

Primary title

10 |

Subtitle

11 | ' 12 | goodcode: ' 13 | .heading-main { color: #000; font-family: "Open Sans"; line-height: 1.2; } 14 | .heading-subtitle { color: #333; font-family: "Open Sans"; line-height: 1.2; }' 15 | advancedExample: ' 16 | :root { 17 | --heading-font-family: "Open Sans"; 18 | --heading-line-height: 1.2; 19 | } 20 | 21 | .heading-main { color: #000; font-family: var(--heading-font-family); line-height: var(--heading-line-height); } 22 | .heading-subtitle { color: #333; font-family: var(--heading-font-family); line-height: var(--heading-line-height); }' 23 | --- 24 | 25 |
26 | 27 | {{ lead }} 28 | 29 | ## Bad example 30 | 31 | ```css 32 | {{ badcode | prettyCSS | safe }} 33 | ``` 34 | 35 | ```html 36 | {{ badcode2 | pretty | safe }} 37 | ``` 38 |
39 |
40 | 41 | ## What is the problem and how to fix it 42 | 43 | - Using inline styling leads to hard maintenance and code readability. The best way is to separate the view, styling and JavaScript from each other. 44 | - Class names should reflect what are they styling, like, in my example, you can tell from the CSS that the `.heading-main` is styling the main heading. 45 | - If you work on a website with more people and don't have a naming convention, it has a risk of creating a class with the same name, and that can cause conflicts on the design, most likely if you are working with reuseable components (the most common class name I often see is `.title`). 46 | - There are several methodologies for naming. The most popular one is [BEM](http://getbem.com/), but you can choose by your liking or just come up with a new one which suits the project. The most important is to follow the naming convention all the time. 47 | 48 |
49 | 50 |
51 | 52 | ## Good example 53 | 54 | ```css 55 | {{ goodcode | prettyCSS | safe }} 56 | ``` 57 | 58 | ## More advanced good example 59 | 60 | ```css 61 | {{ advancedExample | prettyCSS | safe }} 62 | ``` 63 |
64 | 65 |
66 | 67 | ## Resources 68 | - [CSS Naming Conventions that Will Save You Hours of Debugging](https://www.freecodecamp.org/news/css-naming-conventions-that-will-save-you-hours-of-debugging-35cea737d849/) 69 | - [Naming Things in CSS](https://elad.medium.com/naming-things-in-css-a7de9ad31cd9) 70 | 71 |
-------------------------------------------------------------------------------- /posts/font-everywhere.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/post.liquid 3 | author: cat_a_flame 4 | date: 2021-04-18T18:44:00 5 | pageTitle: 'font-family everywhere!' 6 | lead: "Specifying the primary font for almost every selector is not a good approach, yet I often run into this issue." 7 | badcode: '.my-class-1 {font-family: Roboto;} .my-class-2 {font-family: Roboto;} p {font-family: Roboto;} .my-class-3 {font-family: Roboto;} footer {font-family: Roboto;}' 8 | goodcode: 'body {font-family: "Roboto", sans-serif;}' 9 | goodcode2: ':root {--heading-font-family: "Georgia", "Times New Roman", "Times", serif;} .title {font-family: var(--heading-font-family);}' 10 | --- 11 | 12 |
13 | 14 | {{ lead }} 15 | 16 | 17 | ## Bad example 18 | 19 | ```css 20 | {{ badcode | prettyCSS | safe }} 21 | ``` 22 |
23 |
24 | 25 | ## What is the problem and how to fix it 26 | 27 | - Duplicating the `font-family` import only leads to hard maintainability. If, for some reason you want to change your website's font, you have to do it in every line, or, in all files. 28 | - If you add the font name by hand, there is a high chance you mistype it once and the browser will load a totally different font (once I saw Ariel instead of Arial...). 29 | - Quotation is not necessary, but it's a good approach to use it, mostly when the font name contains whitespaces. 30 | - Always add a fallback option. If `Roboto` isn't available, then the user-agent-defined sans serif font will be used. Note, these are not font names, so don't use quotation marks! 31 | - If you want to use a different kind of font for your headings, links, whatever, the best approach it to store the name as a CSS variable. 32 |
33 | 34 |
35 | 36 | ## Good example 37 | 38 | ```css 39 | {{ goodcode | prettyCSS | safe }} 40 | ``` 41 | 42 | ## Another good example 43 | 44 | ```css 45 | {{ goodcode2 | prettyCSS | safe }} 46 | ``` 47 | 48 |
49 | 50 |
51 | 52 | ## Resources 53 | - [CSS Font Module Level 3](https://www.w3.org/TR/2018/REC-css-fonts-3-20180920/#propdef-font-family) 54 | - [font-family on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family) 55 |
56 | -------------------------------------------------------------------------------- /posts/font-variation-misfortune.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/post.liquid 3 | author: vanilla_ixth 4 | date: 2021-05-03T20:44:00 5 | pageTitle: font-variation-misfortune 6 | lead: Variable fonts are awesome, but unnecessary usage of `font-variation-settings` will eventually break your styles. 7 | htmlcode: italic bold? 8 | badcode: >- 9 | .bold { font-variation-settings: 'wght' 700; } 10 | .italic { font-variation-settings: 'ital' 1; } 11 | goodcode: >- 12 | .bold { font-weight: bold; } 13 | .italic { font-style: italic; } 14 | --- 15 | 16 |
17 | 18 | {{ lead }} 19 | 20 | ## Bad example 21 | 22 | ```css 23 | {{ badcode | prettyCSS | safe }} 24 | ``` 25 | 26 | ```html 27 | {{ htmlcode | pretty | safe }} 28 | ``` 29 | 30 | What do you think, will it be both _italic_ and __bold__? Hint: it won't. 31 | 32 |
33 | 34 |
35 | 36 | ## What is the problem and how to fix it 37 | 38 | - `font-variation-settings` do not add up, so, when several rules overlap, they override one another. 39 | - Common workaround for that is [using CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide#notes), but you really don't want to get in that mess just to define font-weight in a fancy way, don't you? 40 | - Redefining `font-weight`, `font-stretch` or `font-style` in this manner does nothing at all, variable fonts can handle these properties without axes modifications. 41 | 42 | Latter is even [mentioned in spec](https://www.w3.org/TR/css-fonts-4/#font-variation-settings-def): 43 | > When possible, authors should generally use […] this property for special cases where its use is the only way of accessing a particular infrequently used font variation. For example, it is preferable to use `font-weight: 700` rather than `font-variation-settings: 'wght' 700`. 44 |
45 | 46 |
47 | 48 | ## Good example 49 | 50 | Just use font properties: 51 | 52 | ```css 53 | {{ goodcode | prettyCSS | safe }} 54 | ``` 55 |
56 | 57 |
58 | 59 | ## Resources 60 | - [CSS Fonts Module Level 4](https://www.w3.org/TR/css-fonts-4/#font-variation-settings-def) 61 | - [Variable fonts guide](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide) 62 |
63 | -------------------------------------------------------------------------------- /posts/lets-talk-about-units.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/post.liquid 3 | author: cat_a_flame 4 | date: 2021-05-08T16:00:00 5 | pageTitle: Let's talk about units 6 | lead: "There is a life beyond pixels and percentages. Using `px` units is fine in certain cases, the real mistake is using absolute instead of relative units." 7 | badcode: "p { font-size: 16px; line-height: 20px; margin-bottom: 8px; }" 8 | goodcode: "p { font-size: 1rem; line-height: 1.25; margin-bottom: 0.5rem; }" 9 | --- 10 | 11 |
12 | 13 | {{ lead }} 14 | 15 | ## Bad example 16 | 17 | ```css 18 | {{ badcode | prettyCSS | safe }} 19 | ``` 20 |
21 |
22 | 23 | ## What is the problem and how to fix it 24 | 25 | - Using relative units ensures that the website scales proportionally according to your choice of font, and according to the users' choice of screen size and zoom level. 26 | - The formula to calculate the rem value is `desired-size / root-font-size`, in short `8 / 16 = 0.5`, this means that `1rem` equals the font size of the `html` element (which for most browsers has a default value of 16px). 27 | - If you don't want to grab a calculator every time you need a new unit, use Sass and create mixin. CSS Tricks has a [pretty good article](https://css-tricks.com/snippets/css/less-mixin-for-rem-font-sizing/) about how you can achive this. 28 | 29 |
30 | 31 |
32 | 33 | ## Good example 34 | 35 | ```css 36 | {{ goodcode | prettyCSS | safe }} 37 | ``` 38 |
39 | 40 |
41 | 42 | ## Resources 43 | - [CSS Units: Which Ones To Use And Avoid](https://medium.com/swlh/css-units-which-ones-to-use-and-avoid-31e4ed461f9) 44 | - [CSS values and units](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units) 45 | - [Building Resizeable Components with Relative CSS Units ](https://css-tricks.com/building-resizeable-components-relative-css-units/) 46 |
-------------------------------------------------------------------------------- /posts/link-and-the-forgotten-accessibility.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/post.liquid 3 | author: cat_a_flame 4 | date: 2021-04-11T20:10:00 5 | pageTitle: 'Link & the forgotten accessibility' 6 | lead: "One of the most common mistakes: setting a color for a link, but not adding `:hover`, `:focus` and `:active` states." 7 | badcode: 'a {color: #ca0000; text-decoration: none;} /* And that is the end of link styling */' 8 | goodcode: 'a { color: #ff0000; } a:hover, a:visited, a:focus { color: #a60000; text-decoration: none; } a:active { color: #000000; background-color: #a60000; }' 9 | --- 10 | 11 |
12 | 13 | {{ lead }} 14 | 15 | 16 | ## Bad example 17 | 18 | ```css 19 | {{ badcode | prettyCSS | safe }} 20 | ``` 21 |
22 |
23 | 24 | ## What is the problem and how to fix it 25 | 26 | - Without the missing states, our link won't be accessible, users might get confused while navigating through our website with a mouse or a keyboard, 27 | because they won't be able to identify what is clickable and what is not 28 | - By default, browsers set `text-decoration: underline;` to links, but removing this property can also lead to confusion 29 | - Try using a color which fits with your design but still makes it obvious if a text can be clicked. In this blog, the red color is consistent for clickable items 30 | 31 |
32 | 33 |
34 | Try navigating on this page by pressing the Tab key and see what happens! 35 |
36 | 37 |
38 | 39 | ## Good example 40 | 41 | ```css 42 | {{ goodcode | prettyCSS | safe }} 43 | ``` 44 |
45 | 46 |
47 | 48 | ## Resources 49 | - [Styling links](https://developer.mozilla.org/en-US/docs/Learn/CSS/Styling_text/Styling_links) 50 | - [CSS and JavaScript accessibility best practices](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/CSS_and_JavaScript) 51 |
52 | -------------------------------------------------------------------------------- /posts/one-size-should-fit-all.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/post.liquid 3 | author: cat_a_flame 4 | date: 2022-06-18T15:15:00 5 | pageTitle: One size should fit all? 6 | lead: "In modern web development, there is less and less reason to use fix sizing for an element, especially when it's a content wrapper." 7 | badcode: ".wrapper { height: 800px; width: 1024px; }" 8 | goodcode: ".wrapper { max-width: 1024px; }" 9 | --- 10 | 11 |
12 | 13 | {{ lead }} 14 | 15 | ## Bad example 16 | 17 | ```css 18 | {{ badcode | prettyCSS | safe }} 19 | ``` 20 |
21 |
22 | 23 | ## What is the problem and how to fix it 24 | 25 | - There are cases when you need to set the size of an element, but even if you want an image to be 600px wide, that will overflow from the content on mobile. 26 | - Specifying fixed sizes to elements can break the responsiveness. You shouldn't set a size for a `div` unless it's necessary, because you can't cover every possible screen size in your media queries. For example, if the `.wrapper` has a longer content than 800px, everything will overflow. 27 | - Try using `max-width`. That way, you can ensure that your element won't take up the whole area, or sticking out on smaller screens (`max-width` better used on block elements). 28 | - `height` is rarely needed in this case. Let the size of the content decide the height, don't force it! 29 |
30 | 31 |
32 | 33 | ## Good example 34 | 35 | ```css 36 | {{ goodcode | prettyCSS | safe }} 37 | ``` 38 |
39 | -------------------------------------------------------------------------------- /posts/overspecified-specificity.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/post.liquid 3 | author: cat_a_flame 4 | date: 2021-04-25T11:59:00 5 | pageTitle: 'Overspecified specificity' 6 | lead: "Specificity determines, which CSS rule is applied by the browsers. Developers often write overly specific selectors just to be 10000% sure their rules will _rule_." 7 | badcode: 'div#my-popup div span.my-radiocheckbox-label-text {color: #666;} #some-id .label {color: #111 !important;}' 8 | goodcode: '.my-class-checkbox-label {color: #666;}' 9 | example: '.label-color {color: red;} .label-color {color: black;}' 10 | --- 11 | 12 |
13 | 14 | {{ lead }} 15 | 16 | 17 | ## Bad example 18 | 19 | ```css 20 | {{ badcode | prettyCSS | safe }} 21 | ``` 22 |
23 |
24 | 25 | ## What is the problem and how to fix it 26 | 27 | - Overspecifing rules will lead to hard maintainability and code readability, while there is no real benefit. 28 | - If we want to reuse our code, avoid using IDs for styling: as the name indicates, these are unique identifiers, they cannot be repeated within a page. If you need help with naming selectors and avoid styling conflicts, try using [BEM](http://getbem.com/) or other similar naming methodologies. 29 | 30 | CSS stands for _Cascading Style Sheets_, which means, if you apply different color for a text several times in your CSS with the same specificity, the selector which is further down in the source will apply. For example, in the code below, the font color is going to be black: 31 | 32 | ```css 33 | {{ example | prettyCSS | safe }} 34 | ``` 35 | 36 | ### How to calculate specificity 37 | 38 | ![Visual representation of selector specificity](/src/images/posts/specificity.svg) 39 | 40 | - If the element has inline styling, that automatically wins (1,0,0,0 points) 41 | - For each ID value, apply 0,1,0,0 points 42 | - For each class value, pseudo-class or attribute selector, apply 0,0,1,0 points 43 | - For each element reference, apply 0,0,0,1 point 44 | 45 | You can generally read the values as if they were just a number like 1,0,0,0 is "1000", and so clearly wins over a specificity of 0,1,0,0 or "100". The commas are there to remind us that this isn't really a "base 10" system, in that you could technically have a specificity value of like 0,1,13,4 – and that "13" doesn't spill over as a base 10 system would. 46 | 47 | The `!important` value appended to a CSS property value is an automatic win, it overrides even inline styles from the markup. The only way an `!important` value can be overridden is with another `!important` rule declared later in the CSS and with equal or great specificity value otherwise. You could think of it as adding 1,0,0,0,0 to the specificity value. 48 | 49 | CSS Specificity is one of the most difficult concepts to grasp in Cascading Style Sheets. I strongly recommend reading all the resources I mention above because once you master this knowledge, it's going to be easy to apply it like setting `!important` to every line 😉 50 |
51 | 52 |
53 | 54 | ## Good example 55 | 56 | ```css 57 | {{ goodcode | prettyCSS | safe }} 58 | ``` 59 | 60 |
61 | 62 |
63 | 64 | ## Resources 65 | - [Specificity on w3.org](https://www.w3.org/TR/selectors-3/#specificity) 66 | - [Specificity on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) 67 | - [Specifics on CSS Specificity](https://css-tricks.com/specifics-on-css-specificity/) 68 | - [CSS Specificity: Things You Should Know](https://www.smashingmagazine.com/2007/07/css-specificity-things-you-should-know/) 69 | - [Specificity Calculator](https://specificity.keegan.st/) 70 |
71 | -------------------------------------------------------------------------------- /posts/posts.json: -------------------------------------------------------------------------------- 1 | { 2 | "layout": "base.liquid", 3 | "tags": ["posts"] 4 | } -------------------------------------------------------------------------------- /posts/prefix-mess.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/post.liquid 3 | author: cat_a_flame 4 | date: 2021-04-15T14:50:00 5 | pageTitle: 'Prefix mess' 6 | lead: "Browser vendors sometimes add prefixes to experimental or nonstandard CSS properties and JavaScript APIs, so developers can experiment with new ideas while — in theory — preventing their experiments from being relied upon and then breaking web developers' code during the standardization process." 7 | badcode: '.my-class {-webkit-transition: left 400ms ease-out; /* older webkit */ -webkit-transition: left 400ms ease-out; -moz-transition: left 400ms ease-out; -ms-transition: left 400ms ease-out; -o-transition: left 400ms ease-out; transition: left 400ms ease-out;}' 8 | goodcode: '.my-class {transition: left 400ms ease-out;}' 9 | --- 10 | 11 |
12 | 13 | {{ lead }} 14 | 15 | 16 | ## Bad example 17 | 18 | ```css 19 | {{ badcode | prettyCSS | safe }} 20 | ``` 21 |
22 |
23 | 24 | ## What is the problem and how to fix it 25 | 26 | - Adding unnecessary prefixes makes your code harder to read and maintain. The file size can also increase for no reason. 27 | - If not sure which property requires a prefix, and which one not, use [caniuse.com](https://caniuse.com). With this tool you can check the overall support for every property, when they plan to leave the prefix (if it has any), and so on. 28 | - If you don't want to mess with prefixes (understandable), you can use [Autoprefixer](https://www.npmjs.com/package/autoprefixer) in your build process, and this part can be covered automatically. 29 | - Browser vendors are working to stop using vendor prefixes for experimental features. Web developers have been using them on production Web sites, despite their experimental nature. This has made it more difficult for browser vendors to ensure compatibility and to work on new features; it's also been harmful to smaller browsers who wind up forced to add other browsers' prefixes in order to load popular web sites (Source: MDN). 30 |
31 | 32 | 33 | 34 | 35 |
36 | 37 | ## Good example 38 | 39 | ```css 40 | {{ goodcode | prettyCSS | safe }} 41 | ``` 42 |
43 | 44 |
45 | 46 | ## Resources 47 | - [Vendor prefix](https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix) 48 |
49 | -------------------------------------------------------------------------------- /posts/we-dont-float-down-here-anymore.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/post.liquid 3 | author: cat_a_flame 4 | date: 2022-02-07T14:50:00 5 | pageTitle: "We don't float down here anymore" 6 | lead: "I just realised I can't tell when was the last time I used the float property. There are so many other ways to align items without any fuss!" 7 | badcode: '.sidebar { float: right; }' 8 | goodcode: '.my-class {transition: left 400ms ease-out;}' 9 | --- 10 | 11 |
12 | 13 | {{ lead }} 14 | 15 | ## Not that bad example 16 | 17 | ```css 18 | {{ badcode | prettyCSS | safe }} 19 | ``` 20 |
21 |
22 | 23 | First of all, `float` is not deprecated. Float was misused. Its original purpose was to align images with texts, nothing more. Then, as layouts and designs started to evolve, we used to align site parts as well, but it was always a pain because elements with the float property were actually floating above our content, so we had to clear them, but `clearfix` was actually a hack, and hard to apply. 24 | 25 | Now in 2022, there are several ways to align elements on our webpage and apps. Let's check out what are those: 26 | 27 | ### Margin 28 | I'm pretty certain that you used `margin: 0 auto;` before to center block elements horizontally. This works with `margin-left: auto;` and `margin-right: auto;` too! The downside is that your element needs to have a fixed size, which is less than 100%. Using fixed sizes is not a good practice, I will explain this in another article later! 29 | 30 | ### Flexbox 31 | Aligning elements with [Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) is really _flexible_. You can not only align them horizontally but vertically too! You can play with the direction, rearrange the item order, etc. Of course, this requires wrapping your desired items into an element with `display: flex;` which can cause a bit long HTML code, but it is worth it. 32 | 33 | ### Grid 34 | [CSS grid](https://css-tricks.com/snippets/css/complete-guide-grid/) is more complex than Flexbox, and it's used on bigger parts of your website such as the main layout. 35 | 36 | ### Conclusion 37 | Using `float` nowadays is a bit obsolete. I don't say stop using it, but the above-mentioned methods are much easier to use, and a lot more modern. As I said in the beginning, `float` was made to align images, so keep that in mind when you want to align your sidebar to the right! 38 | 39 |
40 | 41 |
42 | 43 | ## Resources 44 | - [Is CSS float deprecated?](https://css-tricks.com/is-css-float-deprecated/) 45 | - [Stop Using Float in CSS - Here Are Your Alternatives](https://blog.shahednasser.com/stop-using-float-in-css-here-are-your-alternatives/) 46 | - [Clearfix: A Lesson in Web Development Evolution](https://css-tricks.com/clearfix-a-lesson-in-web-development-evolution/) 47 | 48 |
-------------------------------------------------------------------------------- /posts/z-index-hell.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: layouts/post.liquid 3 | author: cat_a_flame 4 | date: 2021-04-11T20:00:00 5 | pageTitle: z-index hell 6 | lead: "`z-index` is something that can measure one's frustration. The amount of digits represent the fact that the developer tried to position the `div` above the content, but failed miserably." 7 | badcode: '.my-class {z-index: 122828282882;}' 8 | goodcode: '.my-class {position: absolute; z-index: 2;}' 9 | --- 10 | 11 |
12 | 13 | {{ lead }} 14 | 15 | ## Bad example 16 | 17 | ```css 18 | {{ badcode | prettyCSS | safe }} 19 | ``` 20 |
21 |
22 | 23 | ## What is the problem and how to fix it 24 | 25 | - `z-index` can only be used with `absolute`, `fixed`, `relative` or `sticky` `positions`. In my example, this line is missing. 26 | - `z-index` has a maximum value which is **2147483648**, the maximum positive value for a 32-bit signed binary integer in computing (the example has +2 digits). 27 | - If you don't change anything on your content's z-axis value, adding 2 or 3 has the same effect as 100 or 10000. Adding huge numbers can lead to hard maintainability. 28 | - You might not even need `z-index` at all, just push your DOM element a bit further towards your `` tag, it will be rendered later than the elements in the same layer preceding it, so it can cover them. 29 |
30 | 31 |
32 | 33 | ## Good example 34 | 35 | ```css 36 | {{ goodcode | prettyCSS | safe }} 37 | ``` 38 |
39 | 40 |
41 | 42 | ## Resources 43 | - [z-index property on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/z-index) 44 | - [Understanding CSS z-index](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index) 45 | - [2147483648 on Wikipedia](https://en.wikipedia.org/wiki/2,147,483,647#In_computing) 46 |
47 | -------------------------------------------------------------------------------- /rss/feed.njk: -------------------------------------------------------------------------------- 1 | ---json 2 | { 3 | "permalink": "feed.xml", 4 | "eleventyExcludeFromCollections": true, 5 | "metadata": { 6 | "title": "CSSHell", 7 | "subtitle": "", 8 | "url": "https://csshell.dev/", 9 | "feedUrl": "https://csshell.dev/feed.xml", 10 | "author": { 11 | "name": "@cat_a_flame", 12 | "email": "" 13 | } 14 | } 15 | } 16 | --- 17 | 18 | 19 | {{ metadata.title }} 20 | {{ metadata.subtitle }} 21 | 22 | 23 | {{ collections.posts | getNewestCollectionItemDate | dateToRfc3339 }} 24 | {{ metadata.url }} 25 | 26 | {{ metadata.author.name }} 27 | {{ metadata.author.email }} 28 | 29 | {%- for post in collections.posts | reverse %} 30 | {% set absolutePostUrl %}{{ post.url | url | absoluteUrl(metadata.url) }}{% endset %} 31 | 32 | {{ post.data.pageTitle }} 33 | 34 | {{ post.date | dateToRfc3339 }} 35 | {{ absolutePostUrl }} 36 | {{ post.templateContent | htmlToAbsoluteUrls(absolutePostUrl) }} 37 | 38 | {%- endfor %} 39 | -------------------------------------------------------------------------------- /sitemap.njk: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /sitemap.xml 3 | eleventyExcludeFromCollections: true 4 | --- 5 | 6 | 7 | {% for page in collections.all %} 8 | 9 | {{ site.url }}{{ page.url | url }} 10 | {{ page.date.toISOString() }} 11 | 12 | {% endfor %} 13 | -------------------------------------------------------------------------------- /src/ads.txt: -------------------------------------------------------------------------------- 1 | google.com, pub-5519548085198887, DIRECT, f08c47fec0942fa0 2 | -------------------------------------------------------------------------------- /src/css/home.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --read-more-link-background: var(--brand-color); 3 | --read-more-link-background-hover: var(--link-hover-color); 4 | --read-more-link-background-focus: var(--link-focus-color); 5 | } 6 | @media (prefers-color-scheme: dark) { 7 | :root { 8 | --read-more-link-background: #ac1a3c; 9 | --read-more-link-background-hover: #990e2e; 10 | --read-more-link-background-focus: #920a2a; 11 | } 12 | } 13 | 14 | .post-list { 15 | list-style: none; 16 | margin: 0; 17 | padding: 0; 18 | } 19 | .post-list--entry { 20 | margin-bottom: 2rem; 21 | padding-bottom: 1rem; 22 | position: relative; 23 | } 24 | .post-list--entry::after { 25 | background-color: #999; 26 | bottom: 0; 27 | content: ""; 28 | left: 0; 29 | height: .0625rem; 30 | margin-right: auto; 31 | margin-left: auto; 32 | position: absolute; 33 | right: 0; 34 | width: 6.25rem; 35 | } 36 | 37 | .post-title { 38 | font-family: var(--heading-font-family); 39 | font-size: 1.8rem; 40 | font-weight: 400; 41 | margin-top: 0; 42 | margin-bottom: 0; 43 | } 44 | .post-title a { 45 | color: var(--brand-color); 46 | text-decoration: none; 47 | } 48 | 49 | .post-bottom-navigation { 50 | padding-top: 1rem; 51 | text-align: center; 52 | } 53 | 54 | .read-more { 55 | align-items: center; 56 | background: var(--read-more-link-background); 57 | color: #fff; 58 | display: inline-flex; 59 | font-weight: 500; 60 | padding-top: .8rem; 61 | padding-right: 1.2rem; 62 | padding-bottom: .8rem; 63 | padding-left: 1.2rem; 64 | text-decoration: none; 65 | margin: 0 auto; 66 | } 67 | .read-more span { 68 | font-size: 1.5rem; 69 | line-height: 1; 70 | margin-left: 1ch; 71 | } 72 | .read-more:hover { 73 | background-color: var(--read-more-link-background-hover); 74 | color: #fff; 75 | text-decoration: none; 76 | } 77 | .read-more:active { 78 | background-color: var(--read-more-link-background-focus); 79 | color: #fff; 80 | outline: 0 none; 81 | text-decoration: none; 82 | } 83 | .read-more:focus { 84 | background-color: var(--read-more-link-background-focus); 85 | color: #fff; 86 | outline: 0 none; 87 | text-decoration: none; 88 | } 89 | .read-more:focus-visible { 90 | color: #fff; 91 | outline: 2px solid var(--read-more-link-background-focus); 92 | text-decoration: none; 93 | } 94 | 95 | /* Site pagination*/ 96 | .site-bottom-navigation { 97 | margin-top: 4rem; 98 | margin-bottom: 3rem; 99 | } 100 | 101 | .site-pagination { 102 | display: flex; 103 | justify-content: center; 104 | list-style: none; 105 | margin: 0; 106 | padding: 0; 107 | } 108 | .site-pagination--item { 109 | margin-right: .2rem; 110 | margin-left: .2rem; 111 | } 112 | .site-pagination--link { 113 | color: var(--brand-color); 114 | display: block; 115 | font-weight: 600; 116 | padding-top: .5rem; 117 | padding-right: 1rem; 118 | padding-bottom: .5rem; 119 | padding-left: 1rem; 120 | text-decoration: none; 121 | } 122 | .site-pagination--link:hover:not([aria-current="true"]) { 123 | background-color: var(--link-hover-color); 124 | color: #fff; 125 | } 126 | .site-pagination--link:active:not([aria-current="true"]) { 127 | background-color: var(--link-focus-color); 128 | color: #fff; 129 | outline: none; 130 | } 131 | .site-pagination--link:focus:not([aria-current="true"]) { 132 | background-color: var(--link-focus-color); 133 | color: #fff; 134 | outline: 0 none; 135 | } 136 | .site-pagination--link:focus-visible:not([aria-current="true"]) { 137 | outline: 2px solid var(--link-focus-color); 138 | } 139 | .site-pagination--link[aria-current="true"] { 140 | background-color: var(--brand-color); 141 | color: #fff; 142 | pointer-events: none; 143 | } -------------------------------------------------------------------------------- /src/css/layout.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --site-subtitle-font-color: #444; 3 | } 4 | @media (prefers-color-scheme: dark) { 5 | :root { 6 | --site-subtitle-font-color: #c5c5c5; 7 | } 8 | } 9 | 10 | .site-header { 11 | max-width: var(--layout-max-width); 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | .site-header nav { 16 | padding-top: 1rem; 17 | padding-bottom: 1rem; 18 | } 19 | .site-header nav a { 20 | font-weight: 700; 21 | text-decoration: none; 22 | } 23 | 24 | @media print { 25 | .site-top-navigation { 26 | display: none; 27 | } 28 | } 29 | 30 | .site-main-menu { 31 | display: flex; 32 | justify-content: flex-end; 33 | list-style-type: none; 34 | margin: 0; 35 | padding: 0; 36 | } 37 | .site-main-menu li:not(:last-child) { 38 | margin-right: 1.5rem; 39 | } 40 | 41 | main { 42 | border-top: .0625rem solid #999; 43 | margin-top: .4rem; 44 | margin-right: auto; 45 | margin-left: auto; 46 | padding-top: 3rem; 47 | max-width: var(--layout-max-width); 48 | } 49 | @media print { 50 | main { 51 | border-top: 0 none; 52 | padding-top: 0; 53 | } 54 | } 55 | 56 | footer { 57 | font-size: .8rem; 58 | margin-top: 4rem; 59 | margin-right: auto; 60 | margin-bottom: 1rem; 61 | margin-left: auto; 62 | max-width: var(--layout-max-width); 63 | } 64 | @media print { 65 | footer { 66 | display: none; 67 | } 68 | } 69 | 70 | /* Logo & subtitle */ 71 | .site-header--heading { 72 | border-bottom: .0625rem solid #999; 73 | padding-top: 2rem; 74 | padding-bottom: 2rem; 75 | } 76 | @media print { 77 | .site-header--heading { 78 | border-bottom: 0 none; 79 | padding-bottom: 1rem; 80 | } 81 | } 82 | 83 | .site-header--home-link { 84 | display: inline-block; 85 | } 86 | .site-header--logo { 87 | width: 21.875rem; 88 | } 89 | @media print { 90 | .site-header--logo { 91 | width: 7.5rem; 92 | } 93 | } 94 | @media screen and (max-width: 800px) { 95 | .site-header--logo { 96 | width: 15.625rem; 97 | } 98 | } 99 | .site-header--logo-path { 100 | fill: url('#site-header--logo-gradient'); 101 | } 102 | .site-header--logo stop { 103 | transition: .2s; 104 | } 105 | .site-header--home-link:hover .site-header--logo stop:first-child, 106 | .site-header--home-link:focus .site-header--logo stop:first-child { 107 | stop-color: #da1f05; 108 | } 109 | .site-header--home-link:hover .site-header--logo stop:last-child, 110 | .site-header--home-link:focus .site-header--logo stop:last-child { 111 | stop-color: #fe650d; 112 | } 113 | 114 | .site-header--details { 115 | color: var(--site-subtitle-font-color); 116 | font-family: var(--heading-font-family); 117 | font-size: 1.4rem; 118 | margin-top: 0; 119 | margin-bottom: 0; 120 | margin-left: 12rem; 121 | } 122 | @media screen and (max-width: 800px) { 123 | .site-header--details { 124 | font-size: 1.2rem; 125 | margin-top: .5rem; 126 | margin-left: 4rem; 127 | } 128 | } 129 | @media print { 130 | .site-header--details { 131 | display: none; 132 | } 133 | } 134 | 135 | 136 | -------------------------------------------------------------------------------- /src/css/main.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); 2 | @import "normalize.css"; 3 | @import "home.css"; 4 | @import "layout.css"; 5 | @import "post.css"; 6 | @import "prism.css"; 7 | 8 | :root { 9 | --background-color: #f1f1f1; 10 | --primary-font-color: #111; 11 | --brand-color: #c41d44; 12 | --heading-font-family: Georgia, 'Times New Roman', Times, serif; 13 | --layout-max-width: 50rem; 14 | --link-hover-color: #b31a3e; 15 | --link-focus-color: #8b1631; 16 | --logo-fill-color: #000; 17 | } 18 | @media (prefers-color-scheme: dark) { 19 | :root { 20 | --background-color: #0d1117; 21 | --primary-font-color: #fdfdfd; 22 | --brand-color: #ff2659; 23 | --link-hover-color: #d31a45; 24 | --link-focus-color: #b80831; 25 | --logo-fill-color: #f0f6fc; 26 | } 27 | } 28 | 29 | body { 30 | background-color: var(--background-color); 31 | color: var(--primary-font-color); 32 | font-family: "Roboto", sans-serif; 33 | } 34 | @media screen and (max-width: 840px) { 35 | body { 36 | padding-right: 1rem; 37 | padding-left: 1rem; 38 | } 39 | } 40 | @media print { 41 | body { 42 | background-color: #fff; 43 | } 44 | } 45 | 46 | a:not(.read-more, .site-pagination--link) { 47 | color: var(--brand-color); 48 | text-decoration: none; 49 | } 50 | a:not(.read-more, .site-pagination--link):hover { 51 | color: var(--link-hover-color); 52 | text-decoration: underline; 53 | } 54 | a:not(.read-more, .site-pagination--link):active { 55 | color: var(--link-focus-color); 56 | text-decoration: underline; 57 | outline: none; 58 | } 59 | a:not(.read-more, .site-pagination--link):focus { 60 | color: var(--link-focus-color); 61 | outline: 0 none; 62 | } 63 | a:not(.read-more, .site-pagination--link):focus-visible { 64 | outline: 2px solid var(--link-focus-color); 65 | } 66 | @media print { 67 | a:not(.read-more, .site-pagination--link) { 68 | color: #000; 69 | } 70 | } 71 | 72 | /* Helpers */ 73 | .h-hidden { 74 | border: 0; 75 | clip: rect(0 0 0 0); 76 | clip-path: inset(50%); 77 | height: 1px; 78 | margin: -1px; 79 | overflow: hidden; 80 | padding: 0; 81 | position: absolute; 82 | white-space: nowrap; 83 | width: 1px; 84 | } 85 | 86 | @media print { 87 | .print-hide { 88 | display: none; 89 | } 90 | } -------------------------------------------------------------------------------- /src/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /* Document 4 | ========================================================================== */ 5 | 6 | /** 7 | * 1. Correct the line height in all browsers. 8 | * 2. Prevent adjustments of font size after orientation changes in iOS. 9 | */ 10 | 11 | html { 12 | line-height: 1.5; /* 1 */ 13 | -webkit-text-size-adjust: 100%; /* 2 */ 14 | } 15 | 16 | /* Sections 17 | ========================================================================== */ 18 | 19 | /** 20 | * Remove the margin in all browsers. 21 | */ 22 | 23 | body { 24 | margin: 0; 25 | } 26 | 27 | /** 28 | * Render the `main` element consistently in IE. 29 | */ 30 | 31 | main { 32 | display: block; 33 | } 34 | 35 | /** 36 | * Correct the font size and margin on `h1` elements within `section` and 37 | * `article` contexts in Chrome, Firefox, and Safari. 38 | */ 39 | 40 | h1 { 41 | font-size: 2em; 42 | margin: 0.67em 0; 43 | } 44 | 45 | /* Grouping content 46 | ========================================================================== */ 47 | 48 | /** 49 | * 1. Add the correct box sizing in Firefox. 50 | * 2. Show the overflow in Edge and IE. 51 | */ 52 | 53 | hr { 54 | box-sizing: content-box; /* 1 */ 55 | height: 0; /* 1 */ 56 | overflow: visible; /* 2 */ 57 | } 58 | 59 | /** 60 | * 1. Correct the inheritance and scaling of font size in all browsers. 61 | * 2. Correct the odd `em` font sizing in all browsers. 62 | */ 63 | 64 | pre { 65 | font-family: monospace, monospace; /* 1 */ 66 | font-size: 1em; /* 2 */ 67 | } 68 | 69 | /* Text-level semantics 70 | ========================================================================== */ 71 | 72 | /** 73 | * Remove the gray background on active links in IE 10. 74 | */ 75 | 76 | a { 77 | background-color: transparent; 78 | } 79 | 80 | /** 81 | * 1. Remove the bottom border in Chrome 57- 82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 83 | */ 84 | 85 | abbr[title] { 86 | border-bottom: none; /* 1 */ 87 | text-decoration: underline; /* 2 */ 88 | text-decoration: underline dotted; /* 2 */ 89 | } 90 | 91 | /** 92 | * Add the correct font weight in Chrome, Edge, and Safari. 93 | */ 94 | 95 | b, 96 | strong { 97 | font-weight: bolder; 98 | } 99 | 100 | /** 101 | * 1. Correct the inheritance and scaling of font size in all browsers. 102 | * 2. Correct the odd `em` font sizing in all browsers. 103 | */ 104 | 105 | code, 106 | kbd, 107 | samp { 108 | font-family: monospace, monospace; /* 1 */ 109 | font-size: 1em; /* 2 */ 110 | } 111 | 112 | /** 113 | * Add the correct font size in all browsers. 114 | */ 115 | 116 | small { 117 | font-size: 80%; 118 | } 119 | 120 | /** 121 | * Prevent `sub` and `sup` elements from affecting the line height in 122 | * all browsers. 123 | */ 124 | 125 | sub, 126 | sup { 127 | font-size: 75%; 128 | line-height: 0; 129 | position: relative; 130 | vertical-align: baseline; 131 | } 132 | 133 | sub { 134 | bottom: -0.25em; 135 | } 136 | 137 | sup { 138 | top: -0.5em; 139 | } 140 | 141 | /* Embedded content 142 | ========================================================================== */ 143 | 144 | /** 145 | * Remove the border on images inside links in IE 10. 146 | */ 147 | 148 | img { 149 | border-style: none; 150 | } 151 | 152 | /* Forms 153 | ========================================================================== */ 154 | 155 | /** 156 | * 1. Change the font styles in all browsers. 157 | * 2. Remove the margin in Firefox and Safari. 158 | */ 159 | 160 | button, 161 | input, 162 | optgroup, 163 | select, 164 | textarea { 165 | font-family: inherit; /* 1 */ 166 | font-size: 100%; /* 1 */ 167 | line-height: 1.15; /* 1 */ 168 | margin: 0; /* 2 */ 169 | } 170 | 171 | /** 172 | * Show the overflow in IE. 173 | * 1. Show the overflow in Edge. 174 | */ 175 | 176 | button, 177 | input { /* 1 */ 178 | overflow: visible; 179 | } 180 | 181 | /** 182 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 183 | * 1. Remove the inheritance of text transform in Firefox. 184 | */ 185 | 186 | button, 187 | select { /* 1 */ 188 | text-transform: none; 189 | } 190 | 191 | /** 192 | * Correct the inability to style clickable types in iOS and Safari. 193 | */ 194 | 195 | button, 196 | [type="button"], 197 | [type="reset"], 198 | [type="submit"] { 199 | -webkit-appearance: button; 200 | } 201 | 202 | /** 203 | * Remove the inner border and padding in Firefox. 204 | */ 205 | 206 | button::-moz-focus-inner, 207 | [type="button"]::-moz-focus-inner, 208 | [type="reset"]::-moz-focus-inner, 209 | [type="submit"]::-moz-focus-inner { 210 | border-style: none; 211 | padding: 0; 212 | } 213 | 214 | /** 215 | * Restore the focus styles unset by the previous rule. 216 | */ 217 | 218 | button:-moz-focusring, 219 | [type="button"]:-moz-focusring, 220 | [type="reset"]:-moz-focusring, 221 | [type="submit"]:-moz-focusring { 222 | outline: 1px dotted ButtonText; 223 | } 224 | 225 | /** 226 | * Correct the padding in Firefox. 227 | */ 228 | 229 | fieldset { 230 | padding: 0.35em 0.75em 0.625em; 231 | } 232 | 233 | /** 234 | * 1. Correct the text wrapping in Edge and IE. 235 | * 2. Correct the color inheritance from `fieldset` elements in IE. 236 | * 3. Remove the padding so developers are not caught out when they zero out 237 | * `fieldset` elements in all browsers. 238 | */ 239 | 240 | legend { 241 | box-sizing: border-box; /* 1 */ 242 | color: inherit; /* 2 */ 243 | display: table; /* 1 */ 244 | max-width: 100%; /* 1 */ 245 | padding: 0; /* 3 */ 246 | white-space: normal; /* 1 */ 247 | } 248 | 249 | /** 250 | * Add the correct vertical alignment in Chrome, Firefox, and Opera. 251 | */ 252 | 253 | progress { 254 | vertical-align: baseline; 255 | } 256 | 257 | /** 258 | * Remove the default vertical scrollbar in IE 10+. 259 | */ 260 | 261 | textarea { 262 | overflow: auto; 263 | } 264 | 265 | /** 266 | * 1. Add the correct box sizing in IE 10. 267 | * 2. Remove the padding in IE 10. 268 | */ 269 | 270 | [type="checkbox"], 271 | [type="radio"] { 272 | box-sizing: border-box; /* 1 */ 273 | padding: 0; /* 2 */ 274 | } 275 | 276 | /** 277 | * Correct the cursor style of increment and decrement buttons in Chrome. 278 | */ 279 | 280 | [type="number"]::-webkit-inner-spin-button, 281 | [type="number"]::-webkit-outer-spin-button { 282 | height: auto; 283 | } 284 | 285 | /** 286 | * 1. Correct the odd appearance in Chrome and Safari. 287 | * 2. Correct the outline style in Safari. 288 | */ 289 | 290 | [type="search"] { 291 | -webkit-appearance: textfield; /* 1 */ 292 | outline-offset: -2px; /* 2 */ 293 | } 294 | 295 | /** 296 | * Remove the inner padding in Chrome and Safari on macOS. 297 | */ 298 | 299 | [type="search"]::-webkit-search-decoration { 300 | -webkit-appearance: none; 301 | } 302 | 303 | /** 304 | * 1. Correct the inability to style clickable types in iOS and Safari. 305 | * 2. Change font properties to `inherit` in Safari. 306 | */ 307 | 308 | ::-webkit-file-upload-button { 309 | -webkit-appearance: button; /* 1 */ 310 | font: inherit; /* 2 */ 311 | } 312 | 313 | /* Interactive 314 | ========================================================================== */ 315 | 316 | /* 317 | * Add the correct display in Edge, IE 10+, and Firefox. 318 | */ 319 | 320 | details { 321 | display: block; 322 | } 323 | 324 | /* 325 | * Add the correct display in all browsers. 326 | */ 327 | 328 | summary { 329 | display: list-item; 330 | } 331 | 332 | /* Misc 333 | ========================================================================== */ 334 | 335 | /** 336 | * Add the correct display in IE 10+. 337 | */ 338 | 339 | template { 340 | display: none; 341 | } 342 | 343 | /** 344 | * Add the correct display in IE 10. 345 | */ 346 | 347 | [hidden] { 348 | display: none; 349 | } 350 | -------------------------------------------------------------------------------- /src/css/post.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --code-block-background-color: #f9f9f9; 3 | --inline-code-background-color: #000; 4 | --inline-code-font-color: #fff; 5 | --code-color: #ea6155; 6 | --meta-font-color: #666; 7 | } 8 | @media (prefers-color-scheme: dark) { 9 | :root { 10 | --code-block-background-color: #1b222c; 11 | --inline-code-background-color: #d8dfe8; 12 | --inline-code-font-color: #000; 13 | --code-color: #ff8e84; 14 | --meta-font-color: #bbb; 15 | } 16 | } 17 | 18 | .post-meta { 19 | color: var(--meta-font-color); 20 | font-size: .8rem; 21 | margin-bottom: 1.5rem; 22 | } 23 | @media print { 24 | .post-meta a::after { 25 | content: " (" attr(href) ")"; 26 | } 27 | } 28 | 29 | .article-section { 30 | margin-bottom: 3rem; 31 | } 32 | .article-section img { 33 | max-width: 100%; 34 | } 35 | 36 | .list-section ul { 37 | margin: 0; 38 | } 39 | .list-section ul li { 40 | padding-left: .4rem; 41 | } 42 | .list-section ul li:not(:last-child) { 43 | margin-bottom: .2rem; 44 | } 45 | .list-section ul li::marker { 46 | content: url("/src/images/pentagram_icon.svg"); 47 | } 48 | 49 | .resources-section h2 { 50 | margin-bottom: .5rem; 51 | } 52 | .resources-section ul { 53 | margin-top: 0; 54 | } 55 | .resources-section ul li:not(:last-child) { 56 | margin-bottom: .2rem; 57 | } 58 | 59 | @media print { 60 | .resources-section a::after { 61 | content: " (" attr(href) ")"; 62 | } 63 | } 64 | 65 | .post-tip { 66 | background-color: #f9f9f9; 67 | border: .125rem dashed var(--brand-color); 68 | padding: 1rem; 69 | } 70 | 71 | pre[class*="language-"] { 72 | background-color: var(--code-block-background-color); 73 | border: .0625rem dashed #000; 74 | overflow: auto; 75 | padding: 1rem; 76 | position: relative; 77 | } 78 | @media print { 79 | pre[class*="language-"] { 80 | background-color: #fff; 81 | } 82 | } 83 | pre[class*="language-"]::before { 84 | background-color: #dfdddd; 85 | color: #333; 86 | font-family: "Roboto", sans-serif; 87 | font-size: .6rem; 88 | font-weight: 600; 89 | position: absolute; 90 | right: .5rem; 91 | top: 0; 92 | padding-top: .2rem; 93 | padding-right: .5rem; 94 | padding-bottom: .1rem; 95 | padding-left: .5rem; 96 | } 97 | pre[class*="language-css"]::before { 98 | content: "CSS"; 99 | } 100 | pre[class*="language-html"]::before { 101 | content: "HTML"; 102 | } 103 | 104 | code[class*="language-"] { 105 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 106 | color: var(--code-color); 107 | } 108 | @media print { 109 | code[class*="language-"] { 110 | color: #000; 111 | } 112 | } 113 | 114 | code:not([class*="language-"]) { 115 | background-color: var(--inline-code-background-color); 116 | color: var(--inline-code-font-color); 117 | display: inline-block; 118 | font-weight: 600; 119 | line-height: 1; 120 | padding-top: .2rem; 121 | padding-right: .3rem; 122 | padding-bottom: .1rem; 123 | padding-left: .3rem; 124 | } 125 | 126 | kbd { 127 | background-color: #555; 128 | color: #fff; 129 | display: inline-block; 130 | font-weight: 600; 131 | line-height: 1; 132 | padding-top: .2rem; 133 | padding-right: .3rem; 134 | padding-bottom: .1rem; 135 | padding-left: .3rem; 136 | } 137 | -------------------------------------------------------------------------------- /src/css/prism.css: -------------------------------------------------------------------------------- 1 | .token.comment, 2 | .token.block-comment, 3 | .token.prolog, 4 | .token.doctype, 5 | .token.cdata { 6 | color: #9e7141; 7 | font-family: Georgia, serif; 8 | font-style: italic; 9 | } 10 | @media print { 11 | .token.comment, 12 | .token.block-comment, 13 | .token.prolog, 14 | .token.doctype, 15 | .token.cdata { 16 | color: #666; 17 | } 18 | } 19 | @media (prefers-color-scheme: dark) { 20 | .token.comment, 21 | .token.block-comment, 22 | .token.prolog, 23 | .token.doctype, 24 | .token.cdata { 25 | color: #e7ae70; 26 | } 27 | } 28 | 29 | .token.punctuation { 30 | color: #fc669a; 31 | } 32 | @media print { 33 | .token.punctuation { 34 | color: #666; 35 | } 36 | } 37 | 38 | .token.tag, 39 | .token.attr-name, 40 | .token.namespace, 41 | .token.deleted { 42 | color: #098a79; 43 | } 44 | @media print { 45 | .token.tag, 46 | .token.attr-name, 47 | .token.namespace, 48 | .token.deleted { 49 | color: #666; 50 | } 51 | } 52 | @media (prefers-color-scheme: dark) { 53 | .token.tag, 54 | .token.attr-name, 55 | .token.namespace, 56 | .token.deleted { 57 | color: #0dcab1; 58 | } 59 | } 60 | 61 | .token.function-name { 62 | color: #6196cc; 63 | } 64 | 65 | .token.boolean, 66 | .token.number, 67 | .token.function { 68 | color: #f08d49; 69 | } 70 | @media print { 71 | .token.boolean, 72 | .token.number, 73 | .token.function { 74 | color: #000; 75 | } 76 | } 77 | @media (prefers-color-scheme: dark) { 78 | .token.boolean, 79 | .token.number, 80 | .token.function { 81 | color: #ffab73; 82 | } 83 | } 84 | 85 | .token.property, 86 | .token.class-name, 87 | .token.constant, 88 | .token.symbol { 89 | color: #2d7192; 90 | } 91 | @media print { 92 | .token.property, 93 | .token.class-name, 94 | .token.constant, 95 | .token.symbol { 96 | color: #000; 97 | } 98 | } 99 | @media (prefers-color-scheme: dark) { 100 | .token.property, 101 | .token.class-name, 102 | .token.constant, 103 | .token.symbol { 104 | color: #54c7ff; 105 | } 106 | } 107 | 108 | .token.selector, 109 | .token.important, 110 | .token.atrule, 111 | .token.keyword, 112 | .token.builtin { 113 | color: #93329b; 114 | } 115 | @media print { 116 | .token.selector, 117 | .token.important, 118 | .token.atrule, 119 | .token.keyword, 120 | .token.builtin { 121 | color: #000; 122 | } 123 | } 124 | @media (prefers-color-scheme: dark) { 125 | .token.selector, 126 | .token.important, 127 | .token.atrule, 128 | .token.keyword, 129 | .token.builtin { 130 | color: #f085fa; 131 | } 132 | } 133 | 134 | .token.string, 135 | .token.char, 136 | .token.attr-value, 137 | .token.regex, 138 | .token.variable { 139 | color: #b73484; 140 | } 141 | @media print { 142 | .token.string, 143 | .token.char, 144 | .token.attr-value, 145 | .token.regex, 146 | .token.variable { 147 | color: #000; 148 | } 149 | } 150 | @media (prefers-color-scheme: dark) { 151 | .token.string, 152 | .token.char, 153 | .token.attr-value, 154 | .token.regex, 155 | .token.variable { 156 | color: #ff82cf; 157 | } 158 | } 159 | 160 | .token.operator, 161 | .token.entity, 162 | .token.url { 163 | color: #67cdcc; 164 | } 165 | 166 | .token.important, 167 | .token.bold { 168 | font-weight: bold; 169 | } 170 | 171 | .token.italic { 172 | font-style: italic; 173 | } 174 | 175 | .token.entity { 176 | cursor: help; 177 | } 178 | 179 | .token.inserted { 180 | color: green; 181 | } -------------------------------------------------------------------------------- /src/images/csshell_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cat-a-flame/CSSHell/1f43161578daee032d5a481acb6da5d5a0a7b75e/src/images/csshell_logo.png -------------------------------------------------------------------------------- /src/images/csshell_logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cat-a-flame/CSSHell/1f43161578daee032d5a481acb6da5d5a0a7b75e/src/images/favicon-16x16.png -------------------------------------------------------------------------------- /src/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cat-a-flame/CSSHell/1f43161578daee032d5a481acb6da5d5a0a7b75e/src/images/favicon-32x32.png -------------------------------------------------------------------------------- /src/images/pentagram_icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/images/posts/specificity.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 29 | 31 | 35 | 39 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 55 | 57 | 59 | 61 | 63 | 67 | 68 | 69 | 70 | 71 | 72 | 74 | 75 | 86 | 87 | 88 | 89 | 90 | 91 | 93 | 94 | 95 | 96 | 97 | 98 | 100 | 101 | 112 | 113 | 114 | 115 | 116 | 119 | 121 | 125 | 129 | 133 | 137 | 141 | 143 | 147 | 149 | 151 | 154 | 156 | 159 | 161 | 163 | 167 | 171 | 173 | 177 | 181 | 185 | 187 | 190 | 193 | 194 | 197 | 199 | 203 | 207 | 211 | 215 | 219 | 220 | 221 | 222 | 223 | 224 | 226 | 227 | 238 | 239 | 240 | 241 | 242 | 246 | 248 | 252 | 255 | 259 | 261 | 263 | 267 | 269 | 273 | 277 | 281 | 283 | 286 | 289 | 290 | 294 | 296 | 300 | 303 | 307 | 309 | 311 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 324 | 326 | 330 | 334 | 336 | 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /src/js/prism.js: -------------------------------------------------------------------------------- 1 | /* PrismJS 1.23.0 2 | https://prismjs.com/download.html#themes=prism-tomorrow&languages=css */ 3 | var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,e={},M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=l.reach);y+=m.value.length,m=m.next){var b=m.value;if(t.length>n.length)return;if(!(b instanceof W)){var k,x=1;if(h){if(!(k=z(v,y,n,f)))break;var w=k.index,A=k.index+k[0].length,P=y;for(P+=m.value.length;P<=w;)m=m.next,P+=m.value.length;if(P-=m.value.length,y=P,m.value instanceof W)continue;for(var E=m;E!==t.tail&&(Pl.reach&&(l.reach=N);var j=m.prev;O&&(j=I(t,j,O),y+=O.length),q(t,j,x);var C=new W(o,g?M.tokenize(S,g):S,d,S);if(m=I(t,j,C),L&&I(t,m,L),1l.reach&&(l.reach=_.reach)}}}}}}(e,a,n,a.head,0),function(e){var n=[],t=e.head.next;for(;t!==e.tail;)n.push(t.value),t=t.next;return n}(a)},hooks:{all:{},add:function(e,n){var t=M.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=M.hooks.all[e];if(t&&t.length)for(var r,a=0;r=t[a++];)r(n)}},Token:W};function W(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=0|(r||"").length}function z(e,n,t,r){e.lastIndex=n;var a=e.exec(t);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function i(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function I(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function q(e,n,t){for(var r=n.next,a=0;a"+a.content+""},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),t=n.language,r=n.code,a=n.immediateClose;u.postMessage(M.highlight(r,M.languages[t],t)),a&&u.close()},!1)),M;var t=M.util.currentScript();function r(){M.manual||M.highlightAll()}if(t&&(M.filename=t.src,t.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var a=document.readyState;"loading"===a||"interactive"===a&&t&&t.defer?document.addEventListener("DOMContentLoaded",r):window.requestAnimationFrame?window.requestAnimationFrame(r):window.setTimeout(r,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); 4 | !function(s){var e=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),string:{pattern:e,greedy:!0},property:/(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(Prism); 5 | -------------------------------------------------------------------------------- /src/robots.txt: -------------------------------------------------------------------------------- 1 | Sitemap: https://csshell.dev/sitemap.xml 2 | 3 | User-agent: * 4 | Disallow: --------------------------------------------------------------------------------