DEV Community

bob.ts
bob.ts

Posted on • Edited on

CSS: Everything is Broken. What can I do to Fix It?

If you want to master CSS, don’t worry about the details, instead, learn the 5-W’s about what is broken:

CSS Is Awesome Mug

  1. Who authored the change ... legacy code might take a bit more preparation.
  2. What changed recently and how does it reflect in the code?
  3. When did the specification become reality ... how stable are the styles being implemented?
  4. Where are the impacted HTML and CSS?
  5. Why did the change occur? ... some other portion of code; specification implementation; HTML?

“The amazing ideas of today become the problems of tomorrow.” - Unknown

Six ways to become a happier CSS Developer

Or, six important fundamentals when approaching CSS development ...

  1. Don’t wait for IE to die.

    IE6 ran from 27 Aug 2001 to 12 Jan 2016 (more than 14 years after its original release).

  2. Concentrate on the now; learn by making mistakes.

    Use sites like http://www.caniuse.com and other current resources to see how the standards are applied by browser.

  3. Limit the development environment.

    Use sites like http://www.jsfiddle.net to pull out the code that is working incorrectly and work in an isolated environment.

  4. Make it harder to write bad code.

    Have strict rulesets and code reviews, while remembering that “editor inheritance” (copy/paste) duplication leads to errors.

  5. Get to know the tooling.

    Browser development tools; what can be done to manipulate the environment to resolve the issue.

  6. Muffle the noise.

    Use tooling efficiently; be aware of "bleeding edge" code.

CSS is the pinnacle of “black-box-theory”; we are defining what parameters are going in and hoping that properly style comes out from the various boxes (Chrome, IE, FF, and more).

Remember: the “best” isn’t necessarily the best ...
In order to deal with the inherent complexity of CSS, all sorts of different best practices have been established. The problem is that there isn’t any strong consensus on which best practices are in fact the best, and many of them seem to completely contradict each other.

The CSS Mindset

Some people “get it” ... others don’t.

What sets CSS apart

It’s Resilient ...
HTML and CSS were specifically designed to be fault-tolerant. If there’s a problem, the browser won’t throw an error; instead, it will ignore that part of the code and keep on going (delete some JavaSCript and see what happens).

  1. Jen Simmons (Mozilla) half-jokingly calls this “Quantum CSS”. You can take a feature of CSS and “use it and not use it at the same time. It works and it doesn’t work at the same time.”

It’s Declarative ...
Tell the browser what you want to have happen, and it works out the how. [Define some constraints. Let the language work out the details.]

  1. If you get it wrong, you’ll be fighting against the grain of the language and you will be frustrated at every turn.
  2. Writing CSS is effectively setting up a system of constraints. Don’t tell the browser where to put every single element on the page; you tell it how much space to put between them and let it sort out where they belong.
  3. There are too many variables to consider. The point of CSS is to make it so you don’t have to worry about them all.

It’s Contextual ...
CSS is not 100% modular, nor should it be.

  1. The app should have some global styles. You will almost always want to set a default typeface and font size at the page level. These values will then be inherited by all descendant elements that don’t explicitly override them. You will also want certain aspects of your design to apply repeatedly throughout the page, such as theme colors, border radii, box shadows, and common margin sizes. More localized styles on the page will then assume these global styles are in place.
  2. CSS and your styling decisions are informed by the surrounding context of the page. Changing one part of a design can have ramifications on how other items on the screen are perceived.

Hacking User Perception

The Houston Airport had an issue ...

“People perceive time differently depending on how anxious they feel and if they are on the move or at home. In research we ran at Google, we found that 75% of users felt a site was fast when they were at home, but this dropped to 52% when they were out and about. Users who are younger feel sites load slower than older groups as well. On the whole, we perceive a delay on loading which is 80 milliseconds more than the reality. So if you are left waiting around, things will feel even longer.”

Loading
Load time feels longer because the user is left waiting for content.

Also, it shows the app in a “thinking” state rather than “working”.

Filling the screen
Skeleton content: though this is better, using it on its own in place of a preloader isn’t great. Because it still gives the feeling of an error and doesn’t show any context for the type of content that is coming.

Staggering
Using a mixture of skeleton screens, contextual metadata and pixelated images that partially load, you can occupy a lot of the user’s time and make the whole experience feel faster. The idea is to give context to the user of what’s coming and load in things as quickly as you can.

Navigation
Studies by Facebook, RedBooth, Spotify and Google Plus show that hiding menu items means that users didn’t tap or click them. Facebook also found that the switch to bottom navigation made the apps perception of speed seem faster. Because out of sight is out of mind and seeing an item quickly makes the experience feel faster. So making your primary call to action visible at all times helps. Bottom navigation also is more ergonomic on mobile devices, as the user can reach the buttons using one hand, again helps keep the experience quick and natural.

Feedback and reassurance
Letting the user know what is going to happen is critical, but informing them of the action they have triggered also helps make your apps and sites feel fast. Using motion, hover states and ripples you reassure the user that the action they took is in progress.

Web Standards: Friend or Foe?

W3C(World Wide Web Consortium) does not “make” standards.

Based on input from the community, the standards committees simply approve or disapprove the proposed wording. This often leads to confusion based on interpretation when applying these in browsers.

CSS3, CSS 4, and other mythical creatures

  • CSS 1 (1996, 68 pages)
  • CSS 2 (1998, 480 pages)
  • ... going forward, the committee broke CSS into modules with independent versioning; there is no “CSS 3” or beyond.

The troubled history of CSS comes mostly from the fact that it’s so simple for development newbies to learn through brute force, and that it’s too easy to structure poorly in a project.

Vendor Prefixes: Friend or Foe?

Standards groups need input from developers to create specifications.
Developers are not interested in creating things that can’t be used in production.

Experimental technologies get widely used in production, WG is forced to include these in specifications.

  • Vendor Prefixes (-moz-, -ms-, -o-, -webkit-) ... (epic failure)
  • Started getting used everywhere.
  • All possible variations started getting added to codebases.
  • Tooling to maintain (autoprefixers)

Experimental features now starting to require config flags to be turned on.

CSS Methodologies

All CSS development builds on methodologies. CSS is difficult to maintain and poorly written CSS will quickly turn into a nightmare.

  • Preprocessors
  • Postprocessors
  • OOCSS (Object Oriented CSS)

    Good guidelines, but limited details on approach.

    • Separate Structure and Skin (layout and colors, fonts, etc.)
    • Separate Container and Content
  • SMACSS (Scalable and Modular Architecture for CSS)

    A lot more specifics in its approach compared to OOCSS, but it still requires some careful thought in deciding what CSS rules should go into which category.

    • Write CSS in categories: base rules, layout rules, modules, state rules, and theme rules.
    • Naming Conventions (prefixing and state-rules, i.e. is-collapsed)
  • BEM (Block, Element, Modifier)

    Simple to understand, with a specific naming convention that allows newcomers to apply it without having to make complex decisions. The downside for some is that the class names can be quite verbose, and don’t follow traditional rules for writing semantic class names.

    • Independent blocks
  • Atomic CSS (or Functional CSS)

    • Creating small, single-purpose classes with names based on visual function. Search
  • CSS in JS

    • Defining CSS styles not in a separate stylesheet, but directly in each component itself (see React).

... keep in mind that there is no one right approach.

CSS Coding Tips

General ...

  1. Tutorials provide knowledge ... not experience.
  2. Arrange and nest HTML correctly.
  3. Examine layouts if sites you enjoy.
  4. Don’t be afraid to try something new.
  5. Learn selectors (and specificity); effective use of classes and ids (least specific selector).
  6. Use external style sheets; avoid internal and inline (exceptions?).

KISS and Cascade ... remember the “butterfly effect”

  • Minimize code duplication (the amount of edits to make a change).
  • Maintainability versus brevity; maintainable code might actually take more lines of code.
  • “currentColor” (resolves to the color property).
  • Inheritance

    Often forgotten, the “inherit” keyword can use used by any CSS property and it always corresponds to the parent’s computed value.
    input, select, button { font: inherit; }

Trust your eyes, not numbers ...

  • Optical illusions are very common in any form of visual design. A box with equal padding will look like there is less on top and bottom because of the rectangular nature of the letter-forms.

Responsive Web Design ...
RWD often becomes testing at various resolutions, then additional CSS to fix (adding overhead). Media query thresholds should be dictated by the design, not specific devices. If there are tons of media queries to make the design adapt to smaller (or larger) screens, take a step back and reexamine the code structure, because in all likelihood, responsiveness is not the issue.

  • There is a lot unsaid about what good RWD entails.
  • Media queries used right can be indispensable.
  • Strive for liquid layouts and relative sizing between media query breakpoints.

Use shorthands wisely ...

  • It is good defensive coding and future-proofing to use shorthands, unless there is some intent to use cascaded properties for everything else (minimize code duplication)

Use of a preprocessor ...

  • The use of preprocessors needs to be a conscious decision, not a mindless default when starting a new project.
  • LESS, Sass, or Stylus (for a start) offer several conveniences for authoring CSS: variables, mixins, functions, rule nesting, color manipulation, and more.
  • Used properly, they can help keep the code more flexible in a large project.

Pure CSS (rather than Frameworks)

Many preprocessor-inspired features are making their way into pure CSS:

  • variable-like: CSS Custom Properties for Cascading Variables
  • calc(): CSS Values & Units Level 3 ... (well supported)
  • color(): Css Color Level 4 ... (means to manipulate colors)
  • Several discussions (CSS WG) about nesting.

The power of native features like these is that they are much more powerful than those provided by preprocessors, as they are dynamic.

CSS Frameworks (over Pure CSS)

Writing great CSS code can be painful (the part we never enjoy).

“When a tool is good, it’s easy to fall into the trap viewing the tool as the ultimate answer. Even worse is when you believe you can’t do good work without it.” - Unknown

Negatives

  • Commonplace designs
  • Difficult to customize
  • Capability and Understanding (knowledge gap)
  • Autoprefixers

  • Losing track of file size and complexity.

  • Debugging becomes harder.

  • Development latency.

  • Law of Leaky Abstractions: have their own bugs.

Positives

  • Variables (reusability)
  • Nesting (readability)
  • Partials and Imports (maintainable and readable)
  • Mixins and other directives

“I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail. ” - Abraham Maslow

Handling Legacy CSS

“One bad programmer can easily create two new jobs a year.” - Unknown

The kind of codebase ...

  • That no one person truly understands any more.
  • That has had a dozen different contributors over just as many years.
  • That has never had a full-scale refactor or overhaul.
  • That has grown organically over time and changed with new techniques, styles, and trends.

See what breaks

Identify a part of the codebase and play around with it: bend it, break it, change it, see what happens to it. Make a note of anything odd or unusual; if that thing happens again when you play around elsewhere in the codebase, there could be some significance to it.

Identify entry points

Build up an idea of which files import which other files; who passes what onto who; what inherits from where; what does the dependency tree look like? Build a mental model of the topology of the codebase.

Get an idea of what has changed

See what files were changed last: any files that haven’t been altered in over a year are probably less important to current work.

Identify what is used

Chrome’s Coverage tool is a great way to see at a very high-level glance what CSS is being used by the current page. This very non-scientific method of checking code usage should give an approximate idea of what might be dead code, or what could simply be ignored.

Learn the codebase organically

Don’t go looking for trouble. If you never need to touch the help and support section, there’s no point going out of your way to research it. Try to remain focused and learn about the parts of the codebase that are most important and timely.

Setup regression tests

Ideally, we’d have a regression testing suite in-place permanently.

Parker is a static analysis tool. Use it to grab useful information about the overall makeup and health of the CSS: how many IDs, mean specificity, how many !importants, etc.

“Don’t cling to a mistake just because you spent a lot of time making it.” - Unknown

Conclusion

CSS Bomb Humor

To answer the question of how to handle CSS that does something unusual, learn the 5-W’s about what is broken, we can summarize:

  1. Who authored the change ... legacy code might take a bit more preparation.
  2. What changed recently and how does it reflect in the code?
  3. When did the specification become reality ... how stable are the styles being implemented?
  4. Where are the impacted HTML and CSS?
  5. Why did the change occur? ... some other portion of code; specification implementation; HTML?

Top comments (2)

Collapse
 
koresar profile image
Vasyl Boroviak

Do you know if "atomic css" is the same thing as "utility-first css"?

Collapse
 
rfornal profile image
bob.ts

In my mind they are essentially the same, having used both patterns in different projects.

While there are some minor variances in naming conventions, the core concepts are strikingly similar and most developers use a mesh of different naming conventions anyway, which leaves the core concepts of using small "utility" or "atomic" structures within the CSS.