{"@context":{"rdf":"http://www.w3.org/1999/02/22-rdf-syntax-ns#","rdfs":"http://www.w3.org/2000/01/rdf-schema#","owl":"http://www.w3.org/2002/07/owl#","foaf":"http://xmlns.com/foaf/0.1/","dc":"http://purl.org/dc/elements/1.1/","dct":"http://purl.org/dc/terms/","sioc":"http://rdfs.org/sioc/types#","blog":"http://vocab.amy.so/blog#","as":"https://www.w3.org/ns/activitystreams#","mf2":"http://microformats.org/profile/","ldp":"http://www.w3.org/ns/ldp#","solid":"http://www.w3.org/ns/solid#","view":"https://terms.rhiaro.co.uk/view#","asext":"https://terms.rhiaro.co.uk/as#","dbp":"http://dbpedia.org/property/","geo":"http://www.w3.org/2003/01/geo/wgs84_pos#","doap":"http://usefulinc.com/ns/doap#","time":"http://www.w3.org/2006/time#"},"@graph":[{"@id":"https://rhiaro.co.uk/2012/05/stylesheet","@type":"as:Article","blog:bloggerid":"tag:blogger.com,1999:blog-18505529.post-979096441285034894","as:actor":{"@id":"http://www.blogger.com/profile/12227954801080178130"},"as:content":"
About a year and a half ago I realised I needed to get a grip on how to\r\norganise my CSS. I established a template, which I proceeded to change\r\ndrastically with every new project. I noticed recently that I've been reusing\r\na version for the past few projects, with at the most only minor amendments to\r\nthe general structure. I also noticed how quickly I'm rolling out initial\r\ndesigns using this template.
\r\nI have finally reached the point where I figured out what I consistently reuse\r\nacross projects, and finally have a stylesheet structure that makes such\r\nintuitive sense to me I can dart around and make changes with my eyes closed.\r\nI find my stylesheets are much smaller, but even as they grow, I still know\r\nexactly where everything is. I wish I had some statistics to quote about the\r\namount of time spent scrolling through CSS looking for things. I'm confident\r\nit is much reduced.
\r\nSome aspects of my workflow I developed through intuition; I made changes that\r\nfelt right to me at the time, without really consulting anyone else's best\r\npractices. Other things I picked up from here and there. Every now and again\r\nI'd search for 'the right way' of doing this and find processes and systems\r\nthat didn't gel with me (a primary example of this being the number of pre-\r\nbuilt grid systems I tried and hated). Eventually I would give up under the\r\nsheer number of contradicting points of view, but I probably picked up some\r\nsubconscious inspiration on the way.
\r\nI hadn't thought much of this until Chris\r\nEppstein talked about this at\r\nFOWD today. A lot of the\r\nsuggestions he demo'd are very similar to parts of my system (conceptually at\r\nleast; he was discussing SASS and mine is raw CSS). So I figured it's reached\r\nthe point it is worth sharing.
\r\nFirst things first, I start with a basic\r\nInitializr stylesheet; a couple\r\nof minor tweaks, but then I largely accept the helper classes and IE fixes and\r\nhacks (no need to read this; it's just here for completeness):
\r\n/* ====================================================================== \r\nHTML5 Boilerplate CSS: h5bp.com/css \r\n========================================================================== */ \r\n\r\narticle, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; } \r\naudio, canvas, video { display: inline-block; *display: inline; *zoom: 1; } \r\naudio:not([controls]) { display: none; } \r\n[hidden] { display: none; } \r\n\r\nhtml { height: 100%, font-size: 62.5%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } \r\nhtml, button, input, select, textarea { font-family: sans-serif; color: #222; } \r\nbody { height: 100%; margin: 0; padding: 0; font-size: 1em; } \r\n\r\n::-moz-selection { background: #fe57a1; color: #fff; text-shadow: none; } \r\n::selection { background: #fe57a1; color: #fff; text-shadow: none; } \r\n\r\na { color: #00e; } \r\na:visited { color: #551a8b; } \r\na:hover { color: #06e; } \r\na:focus { outline: thin dotted; } \r\na:hover, a:active { outline: 0; } \r\n\r\nabbr[title] { border-bottom: 1px dotted; } \r\nb, strong { font-weight: bold; } \r\nblockquote { margin: 1em 40px; } \r\ndfn { font-style: italic; } \r\nhr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; } \r\nins { background: #ff9; color: #000; text-decoration: none; } \r\nmark { background: #ff0; color: #000; font-style: italic; font-weight: bold; } \r\npre, code, kbd, samp { font-family: monospace, serif; _font-family: 'courier new', monospace; font-size: 1em; } \r\npre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; } \r\nq { quotes: none; } \r\nq:before, q:after { content: \"\"; content: none; } \r\nsmall { font-size: 85%; } \r\n\r\nsub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } \r\nsup { top: -0.5em; } \r\nsub { bottom: -0.25em; } \r\n\r\nul, ol { margin: 1em 0; padding: 0 0 0 40px; } \r\ndd { margin: 0 0 0 40px; } \r\nnav ul, nav ol { list-style: none; list-style-image: none; margin: 0; padding: 0; } \r\n\r\nimg { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; } \r\n\r\nsvg:not(:root) { overflow: hidden; } \r\n\r\nfigure { margin: 0; } \r\n\r\nform { margin: 0; } \r\nfieldset { border: 0; margin: 0; padding: 0; } \r\nlabel { cursor: pointer; } \r\nlegend { border: 0; *margin-left: -7px; padding: 0; white-space: normal; } \r\nbutton, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; } \r\nbutton, input { line-height: normal; } \r\nbutton, input[type=\"button\"], input[type=\"reset\"], input[type=\"submit\"] { cursor: pointer; -webkit-appearance: button; *overflow: visible; } \r\nbutton[disabled], input[disabled] { cursor: default; } \r\ninput[type=\"checkbox\"], input[type=\"radio\"] { box-sizing: border-box; padding: 0; *width: 13px; *height: 13px; } \r\ninput[type=\"search\"] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; } \r\ninput[type=\"search\"]::-webkit-search-decoration, input[type=\"search\"]::-webkit-search-cancel-button { -webkit-appearance: none; } \r\nbutton::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; } \r\ntextarea { overflow: auto; vertical-align: top; resize: vertical; } \r\ninput:valid, textarea:valid { } \r\ninput:invalid, textarea:invalid { background-color: #f0dddd; } \r\n\r\ntable { border-collapse: collapse; border-spacing: 0; } \r\ntd { vertical-align: top; } \r\n\r\n.chromeframe { margin: 0.2em 0; background: #ccc; color: black; padding: 0.2em 0; } \r\n\r\n/* =============== \r\n ALL: IE Fixes \r\n =============== */ \r\n\r\n.ie7 #title{ padding-top:20px; } \r\n\r\n/*******************************************/ \r\n/* */ \r\n/* My styles go here! */ \r\n/* */ \r\n/*******************************************/ \r\n\r\n/* ============================================================================= \r\n Non-Semantic Helper Classes \r\n ========================================================================== */ \r\n\r\n.ir { display: block; border: 0; text-indent: -999em; overflow: hidden; background-color: transparent; background-repeat: no-repeat; text-align: left; direction: ltr; *line-height: 0; } \r\n.ir br { display: none; } \r\n.hidden { display: none !important; visibility: hidden; } \r\n.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } \r\n.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; } \r\n.invisible { visibility: hidden; } \r\n.clearfix:before, .clearfix:after { content: \"\"; display: table; } \r\n.clearfix:after { clear: both; } \r\n.clearfix { *zoom: 1; } \r\n\r\n/* ============================================================================= \r\n Print Styles \r\n ========================================================================== */ \r\n\r\n@media print { \r\n * { background: transparent !important; color: black !important; box-shadow:none !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; } /* Black prints faster: h5bp.com/s */ \r\n a, a:visited { text-decoration: underline; } \r\n a[href]:after { content: \" (\" attr(href) \")\"; } \r\n abbr[title]:after { content: \" (\" attr(title) \")\"; } \r\n .ir a:after, a[href^=\"javascript:\"]:after, a[href^=\"#\"]:after { content: \"\"; } /* Don't show links for images, or javascript/internal links */ \r\n pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } \r\n thead { display: table-header-group; } /* h5bp.com/t */ \r\n tr, img { page-break-inside: avoid; } \r\n img { max-width: 100% !important; } \r\n @page { margin: 0.5cm; } \r\n p, h2, h3 { orphans: 3; widows: 3; } \r\n h2, h3 { page-break-after: avoid; } \r\n}
\r\nMy template is inserted into the appropriate point of the Initializr\r\nstylesheet. I divide into five sections:
\r\n/* 0 Accessibility */ \r\n\r\n/* 1 Typography */ \r\n\r\n/* 2 Colours & borders */ \r\n\r\n/* 3 Spacing & layout */ \r\n\r\n/* 4 Images & video */
\r\nI start each section with empty media query clauses for 480px and up, 768px\r\nand up, 1024px and up, and 1200px and up. By the time a project is done each\r\nsection will typically have from one to six media query breakpoints in it,\r\naccording to requirements.
\r\n0\\\\\\\\. Accessibility
\r\nA staple of this so far is:
\r\n/** \r\n 0 Accessibility \r\n**/ \r\n.no-css { \r\n /* This class hides stuff that needs to be around for screenreaders or users with no CSS, but not in normal circumstances */ \r\n position: absolute; left: -1000px; \r\n}
\r\nWhich I chuck in when I use visuals to enhance some content, to hide an\r\nappropriately positioned textual equivalent.
\r\nThere's probably more useful stuff that should be here. I'm working on it.\r\n(Suggestions welcome!).
\r\n1\\\\\\\\. Typography
\r\nNot a lot going on here. Some obvious placeholders, plus a couple of classes I\r\nfound myself needing over and over, which should be self explanatory (.win and\r\n.fail are applied to success or error messages; usually a form submission is\r\ninvolved).
\r\n/** \r\n 1 Typography \r\n**/ \r\n\r\nh1 {} \r\nh2 {} \r\nh3 {} \r\nh4 {} \r\n\r\np {} \r\na { text-decoration: inherit; } \r\na:hover { text-decoration: underline; } \r\n\r\n.note { \r\n font-size: 1em; \r\n font-weight: bold; \r\n text-align: right; \r\n} \r\n\r\n.wee { \r\n font-size: 0.8em; \r\n} \r\n\r\n.win, .fail {}
\r\nIn typography, I strictly only include font stuff like faces, sizes,\r\nalignment, decoration and enhancements like text-decoration, font-weight.
\r\n2\\\\\\\\. Colours and borders
\r\nBorder styles go here because they need to be defined before the border\r\ncolours are. Otherwise, just colours go here:
\r\n/* Borders */ \r\n .win, .fail { border: 2px solid; } \r\n\r\n/* Dark */ \r\n .dark { color: #2d2d2d;} \r\n .dark-bg { background-color: #2d2d2d; } \r\n .darker{ color: #000; } \r\n .darker-bg { background-color: #000; } \r\n\r\n/* Primary Color */ \r\n .color1 { color: green; } \r\n .color1-bg { background-color: green; } \r\n .color1-border { border-color: green; } \r\n .color1-texture { } \r\n\r\n/* Secondary Color */ \r\n .color2 { color: yellow; } \r\n .color2-bg { background-color: yellow; } \r\n .color2-border { border-color: yellow; } \r\n .color2-texture { } \r\n\r\n/* Tertiary Color */ \r\n .color3 { color: red; } \r\n .color3-bg { background-color: red; } \r\n .color3-border { border-color: red; } \r\n .color3-texture { } \r\n\r\n/* Light */ \r\n .light { color: #ccc; } \r\n .light-bg { background-color: #ccc; } \r\n .lighter { color: #fff; } \r\n .lighter-bg { background-color: #fff; } \r\n\r\n.note { color: silver; } \r\n\r\n.win { \r\n background-color: #E6EFC2; \r\n color:#264409; \r\n border-color:#C6D880; \r\n} \r\n\r\n.fail { \r\n background:#FBE3E4; \r\n color:#8a1f11; \r\n border-color:#FBC2C4; \r\n}
\r\nAfter border styles, I start with the colour scheme, creating classes for text\r\ncolours, background colours and border colours. It's unusual to need to go\r\nbeyond a tertiary colour, and typically I only have primary and secondary.\r\nThis leaves me with classes I can apply to any elements in my html templates,\r\nmaking it really quick and easy to experiment with different colour\r\ncombinations. The color*-texture classes come in handy when I have textured\r\nbackgrounds that match the colour scheme, and would include the background\r\nimage (a repeating square of noise texture for example) and a background-\r\ncolour as a backup.
\r\nMost of the time I don't want to be applying classes to everything to add\r\ncolour though. I list elements that I'm confident aren't going to change in\r\nthe mark-up which need colours applying to them, for example:
\r\n/** \r\n 2 Colours and borders \r\n**/ \r\n\r\n/* Primary colour */ \r\n .color1, body { color: green; } \r\n .color1-bg, nav, footer { background-color: green; } \r\n\r\n/* Secondary Color */ \r\n .color2, nav { color: yellow; } \r\n .color2-bg, body { background-color: yellow; } \r\n\r\n/* ...etc... */
\r\nI'm a fan of using off-white and off-black, so these are what I originally\r\npicked for my .light and .dark classes, which are always handy to have.\r\nSometimes pure black and white are necessary too though, so the .lighter and\r\n.darker classes were born.
\r\nYou can see .note, .win and .fail show up here too.
\r\nThis pretty much means this is as long as the colours section will ever get. I\r\ndon't apply colours anywhere else in the stylesheet, and it helps to ensure I\r\nstick to a colour scheme and don't get carried away with exceptions.\r\nObviously, this also makes it super easy to change the colour scheme uniformly\r\nin a couple of seconds.
\r\n3\\\\\\\\. Spacing and grid
\r\nAs I already mentioned, I have poked around with some of the existing flexible\r\ngrid frameworks but none of them grabbed me. They all seemed to have too much.\r\nThe minimalist system I came up with has answered all of my needs so far,\r\nalthough I wouldn't claim it's suitable for every project in the world. It's\r\nalso subject to tweaks, depending on the project of the moment.
\r\nI stick with Initializr's .wrapper class, which is 100% width until the\r\nviewport reaches 1024px, when it snaps to 900px wide. This is my default\r\nbecause it's been the most frequently appropriate so far. I have an ongoing\r\nproject at the moment where the target audience are largely gamers, so\r\ncapitalising on the excessive screen real estate they'll probably have means I\r\nstripped out this restriction in favour of a full width multi-column layout\r\nwhen the device allows.
\r\nI haven't yet had a need to go above five columns for my grid. I express my\r\nclass names like fractions, and start off with only the 1/2, 1/3 and 2/3 ones\r\ntaking up the correct proportion of the screen, with the others defaulting to\r\n100%. This then changes for wider-than-small viewports, as you can see.
\r\nThere are a few navigation list related things in there that I often find\r\nmyself duplicating across projects (like a default centre-aligned stacked menu\r\nwhich progresses to a floating horizontal version). I pad my a elements (as\r\nopposed to their containing li elements) to enlarge the touch area for links.\r\nPlus some nth-child stuff for three column layouts, for keeping consistent row\r\nheights when the column heights are different.
\r\n/** \r\n 3 Spacing & Grid \r\n**/ \r\n\r\n.wrapper { \r\n width: 100%; \r\n} \r\n\r\n/* Grid */ \r\n.w1of2 { width: 50%; float: left; } \r\n.w1of3 { width: 33%; float: left; } \r\n.w2of3 { width: 66%; float; left; } \r\n.w1of1, .w1of4, .w1of5, \r\n.w3of4, .w2of5, .w3of5, .w4of5 { \r\n width: 100%; \r\n} \r\n\r\n.inner { \r\n padding: 1em; \r\n} \r\n\r\nnav { \r\n max-width: 100%; \r\n} \r\n\r\nnav a { \r\n display: block; \r\n padding: 0.8em; \r\n} \r\n\r\n.inline { display: inline; } \r\n\r\n.win, .fail { \r\n padding: 0.2em; \r\n display: block; \r\n} \r\n\r\n/* 3.1 */ \r\n @media screen and (min-width: 479px){ \r\n\r\n nav li { float: left; } \r\n } \r\n\r\n/* 3.2 */ \r\n @media screen and (min-width: 768px){ \r\n .w1of2 { width: 50%; float: left; } \r\n .w1of3 { width: 33%; float: left; } \r\n .w1of4 { width: 25%; float: left; } \r\n .w1of5 { width: 20%; float: left; } \r\n .w2of3 { width: 66%; float: left; } \r\n .w3of4 { width: 75%; float: left; } \r\n .w2of5 { width: 40%; float: left; } \r\n .w3of5 { width: 60%; float: left; } \r\n .w4of5 { width: 80%; float: left; } \r\n\r\n .w1of3:nth-child(odd) { clear: none; } \r\n .w1of3:nth-child(3n-2) { clear: both; } \r\n } \r\n\r\n/* 3.3 */ \r\n @media screen and (min-width: 1024px){ \r\n .wrapper { \r\n width: 900px; \r\n margin-left: auto; margin-right: auto; \r\n } \r\n }
\r\nEverything that goes in this section is to do with spacing: padding, margins,\r\npositioning, floating, wrapping... et cetera.
\r\n4\\\\\\\\. Images and video
\r\nMost projects call for tweaks to images that may or may not fit into the other\r\nsections of the stylesheet. Nonetheless, my brain copes better with I group\r\nthem all together. Flexible YouTube video embed lives here too.
\r\n/** \r\n 4.0 Images and video \r\n**/ \r\n\r\n.vid-holder { \r\n position: relative; \r\n padding-bottom: 56.25%; \r\n padding-top: 30px; \r\n height: 0; \r\n overflow: hidden; \r\n} \r\n\r\n.vid-holder iframe, \r\n.vid-holder object, \r\n.vid-holder embed { \r\n position: absolute; \r\n top: 0; \r\n left: 0; \r\n width: 100%; \r\n height: 100%; \r\n} \r\n\r\n/* Full width images on bigger than small screens are dumb. Reset this. */ \r\n@media screen and (max-width: 478px){ \r\n .w1of1 img, .w1of2 img, .w1of3 img, .w1of4 img, .w1of5 img, \r\n .w2of3 img, .w3of4 img, .w2of5 img, .w3of5 img, .w4of5 img { \r\n width: 100%; \r\n } \r\n}
\r\nAnd that's what I start all projects with. Here is it all\r\nassembled, with a few of the classes throw into\r\nthe mark-up so you can see what's going on. If (when) I end up doing another\r\nmajor update, I shall probably write about it again.
","as:name":"Stylesheet organisation","as:published":{"@type":"http://www.w3.org/2001/XMLSchema#datetime","@value":"2012-05-17T16:25:00.000Z"},"as:tag":[{"@id":"https://rhiaro.co.uk/tags/doing"},{"@id":"blog:Doing"},{"@id":"https://rhiaro.co.uk/tags/clean+css"},{"@id":"https://rhiaro.co.uk/tags/cleanstyles"},{"@id":"https://rhiaro.co.uk/tags/css"},{"@id":"https://rhiaro.co.uk/tags/fowd"},{"@id":"https://rhiaro.co.uk/tags/frontend"},{"@id":"https://rhiaro.co.uk/tags/hacking"},{"@id":"https://rhiaro.co.uk/tags/learning"},{"@id":"https://rhiaro.co.uk/tags/stylesheet+organisation"},{"@id":"https://rhiaro.co.uk/tags/web+dev"}],"as:updated":{"@type":"http://www.w3.org/2001/XMLSchema#datetime","@value":"2013-04-01T00:11:02.726Z"}},{"@id":"https://rhiaro.co.uk/tags/fowd","@type":"as:Collection","as:totalItems":{"@type":"http://www.w3.org/2001/XMLSchema#nonNegativeInteger","@value":"1"}},{"@id":"https://rhiaro.co.uk/tags/fowd?before=https://rhiaro.co.uk/2012/05/stylesheet&limit=16","@type":"as:CollectionPage","as:items":{"@id":"https://rhiaro.co.uk/2012/05/stylesheet"},"as:name":"fowd","as:partOf":{"@id":"https://rhiaro.co.uk/tags/fowd"}}]}