DEV Community

Cover image for What should production CSS look like? Share your layout-to-web workflow
Jen Chan
Jen Chan

Posted on • Edited on

What should production CSS look like? Share your layout-to-web workflow

When someone asks you to build a layout in HTML and CSS, how do you approach it? And how do you approach it in a test, versus working for production?

I've been interviewing, testing, and can't seem to figure out what the bar is. I have worked at places with long af .css sheets, and others with LESS compiled ones. Previously I based my ideas of how to write CSS on docs I had seen or glitch.com examples. I had also heard of the need to modularize CSS for different components to make it more reusable and shorter, and thus easier to read.

How I do It:

  1. Make sure I've got prettier or a linter installed on VSCode.
  2. Slice layout with guides in Photoshop, measure between elements
  3. Decide which areas require grid and flexbox.
  4. Start new HTML doc, embed external CSS file, convert px to em, include 3 media queries OR prototype with tachyons or bootstrap
  5. OR Include all interactions with vanilla JS or use a JS framework

Docs and library code looks really thorough (ie. media queries for small, medium, desktop screens), and so I try to mimic that. After getting some feedback I realize that I'm overcomplicating stuff and my CSS is disorganized.

Here's some things I've gathered for improvement so far:

  • if using grid, use height: 100vh to make the minimum height appear the height of the viewport
  • apply style using classes with semantic names instead of IDs or elements (i.e. .site_header instead of #header ul)
  • include cross-browser prefixes for any animations or exceptions (i.e. for drop-capitals in Safari or webkit- for Safari and moz- for Firefox and ms- for IE. Using an autoprefixer makes that easier.
  • convert any sizes to em and rem instead of px
  • Use grid or flexbox where available, always stick to a grid
  • Write as little to accomplish the most as possible, detailing margin and padding on every little thing makes your styles confusing for someone else to read.
  • To make everything show as the size it should in the design, use *{box-sizing: border-box;}
  • Stay away from inline styling at all costs.
  • float as a positioning selector is a thing of the past.
  • !important does not always fix a problem

I'm open to you challenging any of these since this is cobbled-together afterthought based on medium posts and observing glitch community examples

I also have some questions for devs:

  1. What do you do about responsiveness for mobiles when you get one layout? I totally get clarifying with the designer about what the decisions around positioning and stacking order may be and communication is key.But in the test situation or working with freelance clients who don't always know what they want, what do you usually do? I default to a hamburger menu with a slide/dropdown.

  2. Any particular choice on grid (4, 10 or 12 columns. 30em, 40em) ?
    I'm really tempted to use exact pixels on a smaller number of columns to make it match the desktop version as much as possible but ultimately I'm really confused about this. I've also seen grid layouts with the smallest grid item repeated 9 times... I suppose it depends on the design.

  3. How many media queries do you include? How do you decide where the breakpoints are?
    I have seen totally functional examples with folks writing for only one screensize (400px or 768px). Is that enough?

  4. Any opinions on using CSS vs JS for animations?

  5. At what point do you see it necessary to use SASS or LESS? Is BEM still a thing?

Annnd... while it is my life goal to be really good at JS, I can't help being curious. I've discovered CSS is something I'm prone to think it's easy to be good at, but actually full of so many specifics.
... any other thoughts or crits are much appreciated! Thank you for reading!

Update: Just discovered Jen Simmons' Layout Land series on YouTube and added a link to that because she's so great at explaining the differences and pros/cons to CSS grid/flexbox

Some other sources I'd been reading over the last few years:
Simplify Styling with Functional CSS | Rangle.io
Common responsive layouts with CSS grid and some without | Medium
Beginner's Guide to Choose Between Grid and Flexbox | Medium
CSS Grid Starter Layouts | CSS-Tricks
Holy Grail Layout CSS Grid
In Simple Terms: CSS vs Javascript
Myth-busting CSS Animations vs Javascript
Flexbox vs. CSS Grid โ€” Which is Better? | Jen Simmons for LayoutLand on YouTube

Top comments (40)

Collapse
 
whoisryosuke profile image
Ryosuke
  1. Since mobile development tends to be one, maybe two col max, if I'm only provided a desktop version of the design, I just run with it and simplify/distill the design down. If there's any elements that don't work on mobile, they get cut out completely until the designer complains and sends over a more mobile-friendly design ๐Ÿ˜ Unless you're hired as the designer, or you're included in the design process, it's not your job to "get creative" or "invent" solutions to design problems that should have been resolved in the wireframe/mockup phase.

  2. No preference on grid size really. I tend to use 5 and 24 cols, since they're most prevalent in grid systems, but I'll use 3/4/8/16/anything that looks right/makes the design work best.

  3. At minimum for any project, one media query (either for desktop or mobile), and the base CSS defaults to the other. If the design is more complex, I add media queries as necessary to correct issues at the problem breakpoint (usually at uber-wide resolutions if the site's audience is rocking 4k double-wide monitors, or small fixes for absolutely positioned elements)

  4. CSS/SASS for most animations, unless it's so complex that it requires JS (JS functionality like checking animation frames or DOM elements, or using a lib like GreenSock). Going CSS-first usually ensures the highest level of browser compatibility, particularly since animations will work even when JS is disabled client-side.

  5. I use SASS when the project is so large I'll be using variables across the app (which could be replaced with CSS vars) and when I need the power of mixins to simplify CSS generation (like grids, complex animations, or repetitive actions). Otherwise pure CSS run through a minification process (Gulp/Grunt/Webpack/Parcel) before it's deployed to prod works fine. I tend to use BEM combined with OOCSS, so I have non-conflicting CSS styles (.HeaderMenu with .HeaderMenu > .list and .HeaderMenu .item nested classes). That way I get non-conflicting base styles, with without the verbose BEM sub-classes (.HeaderMenu__item) and my shorter CSS classnames work fine thanks to specificity. Similar to Airbnb's CSS style guide (BEM component-style names), combined with Semantic UI's (OOCSS).

Collapse
 
jenc profile image
Jen Chan

Thanks for the thorough answers Ryosuke! Re: 5. This is giving me clear insight on why to use SASS. I've given it a half-hearted shot at learning but never felt a personal project of mine needed it. I forgot about mix-ins too, which could be fun. I do enjoy the facility of using minifiers and maybe that is the appeal of preprocessors/CSS libraries. I have also leaned towards using CSS for animations because I heard JS forces the browser to do more work, but never really animated anything that complicated anyway.

Collapse
 
equinusocio profile image
Mattia Astorino • Edited

I donโ€™t use grids from 2015, and bem from 2016. Old good plain css (with some help by postcss) and components based architectures with style-in-component (webcomponents, vue or react doesnโ€™t make difference). The โ€œframework phaseโ€ is something that iโ€™ve already saw.

Collapse
 
jenc profile image
Jen Chan

Sounds like you feel over grids and frameworks.
What do you enjoy about PostCSS (don't know very much about it) as opposed to the other methodologies mentioned? What kind of projects do you feel they are working well for?

Collapse
 
equinusocio profile image
Mattia Astorino

I just stopped using css frameworks and methodologies since I started workings with components. I now enjoy the benefit of simple architectures and code maintainability dropping complex systems (and now i can see also useless).

Postcss alone is just a a fast AST parser, the advantages come from the plugins you use. I always start with what i need (3 plugins) and i can make everything. No needs of node-sass, huge dependencies and unused functionalities.

About methodologies, i used BEM for years but with components i donโ€™t need it anymore (itโ€™s is still useful in some contexts).

I think people should just try to drop these 2012 approaches and start trying something that solve today problems.

Thread Thread
 
jenc profile image
Jen Chan

Could you explain what you mean by "components" outside of what i understand as components in frameworks? I've also read the no-framework thinkpieces out there and while I agree for 90% of hobby horse dev projects frameworks are wayyy too bloated and overkill, I'm at a stage where breadth is helpful for developing experience and a profesh opinion. Also as someone semi proficient in everything libraries help solve a lot of problems beginners can't vanilla js their way out of. Not looking to reinvent the wheel here.

Thread Thread
 
worc profile image
worc

i think mattia is talking about components as in javascript classes or functions that render a single visual component, like you find in react, angular or vue. there are approaches that limit styling and stylesheets to the component level and [nearly] completely throw out the notion of a master stylesheet.

so if you find yourself in the future redesigning the login form, you only have to redesign the login form and not the whole login screen or page or other higher level container. it's essentially BEM, but enforced and maintained by the computer and not a person. it reduces a ton mental overhead and eliminates a whole class of typo/misuse bugs in CSS.

Thread Thread
 
equinusocio profile image
Mattia Astorino • Edited

Exactly. But non only with vue/react/svelte etc.. i trust it as mindset. An approach that you can apply even with plain html/css/js and drop the monolithic frameworks approaches that are born many years ago to fix different problems.

Thread Thread
 
jenc profile image
Jen Chan

Thank you @worc for explaining. Your description makes a lot of sense. I like the idea of writing super lean plain html/css/ vanilla js... but I would need to master JS first. Then would come the question of should I CSS functions or still use SASS? I don't want to be obsessed with rigour but I'm trying to understand what's a professional standard. I'm both studying to "pass the test", but also want to self-improve from what was a previously anti-technical, anti-framework, anti-rigour kind of artistic point of view.

Thread Thread
 
jenc profile image
Jen Chan

correction: Makes a lot of sense for reusable components/features*, and large scale applications, which I should be gearing up to get used to

Thread Thread
 
equinusocio profile image
Mattia Astorino • Edited

Yes. But this approach and mindset can be applied even on small website. Every html elememt and composite block is a "reusable component" by default.

Thread Thread
 
worc profile image
worc

styled-components is a good working example in the react ecosystem. @jen chan, in general, you don't need to use sass if you're building CSS blocks in javascript. javascript gives you access to variables and functions and extensibility natively. it's probably not the best looking syntax around, but i've seen it help a ton in keeping CSS definitions from leaking across components and keeping the scope of a styling problem/solution very narrow.

Collapse
 
turnerj profile image
James Turner

For your specific questions, see below. I'll post another comment for your other points. :)

  1. Sometimes I get mobile designs, sometimes I just have to improvise. Normally though, that improvisation is pretty simple like just re-arranging items. I don't often have to fully switch out interfaces from desktop when going down to mobile. That said, I normally do have a designer I can talk to if I really am not sure about what to do.

  2. Honestly, I don't actually use a grid layout. I have looked at them before but I haven't found one that I'd want to stick with.

  3. I normally have quite a lot of media queries, it probably plays a bit into #2 about why. I write a new media query every time something "breaks" in the layout like if it overflowed off the screen horizontally or wraps in an unusual way. I am aiming for as fluid of a responsive layout as I can. I aim to get breakpoints down as low as 320px.

  4. I use CSS to do all the actual heavy lifting of styling the animation. I will use JS to add/remove classes on a timed sequence if the animation is that complex. The browser can make better use of hardware rendering via CSS transforms etc.

  5. This is going to be an uncommon opinion but I'm not actually a fan of SASS/LESS etc. I do understand what it can provide like removing repetition from CSS and allowing for easier to manage complex styles (eg. variables). That said, I've never hit something with vanilla CSS that I consider a problem that needs a solution like SASS etc. As for BEM, I understand what it can help with but it is too verbose for my liking and I feel makes the styling actually more complicated. I guess these both can be summarized that SASS and BEM solve problems but they don't solve my problems.

Collapse
 
jenc profile image
Jen Chan

"SASS and BEM solve problems but they don't" โ€“ I feel this way too. Maybe my projects currently doesn't have such a variety of templates/views. I've never had to create something with logins, accounts, dashboards and so many bells and whistles yet. In which case, I really could see scoped or SASS working out. I like the nesting in SASS but it seems counterintuitive to BEM. These kinds of things are confusing and at the moment I guess whatever works doesn't hurt, but I could see it being a leg up in a job app.

Collapse
 
turnerj profile image
James Turner

I've worked on a few big applications in vanilla CSS and while I wouldn't be able to say how it would have turned out with SASS, I didn't really have a problem building it.

Obviously YMMV but I think the approach to take is having clean and concise CSS, broken apart in separate files where it makes sense. This can be achieved without needing something like SASS.

Collapse
 
jenc profile image
Jen Chan

I improvise a lot. But I'd like to develop a concise and confident way of going about things. The whole grid thing is relatively new to me as I only used flexbox only before. However recently tried grid with flexbox and some nested grids inside... took much longer but there is way more control.

Collapse
 
turnerj profile image
James Turner

I think a lot about CSS (and programming in general) is finding what works for you. Learning ideas and concepts from others is important but really you are the one that needs to write the code that you need to deal with later. :)

Thread Thread
 
jenc profile image
Jen Chan

Absolutely. I think after using this for a few years and not quite paying attention to BEM or a lot of CSS frameworks has produced a lot of fomo and confusion, esp trying to get to โ€œindustry standardโ€ and itโ€™s time to try a few things to see what sticks. My way has been super detailed base styles or a class per styled element, then media queries for different screen widths. I discover I could be writing a lot less.

I also like the idea of multiple sheets for different components.

Collapse
 
keinchy profile image
Frederick Jaime

i come from the Marketing side ( Ad agencies ), my experience may differ from yours if you're working directly with clients.

  1. You should always request a Desktop and Mobile layout at a minimum, if there is no way around it, do your best to adjust and make sure people are aware you're a dev and not designer, so expectations are set. Hopefully by then, they will provide you with the additional layout(s). I don't want to go down the rabbit hole how to design for devs because as a dev, you shouldn't be designing.

  2. I tend to lean into how frameworks create their grids, i normally create a sass mixin to output my columns, 12-grid fluid columns. I would suggest to look at Foundation or maybe Bootstrap. If this is a large project maybe import a framework, if this is a small project i would highly suggest to keep a list of handy mixins you can use in various project.

  3. Everyone should develop smallest-screen-first ( mobile-first ), and should start with two breakpoints, 768px and 1024px. Any additional breakpoints will be dictated by the design.

  4. With animations i would suggest to use GSAP, this animation platform tries to leverage css first but defaults to js. Let's be clear, when you refer to animations i am thinking of non-linear animations, something more then just a fade. Simple rollovers, effects should be in css but the fancy stuff should be with something similar to GSAP. You don't want to add unnecessary weight to your page.

  5. I always use Sass, I like using a process to build my Sass. Most of the current frameworks allow you to add linters, in my current project we are using Gulp, created task to clean, compile, and minified my code.

Not every project is the same, so a one solution approach will not work. Before any project you should start by asking yourself, What tools do i need?, you can use Angular, React, Vue, or even Static Generators like NunJucks. Always have a plan before you build.

Collapse
 
turnerj profile image
James Turner

I've cherry picked a few of your specific points that I can provide opinion on.

apply style using classes with semantic names instead of IDs or elements (i.e. .site_header instead of #header ul)

Yep, a good rule to live by.

include cross-browser prefixes for any animations or exceptions (i.e. for drop-capitals in Safari or webkit- for Safari and moz- for Firefox and ms- for IE. Using an autoprefixer makes that easier.

I've kinda stopped using cross-browser prefixes. The main things I use like transitions, transforms and animations have been long supported. The browsers that don't support them aren't ones I test. That said, it really depends on your target compatibility.

convert any sizes to em and rem instead of px

That is a good rule but sadly not a rule I have been following very much. :(

Write as little to accomplish the most as possible, detailing margin and padding on every little thing makes your styles confusing for someone else to read.

I think the general statement here is good for programming in general. Overly verbose code is always going to have a higher maintenance burden.

To make everything show as the size it should in the design, use *{box-sizing: border-box;}

I agree with wanting box-sizing to be border-box but the way I implement it is a little different.

*, *:before, *:after {
    box-sizing: inherit;
}
html {
    box-sizing: border-box;
}

While not super common, if you did change the box-sizing for a particular element, there is a good chance you want the child elements to behave the same way.

Stay away from inline styling at all costs.

Yep! Even for cases where you might have something like style="display: none;", I'd switch that for a class like .hidden or something.

float as a positioning selector is a thing of the past.

Yep though I'm also bad with this though I am getting better! Flexbox is my go-to instead.

!important does not always fix a problem

Yeah... I've had long discussions with one of my colleagues about !important and whether we should use it at all. Personally, I've tried to avoid !important in any styles at all with the exception of print styles. The only reason I have it there is because of a no-print class I have. Because I target that specific class, other selectors have more specificity so I need to force override them.

Collapse
 
jenc profile image
Jen Chan

Thanks for your feedback. By the way, what is this no-print class you mentioned?

Collapse
 
turnerj profile image
James Turner • Edited

So a no-print class is designed for controlling whether an element will be printed if someone prints the page. Quite simply, the CSS rule looks like:

.no-print {
    display: none !important;
}

That would be in a print.css file or media query with the media being print.

For me, that is probably one of the only cases where I use !important because that declaration is otherwise not always going to apply.

When you go !important, you need to be absolutely sure that it is the final and ultimate transformation you want to do for matching elements. In print, I need the elements to be gone.

Similarly, you can have only-print classes which do the reverse though it gets harder because for some you might want display: block !important; and others display: flex !important;.

All of this being said, a class like this really is saying what it does rather than what it is, which you may look at as breaking semantic rules for class names.

Collapse
 
ryan profile image
Ryan • Edited
  1. Way too project-dependent to answer. Since space is usually the concern, figure out which elements are essential and which can be relegated to a menu or removed entirely.

  2. I don't use fixed-size grids, it's too restrictive. I do like to have a centered content area of a fixed maximum width, since it's hard to read extremely wide windows.

  3. As few as possible, obviously depends on design and that may not always be possible but I feel it's best to have a single breakpoint around 480px. Why 480? Because your mobile layout will span 300-480 wide and your desktop breakpoint will span 480-800 or 900. You can have a layout that looks good at 480 that's not cramped at 300, you can have a layout that looks good at 500 that doesn't look empty at 800.

    I think it's fine to show/hide a couple of elements with more than one breakpoint too but you don't want to be maintaining 3 or 4 complete separate layouts.

  4. CSS where possible. Not sure where I would have an animation that is only possible with JS. Not counting using JS to change an element's style in order to cause a CSS animation.

  5. SCSS all the time! Here's why a preprocessor like SCSS is indispensable for even small projects:

    • You can manage your theme colors with variables in one spot. If you decide to tweak some colors, makes updating the project super easy. Also makes sure you are staying on-brand and not using a bunch of slightly different shades.
    • You can use mixins for compatibility. Instead of having to write multiple lines of CSS for all vendor prefixes each time you use a single rule, you can write out the prefixes once and be cross-compatible with one line (this is especially handy with css grid)
@mixin select-none {
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

span.cant-select-this {
    @include select-none();
}

Also minification and comments! It's good practice to comment CSS, but I don't necessarily want my comments to be made public. So a preprocessor helps with that too.

Collapse
 
aspittel profile image
Ali Spittel • Edited

Hey! These are great thoughts. Totally agree โ€” would also check out AirBnBโ€™s CSS style guide โ€” itโ€™s great.

  1. Iโ€™ve never worked on a team with a full time designer! I would agree though, that hamburgers and full screen layouts are usuallly the way to go.

  2. Definitely depends on the design, but I use frโ€™s a lot. Super helpful for a lot of layouts.

  3. I normally make them once something looks weird. So once text is overlapping or something, Iโ€™ll add another mediaquery. I would also look up the sizes of popular devices and make sure your work looks great there.

  4. Normally CSS animations are more efficient than JS ones, but really complex ones can only be done in JS. Transforms specifically go to the GPU which makes them super smooth.

  5. Bem is still a thing a lot of people like and use! I would say SCSS has the market share for preprocessers. Would go in that direction. I use it if itโ€™s easy to set up for the project, if not, itโ€™s not enough of a game changer for me to get it working.

Collapse
 
jenc profile image
Jen Chan

I have heard a lot about the AirBnB style guide. And before today BEM seemed just like 1 of 10 million ways to do CSS when I heard about it 2 years ago (and strangely verbose to me), but on another look it seems like a really significant method of component-based styling and also a way to avoid overriding/conflicting styles. I have to go re-read the thing with fr's as far as I understand they do tracking/dividing. laughs nervously

Collapse
 
phoinixi profile image
Francesco Esposito • Edited

Great article, thanks, very inspiring!

Those are my thoughts:

  • I would use bootstrap (or similar) only for prototypes or small projects without design specifications, in a big project it becomes a limit in few months (overrides and !important hell)

  • There are auto-prefixers out there, you donโ€™t want to write them manually

  • CSS transition or keyframes (with transform and other hardware acceleration properties) when possible

  • never, ever use IDs for CSS, are unique, in CSS we want to style reusable components, not unique elements :)

  • donโ€™t try to generalise or reuse everything, repetition in CSS is ok, create reusable components, also small ones that includes behavior and style, donโ€™t create reusable classes, there will always be a special case (many actually:) )

  • BEM is a thing, and itโ€™s a good thing to avoid stuff like card sm-margin red in favour of card cardโ€”small cardโ€”red but also CSS modules and CSS-in-JS are a thing :)

Collapse
 
jenc profile image
Jen Chan

Truth be told I recently used initializr when I had to do something super quick for a friend and it was PERFECT. I am not sure why people knock on frameworks.

Oh yes, good point about the auto-prefixers. Going to update that part in the bullet points.

Until today I always thought the best thing about CSS was showing how crazy specific by naming as many direct parent and children and classes as possible. Turns out this is not true! (womp womp)

I only became aware of scoped styles through Vue, though I have yet to build something to such a scale with so many views and templates where it becomes vastly important and convenient. One day.

Just to confirm about ids--so if I wanted to style a "unique" element, I create a different class?

And just to clarify, when you said "create reusable components" instead of classes, you meant that I should decide on what is Block, Element and Modifier (or the look of something in different states) instead of just arbitrarily creating classes for different visual elements right?

Collapse
 
phoinixi profile image
Francesco Esposito

About ids yes, I would just create a different class.

Create reusable components instead of reusable classes I mean that itโ€™s more clean and elegant, in my opinion, to reuse a component or custom element that encapsulates its own style instead of using the same class on 2 different elements, that I guess itโ€™s the same of scoped CSS in Vuejs

Collapse
 
akashkava profile image
Akash Kava • Edited

I have created Web Atoms Core, which has CSS styling as JavaScript code.

class ListStyle extends AtomStyle {

    public get root(): IStyleDeclaration {
        return {
            color: Colors.gray,
            backgroundColor: Colors.white,
            subclasses: {
                " > li": {
                    color: Colors.blue,
                    subclasses: {
                        " > button": {
                            color: Colors.green
                        }
                    }
                },
            }
        };
    }
}

HTML

<script>
    import ListStyle from "~src/web/styles/ListStyle";
</script>
<ul
    default-style="{ ListStyle }"
    style-class="{ this.controlStyle.root }">
    <li>First Item</li>
    <li>Second Item</li>
    <li>
        Third Item
        <button>Delete</button>
    </li>
</ul>

In order to avoid naming conflicts in CSS, ListStyle class is instantiated once and root property style is given a css name that is unique. When we assign default-style it creates an instance of StyleSheet if it does not exist and attaches style to current component.

Best part is, IStyleDeclaration object is JavaScript object and it can contain any valid javascript and it refreshes when device size changes. You don't need media queries.

class ListStyle extends AtomStyle {

    public screen = (this.styleSheet as AtomTheme).app.screen;

    public get root(): IStyleDeclaration {
        return {
            width: this.screen.screenType === "mobile" ? "250px" : "900px"
        };
    }
}

Styles can be inherited and overridden easily as JavaScript objects. And you don't need to worry about how and where to put in assets. Also style will only be created for the components that are hosted in the page, making browser free of all unused CSS.

Collapse
 
fjo_costa profile image
Fernando Costa

I read about 3%... 2.5% to be honest and kicked this to the read list. But I'll read it when I get 100% sure I can dedicate all of my attention.

As a (mainly) backend developer, I want to give a shout out to all frontend devs. The true magic happens here! Thank you!

Collapse
 
jenc profile image
Jen Chan

I know right?! I learn something new talking to devs everyday.