Skip to content

Instantly share code, notes, and snippets.

@OliverJAsh
Created June 21, 2014 13:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OliverJAsh/aeb5bf62e062ecc294d7 to your computer and use it in GitHub Desktop.
Save OliverJAsh/aeb5bf62e062ecc294d7 to your computer and use it in GitHub Desktop.
CSS tooling: implicit style dependencies

I see this quite often in CSS: something doesn't look right, so we apply some new styles on our class to make it look right.

Instead we need to review what the current styles are, and where they come from – another class (composition) or inheritance. If you’re changing the font-family style, for example, you should have a look to see what might be currently setting that property in the styles pane, and identify how it’s cascading to this element. It may be that you can remove it from a parent element, or you might need to override it with a class. Without reviewing the code is this way, you CSS codebase can easily become bloated with style overrides.

Chrome DevTools makes reviewing the cascade very easy with its styles pane. However, when you look at some CSS code in your IDE, it’s not at all explicit what styles will be inherited or applied through composition. This means we have to have strong discipline in documenting our CSS – where you’re unsetting or resetting a style that is inherited, you might leave a comment such as “Unset from .foo”. There are also other implicit dependencies in CSS code, for example position: absolute will be relative to a parent that has position: relative. Again, this is not immediately clear from scanning the code, so it has to be documented.

What would be really great is if your IDE could show you what styles are inherited or composed, and then which styles you are unsetting or resetting. As of now, my workflow is to jump into Chrome DevTools and review this manually, but it’s tedious and most developers won’t bother, resorting to adding new styles instead of modifying inherited ones (for example).

If you document the DOM hierarchy of how you plan to use your classes (for example, in a comment at the top of the file), theoretically a tool would be able to render this information inline in your IDE. I have attached two examples of implicit style dependencies – inheritance and positioning. In these examples I have left comments for where the tool might display this information, just as an example.

Do you have any suggestions for how I might build this? Essentially I have some HTML and CSS as input, and as output I need the computed styles(?) for each element. I’m not sure if there are any tools I can use to produce this information. Chrome DevTools obviously parses this information somehow, so I should look into that.

/*
<div class="foo">
<div class="bar"></div>
</div>
*/
.foo {
font-size: 13px;
}
.bar {
/* TOOL:
* inherited:
* font-size: 13px; (`.foo`)
*/
color: blue;
}
<link rel="stylesheet" href="inheritance.css">
<div class="foo">
<div class="bar"></div>
</div>
/*
<div class="foo">
<div class="bar"></div>
</div>
*/
.foo {
position: relative;
}
.bar {
/* TOOL:
* positioned relative to `.foo`
*/
position: absolute;
}
<link rel="stylesheet" href="positioning.css">
<div class="foo">
<div class="bar"></div>
</div>
@kirjs
Copy link

kirjs commented Jun 21, 2014

But how to deal with something like this:

<link class="bar" rel="stylesheet" href="positioning.css">
<div class="foo"  class="bar">
    <div class="bar"></div>
</div>

@OliverJAsh
Copy link
Author

Yes, the tool could show you styles applied from other classes.

@kaelig
Copy link

kaelig commented Jun 24, 2014

Interesting idea but good luck documenting code like this and keeping it up to date.

I guess low specificity selectors can help you avoid having to get there up to a certain point.

@vladmalik
Copy link

Agreed that it certainly would be useful if CSS authoring tools were DOM-aware. They should already know which HTML file or files are in the project and whether they use that CSS. I think you'd need to see relationships from both sides: before you modify a style, see what style definitions this style cascades to as well as what styles cascade to it from other style definitions.

I think in principle it would not be proper to embed document structure in CSS, since that's the job of HTML. Perhaps the CSS authoring tool could be smart enough about reading the DOM and automatically structuring CSS accordingly. The challenge with that is CSS is more abstract than HTML. The tool would have to deal with the one-to-many relationship between a particular style definition and multiple DOM elements it describes. Also, as much as CSS is HTML-dependent, CSS also needs to be HTML agnostic. If you restructure your HMTL, you might not necessarily want to restructure your CSS e.g., if you move an element to the sidebar, you want the sidebar style to cascade down to that element.

That said, I'm pretty comfortable with the tools I have. I don't mind manually checking dependencies in Firebug. And I use a few simple annotations to keep track of relationships.

(1) I indent my CSS to represent parent-child relationships. This is most helpful:

  .foo {
        position: relative;
        font: 100%;
  }

        .bar {
              position: absolute;
              font: 80%;
        }

(2) When the root has no special styles, I might leave a comment or empty definition as parent node. And when a style is already defined or grouped elsewhere for efficiency, I might leave a comment:

  .foo {}

        .bar, .meh {
              font: 80%;
        }

  /* .meh is under .foo */

(3) For extra clarify (e.g., in a long list of styles), I might use a compound selector (also to add specificity):

  .foo {}

        .foo .bar {}

or

  /*.foo*/ .bar {}

(4) I've also occasionally grouped styles by theme, so it's easier to discern relationships between specific style types, but I've since found it's better to keep definitions together:

  /* Text */
  .foo {
        font-size: 100%;
  }

        .bar{
                font-size: 80%;
        }

  /* Position */
  .foo {
        position: absolute;
  }
        .bar{
              position: relative;
        }

(5) I space separate styles but sometimes omit space to show that two styles are functioning as a unit:

  form {
        margin: -20px;
  }
  form .wrapper {
        padding: 20px;
  }

        input {
        }

@simonsmith
Copy link

Is there a need for a tool such as this? Since I started using SUIT on large projects I've found it very easy to make sense of this kind of thing. Everything is very shallow in terms of inheritance, with utility classes abstracting away common styles.

However, I wonder if something like rework could help?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment