Refactoring my CSS

I enjoy working with CSS, but when I stand back and look at what I have done over the last few years, it is an absolute mess.

How so?

Well, I have 4 .css files and in total they are over 5,000 lines of code.

How did things get to be so big?

One reason is that I’m a perfectionist that wants things to look exactly the way that I want, so that navigating and reading things on my website is easy and pain-free!

The other reason is that I don’t believe in a “one-size” fits all approach, and that leads me to customizing similar things, and that makes my CSS code-base “mushroom”.

A good example is what I am working on now…

Thanks to @coothead, I am starting to learn FlexBox and dabbling with responsive design. And to apply what he has taught me, I am trying to build a Product “component” to use in 4 different places on my website. (This Product consists of sub-components of: “Product Image” and “Product Details”, with the 2nd one having a “Product Title”, “Product Author”, “Published Date”, “Description”, and so on…)

The problem is that something as simple as a “Product Title” needs to be styled differently for each page. Why? Because the “Product Catalog” displays several Products and so there is limited space for a given Product and thus “Product Title”. By contrast, if the uesr chooses the “Product Details” page, then that is an entire page for a single Product, and so the “Product Title” should be much larger.

Everyone here at SitePoint seems to make things a class like .productTitle{ ] but that seems pointless to me if I only ever have a single productTitle style on say my “Shopping Cart” page.

(I can see using classes for things like a style like: .important{font-color: red;} but classes don’t seem to apply much to what I am doing.

Not wanting to have this…

h2#productTitle1{fontisize: 2em;}
h2#productTitle2{fontisize: 1.4em;}
h2#productTitle3{fontisize: 0.9em;}
h2#productTitle4{fontisize: 0.8em;}

the only thing I could think to do is this…

#wrapper_Store h2#productTitle2{fontisize: 1.4em;}
#wrapper_Details h2#productTitle1{fontisize: 2em;}
#wrapper_Cart h2#productTitle3{fontisize: 0.9em;}
#wrapper_Checkout h2#productTitle4{fontisize: 0.8em;}


***********************

On a side note, I have often wondered if taking a mix-n-match approach like the following might help…

<style>
  .red{color: #F00;}
  .green{color: #0F0;}
  .blue{color: #00F;}
  .important{font-weight: bold;}
  and so on...
</style>

Then I could “build” something using “component” styles…

<p>This is <span class="red">RED</span> and this is <span class="green">GREEN and this is <span class="blue">BLUE</span> and this is <span class="important">BOLD</span></p>

<p class="highlight">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>

<p class="highlight error">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>

<p class="highlight error important">Lorem ipsum dolor sit amet, consectetur.</p>

Not sure if that approach is legitimate, or how it might apply to my earlier example.




At any rate, I would appreciate some advice on how to make my CSS more efficient moving forward. Clearly what I have now for v1.0 is going to have to stay, but for v2.0 maybe I can make things cleaner?

Btw, if @Ray.H or the Mods wouldn’t mind pasting what was said in my “ID vs Class” thread here, I would love to do a deeper dive on what @Ray.H was starting to say!!

Thanks!

I would suggest first writing out your html without even thinking about styling it. Throw away any idea of the last 30 or so lines of your post (that starts with " .red {color: #F00;}), as that’s pretty horrible. The html should be about the content of the page, not the style.

Once you have the html written up, then look at how you want to style it. Is there a header? Then style that. I don’t care if that header is the name of the product, I am just styling the header. Is there a table with th entries? Style “table th” then. You should not end up with classes or id’s that look like database column names, you should be styling sections of the structured web page, either by directly styling the html tag, or by creating an id (you might think of the id as a noun, a thing on the page) or a class (you might thing of this as an adjective, a type of thing on the page). My use of noun and adjective is not at all definitive, just a convenient analogy.

So as far as your product title, I would just look at one page at a time. Is the product title on this page always the first line in the header of that page? Then great, style that first line however you like. If on some other page, the product title is now showing up in a shopping cart listing over on the side of the page, they that’s fine, style that li item however that makes sense on that shopping cart.

Hope that helps…

3 Likes

I already do that, and think I have a pretty solid grasp of marking up a website thinking “semantically” about the content.

Ouch!

While I agree to a point, the problem with that approach is it assumes a simple, content-heavy website that looks like a blog from the 1990s.

When your website looks more like Amazon.com - minus all of the annoying advertising and pop-ups, then it gets much trickier!!

Sorry, that doesn’t help, because if I took that approach I would end up exactly where I am now - with over 5,000 lines of CSS!

At the top of the post you say don’t make things look like a database, and then in the second half you say style things as they need to be styled.

What I need is a “system” to minimize the number of IDs and Classes that I have and make them as flexible and scalable as possible.

It would seem that applying data modeling - ironically just like a database - or an object-oriented approach would be more efficient, because then you could re-use “objects”.

By the way… Why is my .red{color: #F00;} such a “horrible” idea?

When I was really into learning web design a decade ago, it sure seems to me that there was a school of thought/approach where you did just that, i.e. “component architecture” where instead of styling everything on your website as a one-off “thing” - like you are advising by the way - the idea was to build a library of smaller “things” that you could plug together to mimic larger real world “things”.

Just like a hardware store or a lumber yard where you buy the raw materials, and by combining 2X4’s and 16d nails you end up building an entire house! (@Ray.H, I see you are a woodworker, so you should be able to appreciate what i am saying… You presumably buy raw lumber and cut it certain ways and nail or glue or groove it together to create unique custom cabinets, right?)

Btw, if what i am describing exists, what is it called?

@Ray.H,

I do have sample code, but would actually rather keep things agnostic for now because really what I am looking for is help to start thinking differently in how I create styles regardless of the particulars.

And as a re-cap, what confuses me is what you should do when you have similar things that are style different - like how I might have a “Product Title” that is the same content and same HTML but which needs different styling whether it is on a dedicated product details page or in a listing of several books in a product catalog or in a smaller shopping cart.

This problem I am describing must be pretty common on larger, more complex sites. hasn’t someone already solved for it? I was sure there was an approach and it had a name but I have been away from all of this for so long I don’t recall.

Because it is contrary to the semantic markup you are trying to do. .red is not semantic. If you’d called it .critically-important {color: #F00}, then it would be semantic.

The only thing I can think of for you in terms of your component architecture is possibly the abstraction that using SCSS or LESS provides, where rather than lay out your CSS in a cascading way yourself, you can group those things that cascade into one SCSS “group” (I don’t know what they call it, I don’t use it) and then see them as one thing. Whether this will reduce your line count or not, I don’t know, but it might add the structure you’re looking for.

That does not make any sense to me. :unhappy:

If the font size is readable in one condition why does it need
to be changed for another? :rolleyes:

Simple thinking, simple coding. :winky:

I would suggest that something like this…

body {
    font: normal 1em / 1.5em BlinkMacSystemFont, -apple-system, 'Segoe UI', roboto, helvetica, arial, sans-serif;
 }
h1 {
    font-size: 1.5em;
 }
h2 {
    font-size: 1.25em;
 }

… would be adequate for all your pages. :biggrin:

coothead

1 Like

But the particulars can be the deciding factor for finding the best way to style it.
Here again, if you have semantic HTML you might find yourself being able to target certain tags without even needing an ID or Class name on it.

I don’t know what your HTML elements knowledge is but make sure you are aware of all the elements that are at your disposal. Review the list here at MDN…
HTML elements reference

Now let’s take this example you posted above…

.important{font-weight: bold;}

Stay away from naming anything as important. Why? Because that is a reserved CSS value that should rarely ever be needed. You have it shown as the property rather than the value but just get rid of that to avoid any confusion.

So you were calling a span tag with bold font important. Well we already have an HTML inline text tag for that. It would be the <em> tag for ‘emphasis’ or the <b> tag for ‘Bring Attention To’ according to HTML5. It was formerly just known as the ‘bold’ tag. No classes needed just target that element where it is in your HTML. If the parent has a class name on it and that tag needs to be styled accordingly then target it from the parent’s class name.

Now keep in mind you have a wide range of pseudo-classes at your disposal as well. Get familiar with using :nth-child() also.

Those are just some ways to style elements without having to place an ID or Class on everything. It takes time to learn but you will soon be able to recognize which direction gives you the path of least resistance.

If your CSS selector is a descendant chain of 3 or 4 IDs’ to style one piece of text then something is wrong.

Well let’s use that as a starting point for finding the most semantic way to write that HTML.

Please post the HTML you are currently using for this, then let’s see if we can streamline it.

So it sounds like all of them will at least have a “Product Image” and “Product Details”.

HTML5 gives you the starting point for that with the <figure> element with a <figcaption>

<figure>
    <img src="/media/examples/elephant-660-480.jpg"
         alt="Elephant at sunset">
    <figcaption>An elephant at sunset</figcaption>
</figure>

Be sure to read up on it at W3C, 4.4.12. The figure element

Your author and publish date may very well be a case for another <figcaption> and the <time> element.

Take note of the figure examples on MDN where an author is referenced after the <cite> tag in the figcaption of a poem.

<figcaption>
    <cite>Venus and Adonis</cite>,
    by William Shakespeare
</figcaption>

W3C also allows an author to be credited in the <cite> tag, but the WHATWG oppose that. So at this point it might be best to avoid it.

It’s worth noting that the W3C specification says that a reference to a creative work, as included within a <cite> element, may include the name of the work’s author. However, the WHATWG specification for <cite> says the opposite: that a person’s name must never be included, under any circumstances.

So let’s try to use as many pre built HTML elements as we can to build your Product “component” in a semantic way.

Then on to the CSS afterwards.

Sorry if this appeared to get off track to your thread title again, but that’s how it is. Your HTML needs to be correct before you proceed with CSS.

So once again, Please post the HTML you are currently using for this so we can see where your at.

2 Likes

Class do not have to be semantic. If its easier for you to use a utility type function, then go for it as class selectors don’t matter a hill of beans.

First, disclaimer I use Sass in all projects so sorry if I default to that syntax. In all projects I ususally have a separate typography styles. So it would like this:

.header {
 // DEFAULT STYLES FOR ALL HEADERS SUCH AS FONT FAMILY, LINE HEIGHT, ETC.

    &-h1 {
       // STYLES FOR H1 OR THINGS I MIGHT WANT TO LOOK LIKE H1
     }

    &-h2 {
        //  STYLES FOR H2 OR THINGS I MIGHT WANT TO LOOK LIKE H2
     }
}

Then to use, just add class where appropriate. Again, there is no such thing as semantic classes, so if the CODE needs to semantically be an h2, but looks like an h1 in design, then just add class=“header header-h1”

You may well choose to believe that, but it is
actually recommended that you make it so. :rofl:

" …authors are encouraged to use values that
describe the nature of the content, rather than
values that describe the desired presentation
of the content.
"

Further reading:-

  1. https://dev.w3.org/html5/spec-LC/elements.html#classes
  2. https://maintainablecss.com/chapters/semantics/

coothead

1 Like

Okay, I see what’s going on here now (I think). When I read the first quote above the first thing I thought of was Amazon, then I found your reference to it in another post.

And coothead is right in post#6.

But here’s where the difference is…

On your “Product Catalog” page, each Product Title would be an h2. That assumes that they are all following the Product Catalog Title which would be your h1.

Then on your “Product Details” page the actual Product Title will be the h1.

That way it’s all still semantic markup and the font sizes haven’t changed. You’ve just swapped the hierarchy around and it naturally takes care of the font size itself.

See Example 1 here at W3’s CSS Flexible Box Layout Module

product

Their code for that is shown using <section> tags and each product title is using an h1. I don’t like multiple h1 tags on a page and those titles would be an h2 to me (as I just described above).

Whether each product is marked up with a <section> tag as the product wrapper or a <li> as the product wrapper is up to you. I see it as a list of products so I would be good marking up the product page with a ul and list items.

1 Like

So, here’s the thing. If your doing something like #selector h2 over something like class names for heading-h2, your going to be repeating a lot of code, which is such an anti-pattern. You can do whatever you want but, when I do interviews and we see the first being used over the second, it raises alarms and odds are you wont be hired.

BTW I choose to believe this because I have worked on several large projects and, thats just the way its done. It makes for smaller CSS files with reusable classes. Also what I wrote by definition is semantic btw, what I am saying it doesn’t HAVE to be. If your doing this solo, write them in a way that you understand. If your part of a team, work out a reusable naming convention that works for everyone.

2 Likes

I am not here to change your beliefs, I am just
here to point out what the W3 org’s position
is with regard to semantic coding. If you and
your team wish to disregard their guidelines
far be it from me to dissuade you and your
workmates from doing whatever you choose

But, I would suggest that instead of posting a
statement like this

Class do not have to be semantic.

…you should word it somewhat like this…

Personally, I believe that the class selector
does not have to be semantic

coothead

Why, even your own reference material stated “we recommend”. And I teach these kind of things, so that being said, if you want to use W3C as a source, perhaps don’t reference an Last Call Working Draft, first off its from 2011. Secondly why not link to the recommendations, which talk of no such thing anymore:

HTML Sematics
Style Attribute

So again, classes do not HAVE to be semantic. Screen readers don’t care what your classes are. SEO doesn’t care what your classes are and frankly no one cares what your classes are, do what works for you and/or your team.

If you look at the top css frameworks (NOT that this is a recommendation), they follow the same pattern I described.

Material UI is one of the more popular

I looked at some of ya’lls sites and ( do NOT take this as mean, it’s just an observation), and they all look fairly basic design wise(but hey you have them, I wish I could get around to fixing mine). But of you want to take it to the next level and do more complicated work, trust me on this.

@Ray.H and @coothead,

Sorry to start a heated thread and then disappear, but I have been sick all week. :nauseated_face:

Am reading everyone’s responses and hope we can pick up this thread, as your help is definitely needed!!

P.S. I’ve got some nasty medical stuff going on and may not be able to finish my website, but when I have lucid periods I will try to provide the things you are asking for.

@Ray.H,

Thank you for trying to help.

While you may disagree, I would really prefer to stick with HTML 4 for now. That is what my entire website is built in, and trying to learn HTML 5 and cram it into a website that is 90% done seems futile. (Yes, I want to learn HTML 5 and CSS3, but having good semantics should be independent of the version of HTML.)

Also, I am wondering if having this conversation at this late stage of my website even makes sense? Maybe I should just plow through doing things as I have, and worry about cleaning things up in v2.0? :wonky:

Okay, but that was my point… I think what I have is semantically okay. It may be more generic using HTML4, but it is decent.

The thing I am trying to get my head around - but am not doing a good job describing here - is what to do when basic HTML elements repeat in your website yet require different styles.

For example, you could have a UL/LI that is used in one place to lay out a page using flexbox. And you could have a UL/LI in another spot that is used purely for bullet points in a body of text. And then you could have another UL/LI used to lay out a shopping cart.

In those instances, using the UL/LI semantic metaphor is acceptable, right?

But my point is that you cannot simply style the UL/LI and call it quits, because a UL/LI represents vastly different things depending on context.

So the way I have handle that is using some anchor like…

/* Page Layout */
#context-01 ul{ }
#context-01 li{ }

/* Bullet List of items in a paragraph */
#context-02 ul{ }
#context-02 li{ }

/* Shopping-Cart items */
#context-03 ul{ }
#context-03 li{ }

The point is that if you are re-using some HTML element like a UL/LI in multiple places in your website, then I don’t see a more efficient way of doing things because each UL/LI is a separate creature.

Furthermore, using a CSS class wouldn’t do jack to help refactor things when one UL/LI represents 3 different things. (If you had a bulleted list in 4 places on pne page, then yes, a class would be needed, but you hopefully see my point!)

Thanks to #Coothead, I have started using MDN much more. But for now I am sticking with basic HTML4 because of the reasons mentioned above.

That was a bad example - I didn’t know it was a keyword.

I’m listening… :wink:

This is all a complicated topic, but hopefully I can learn better ways to do things.

Here is a contrived example of what a Product “component” would look like…

<!DOCTYPE HTML>
<html lang="en">

<head>
  <!-- 2019-11-02 -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

  <title>z_sample-product-details.html</title>

  <style media="screen">
    body{
      font-family: Helvetica, Arial, Sans-Serif;
      font-weight: normal;
      line-height: 1.4em;
      font-size: 0.9em;
    }

    #pageBody_ProductDetails{
      display: flex;
      flex-wrap: wrap;
      margin: 50px auto 0 auto;
    }
    
    ul#productWrapper{
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      justify-content: flex-start;
      margin: 0 auto;
      padding: 0;
      list-style: none;
    }

    li.productImage,
    li.productDetails{
      width: 300px;
      margin: 20px 40px 10px 40px;
      padding: 0;
      border: none;
    }

    li.productImage img{
      width: 300px;
      border: 1pt solid #999;
      box-shadow: 5px 5px 15px 0px #AAA;
    }

    li.productDetails h2.productTitle{
      margin: 0;
      padding: 0.4em 0 0.2em 0;
      font-family: New Courier;
      font-size: 2.2em;
      font-weight: bold;
    }

    li.productDetails span.productAuthor{
      display: block;
      margin: 0;
      padding: 0 0 0.5em 0;
      font-family: New Courier;
      font-size: 1.2em;
      font-style: italic;
    }
    
    li.productDetails hr{
      color: #CCC;
    }

    li.productDetails p.productDescription{
      margin: 0;
      padding: 0 0 0.2em 0;
    }

    li.productDetails span.productFormat{
      display: block;
      margin: 0;
      padding: 1em 0 0 0;
      font-size: 1.2em;
    }
    
    li.productDetails span.productPrice{
      display: block;
      margin: 0;
      padding: 0.2em 0 1em 0;
      font-size: 1.5em;
      font-weight: bold;
    }

    form#freeBookCheckout{
      margin: 10px 0;
      padding: 0;
      text-align: left;
    }

    form#freeBookCheckout fieldset{
      margin: 0;
      padding: 0;
      border: none;
    }

    form#freeBookCheckout input{
      margin: 0 0 -20px 0;
      padding: 0.6em 1em;
      background-color: #CFA;
    }
  </style>
</head>

<body>
  <div id="pageBody_ProductDetails">
    <ul id="productWrapper">
      
      <!-- Product Image (Left) -->
      <li class="productImage">
        <a href="">
          <img src="https://i.imgur.com/c10UTWv.png" alt="" />
        </a>
      </li>
      
      <!-- Product Details (Right) -->
      <li class="productDetails">
        <h2 class="productTitle">101 UX Principles</h2>
        <span class="productAuthor">by Will Grant</span>
        <hr>
        <p class="productDescription">We want our UX to be brilliant. We want to create stunning user experiences. We want our UX to drive the success of our business with useful and usable software products. This book draws on the wisdom and training of Jakob Nielsen and Don Norman to help you get your UX right - in 101 ways!</p>
        <span class="productFormat">eBook</span>
        <span class="productPrice">$44.99</span>
        
        <!-- Free eBook Checkout Form -->
        <form id="freeBookCheckout" action="" method="post">
          <fieldset>
            <!-- Submit Form -->
            <input type="submit" name="freeBookCheckout" class="button" value="Checkout" />
          </fieldset>
        </form>
      </li>
    </ul>
  </div>

</body>
</html>

As stated in my OP, I have four different places on my website where I might want to display a Product, but the content - and especially the styling - will vary in each “context”.

Or, as I stated earlier in this post, I have lots of places on my website where I am using HTML in a semantically correct way, but the problem is that the given HTML element has many different “contexts”. (In object-oriented programming this is referred to as “polymorphism”. For instance, you have a “shape” which depending on “context” could be a “square” or a “circle” or a “right triangle” and so your code varies depending on the “content” even though they are all still a “shape”!)

Hi @UpstateLeafPeeper. From my understanding, what you’re looking for is a flexible/scalable way to write CSS in a component-driven way.

For example, in your Product Title example, you have the component of a “Product” used in various places across your website, but the Product Title style changes between components.

What you’re describing is a very common use case (especially among larger websites!).

What you’re looking for is a CSS methodology. This is not a plugin or an extension you add to your code editor. It’s essentially a naming convention method where, when followed correctly, allows you to write CSS that is very modular.

There are quite a few CSS methodologies you can choose from, but the most popular is BEM.

I’d recommend checking out this resource which shows you (with examples) how BEM works.

I’ve got a fair bit of experience with BEM and other methodologies so let me know if you have any other questions!

@Ray.H,

So what do you think?

Hi LeafPeeper, My apologies for not replying back to you sooner.
It was a busy week for me, let me look back over your last post and I’ll follow up. :slightly_smiling_face:

Like others around here, I cut my teeth on HTML 4.01 strict. What I liked about it was, well it was strict, it forced you to write proper valid code. Which is a good thing, and I have carried that with me into HTML 5. Though 5 allows a little bit more looseness that does not mean you have to follow that. For example 5 allows multiple h1 tags on a page, but I don’t agree with that so I don’t follow that.

HTML5 introduced a lot of new html elements and I have come to appreciate some of them as they are things that were missing in HTML 4.01 (that we needed). So HTML 5 allows you to take your semantics a step further than 4 does.

That doesn’t mean I use every new and shiny element. Honestly I haven’t found myself needing multiple <footer> elements either. Though it is allowed, it does mean we have to do it.

That is up to you and honestly if I was in your shoes I would be inclined to follow through with what I started. Then like you say, in v2.0 you can rework it with HTML 5. You will have a lot of reading and learning to do and that may be too much of a distraction for you at this point.

At the end of the day a UL is an “Unordered List of Items”. In the three examples you gave of a UL, I see three different classes going on the UL element. Maybe not even needing a class for the one that has default bullets. Just style your default UL the way you want as far as margins and paddings are concerned.

Like I mentioned earlier, there may be no escaping the fact that you will need several different classes to accomplish what you need to do. But try your best to make as many global classes as you can so they can be reused.

But back to that UL example you mention. I would not have a problem setting a class directly on the parent UL and then styling my child li from the parent’s class. I would be doing that before I tried to work global classes into my child li.

And then you could have another UL/LI used to lay out a shopping cart.

For example…

<ul class="cart">
   <li></li>
   <li></li>
   <li>
        <p>Some paragraph content</p>
   </li>
<ul>

.cart {
   margin:0;
   padding:0;
   list-style:none;
}
.cart li { }
.cart p { }

So I’ve got one class that I can style my cart list with. And yes, that is a <p> tag there. You may very well have a paragraph in your list item and it can style differently from your global site p tags. But it doesn’t necessarily need a class on it in the html to target it.

All along I’ve just been saying that you can use descendant selectors to target from the parent. But if you find yourself getting deeper than 3 descendants it may be time to step back and simply make it a new class. Whatever it takes to keep Both your html and css as lean as possible.

Do get caught up on CSS3 though. You can use things like :nth-child() to save yourself from adding a bunch of classes to your html and getting your descendant selectors too long. You can use CSS3 with HTML 4.01

2 Likes

Had a typo there.

1 Like