Replacing CSS classes with more generic ones - css

I'm currently working on refactoring a large amount of CSS, and a common trend I'm seeing is that several classes have been created for a very specific item on a page. Rather than trying to describe what they do, the classes are named things like "PressReleaseText", or "SpecLabel", etc. Most of these just define one item, like a font-size or a color.
I'm wondering if it would be better to just create several utility classes, like .fontSize140 {font-size: 140%;}, .bgColorWhite{ background-color: white;}, and utilize those in place of all the duplication occurring across the current set of classes.
Are there any drawbacks to doing this? The point where it becomes blurry is if a current class has 3 attributes set, like color, background color, and font size, and I already have generic classes for all three of those, would my class definition in the html just look something like class="white bgColorBlue fontSize140". That just seems excessive.

This is absolutely a horrible practice. It's 10x worse than the current class names that you're trying to replace. Consider the following class names:
fontSize140
bgColorWhite
marginTop150
These are obviously very descriptive class names. The problem is that they describe the styles behind the class, not the content that it styles. While this can be easier to read in HTML, it will be a complete nightmare in the future when and if you decide to make even the tiniest redesign.
For example, let's say we just applied these three classes to a block of text. It has a font size of 140%, a white background, and a top margin of 150px. That's all fine--until we decide that it needs to be 90% font, a blue background, and no top margin. Now, not only do you have to change the CSS declarations, you have to either:
(1) edit every instance of the class in the HTML to be fontSize90bgColorBlueNoTopMargin or whatever; or
(2) leave the class name alone and leave an extremely confusing class name in the HTML.
Either way it will be a massive pain for you in the future, whereas the current class names (e.g., specLabel, pressReleaseText) appropriately describe the content that they style; their styles can be easily changed without affecting the content inside of them, and thereby never affecting the name of the class.

Part of the point of CSS is to separate the content from the presentation, to make it easier to alter the presentation without altering the content. If you have class="white bgColorBlue fontSize140" all over the place, you have defeated this goal; you might as well just go with style="color: white; background-color: blue; font-size: 140%". Your classes should say what you mean not what you want it to look like.
If you find yourself repeating certain settings for lots of classes, like the following
.PreReleaseText { font-size: 140% }
.SpecLabel { font-size: 140%; background-color: white }
.SomeOtherThing { font-size: 140% }
You can instead combine several of them into one single rule
.PreReleaseText, .SpecLabel, .SomeOtherThing { font-size: 140% }
.SpecLabel { background-color: white }
If you really do just have several classes that are synonyms of each other, you might want to think about why that is. Why are all of those styled the same way? Is there some class name you can come up with that encompasses all of those uses? Or is it just incidental that they happen to be styled the same way? If it's just incidental, then they should have separate rules, so you can easily update the styles of each class independently. If there is some unifying theme, then perhaps you should merge them into a single class.
Remember to consider what will happen in different media, or in a redesign. Imagine that the company is bought out, and you want to change the color scheme to match the new corporate colors, without doing a full redesign. If you have a .bgColorWhite class, but only some of the things labelled with that class should change to a new color in the redesign, you'll have to go through all of your templates and markup again to separate out the classes, but if you labelled them with more meaningful classes, you may be able to just tweak the colors in the appropriate classes.
These are some general guidelines; you should always use what works best for you. If you had a more specific example, I might be able to suggest a better way of refactoring your classes for your specific need.

There is not a right and wrong way to do this as far as I'm concerned. It depends on knowing how often you'll reuse things and what makes it easiest to understand the CSS. I've often seen those general things like .fontSize140 end up causing problems later on when you have to make changes. I prefer in most cases to group classes but keep the individual names.
So I might have
.Thing1,
.Thing2,
.Thing3 { font-size:14px; }
.Thing1 { font-weight:bold; }
.Thing2 { font-size:italic; }
Instead of having
.font14 { font-size:14px; }
And then still needing the .Thing1 and .Thing2 clases.
That was I can always change the CSS easily later without having to worry what is sharing that common .fontSize140 for example.

I would stay away from getting too general like .fontSomeSize. That said i generally try and use classes that define things as logical "types" or "objects" for example .ruled-list or .summary.

Why don't you try something like this:
Use a css preprocessor like sass.
/* define app/website colors */
$main-color: #223c61;
$secondary-color: #2954a2;
$accent-color: #4cceac;
/* some example css classes */
.text-main { color: $main-color; }
.bg-secondary { background-color: $secondary-color; }
.bg-accent { background-color: $accent-color; }
/* define app/website spacings */
$spacing-xs: 10px;
$spacing-sm: 15px;
$spacing-md: 25px;
$spacing-lg: 35px;
/* some example css classes */
.padding-up-xs { padding-top: $spacing-xs; }
.padding-down-lg { padding-bottom: $spacing-lg; }
.margin-left-md { margin-left: $spacing-md; }
The above code has generic css classes, but it is not bound to a specific value. For some very specific styling, you can always make a custom css file to account for that.
I see a lot of people using custom margins and paddings throughout their css. See the code below.
.blog-post-sidebar-right { margin-top: 14px; }
.news-post-bottom-text { margin-bottom: 23px; }
As a rule of thumb, I always use 4/5 predefined margins and paddings. And not some arbitrary number you make up on the fly.
So why not define generic css classes to use them. I took this same idea an applied it to all of my css. Now I can have the same code base in every project.
Because you now use a css preprocessor, it's easy to maintain, flexible and easy to extend.
Im not saying this is the best option, but it does the job for me.

Related

Dynamic CSS class [duplicate]

It is possible to pass parameters for CSS in class name? For example:
.mrg-t-X {
margin-top: Xpx;
}
<span class="mrg-t-10">Test</span>
In this example X should be 10.
No it isn't. The closest we have to this is the attr() function, but that only works within the content property:
figure::before {
content: attr(data-before) ', ';
}
figure::after {
content: attr(data-after) '!';
}
<figure data-before="Hello" data-after="world"></figure>
Perhaps one day this will be expanded so that we can use it elsewhere, but for now this isn't possible.
Currently as I'm sure you're aware if you want to be able to use the .mrg-t-X class, you'll need to define separate style rules for each X you wish to allow:
.mrg-t-1 { ... }
.mrg-t-2 { ... }
.mrg-t-3 { ... }
...
Nowdays you can use CSS variable inside a style attribute instead generating a specific class:
Custom properties (sometimes referred to as CSS variables or cascading variables) are entities defined by CSS authors that contain specific values to be reused throughout a document. They are set using custom property notation (e.g., --main-color: black;) and are accessed using the var() function (e.g., color: var(--main-color);).
Complex websites have very large amounts of CSS, often with a lot of repeated values. For example, the same color might be used in hundreds of different places, requiring global search and replace if that color needs to change. Custom properties allow a value to be stored in one place, then referenced in multiple other places. An additional benefit is semantic identifiers. For example, --main-text-color is easier to understand than #00ff00, especially if this same color is also used in other contexts.
Custom properties are subject to the cascade and inherit their value from their parent.
example
span {
display: block;
margin-top: var(--m-t);
}
html {
background: repeating-linear-gradient(to bottom, transparent, 10px, lightgrey 10px, lightgrey 20px);} /* see 10px steps */
<span style="--m-t:50px">one</span>
<span style="--m-t:85px">two</span>
<span style="--m-t:110px;">three</span>
Maybe you are looking for SCSS or LESS. It have mixins, variables, etc, and it autocompile real and long css. It was maded to this purposes and write less and less css with the same result.
http://sass-lang.com/guide
http://lesscss.org/
#size: 10px;
.class { font-size: #size; }
Good luck!
It isn't possible to directly pass parameters using just CSS but you're not the first person to ask - check out this question which looks at CSS and JavaScript options and also this might be helpful regarding attribute selection.
This will only help if you are looking at a few variables of margin-top but I don't know what context you're using this in. Depending on what you're using it for there might be better ways.
The simplest way would probably be just to add the style inline to your span <span style="margin-top:10px"> but I try to stay away from inline CSS!
no your code is wrong
but you can write css inside the tag
*<span style="margin-top:Xpx;">*

CSS Set dynamic value depend on class [duplicate]

It is possible to pass parameters for CSS in class name? For example:
.mrg-t-X {
margin-top: Xpx;
}
<span class="mrg-t-10">Test</span>
In this example X should be 10.
No it isn't. The closest we have to this is the attr() function, but that only works within the content property:
figure::before {
content: attr(data-before) ', ';
}
figure::after {
content: attr(data-after) '!';
}
<figure data-before="Hello" data-after="world"></figure>
Perhaps one day this will be expanded so that we can use it elsewhere, but for now this isn't possible.
Currently as I'm sure you're aware if you want to be able to use the .mrg-t-X class, you'll need to define separate style rules for each X you wish to allow:
.mrg-t-1 { ... }
.mrg-t-2 { ... }
.mrg-t-3 { ... }
...
Nowdays you can use CSS variable inside a style attribute instead generating a specific class:
Custom properties (sometimes referred to as CSS variables or cascading variables) are entities defined by CSS authors that contain specific values to be reused throughout a document. They are set using custom property notation (e.g., --main-color: black;) and are accessed using the var() function (e.g., color: var(--main-color);).
Complex websites have very large amounts of CSS, often with a lot of repeated values. For example, the same color might be used in hundreds of different places, requiring global search and replace if that color needs to change. Custom properties allow a value to be stored in one place, then referenced in multiple other places. An additional benefit is semantic identifiers. For example, --main-text-color is easier to understand than #00ff00, especially if this same color is also used in other contexts.
Custom properties are subject to the cascade and inherit their value from their parent.
example
span {
display: block;
margin-top: var(--m-t);
}
html {
background: repeating-linear-gradient(to bottom, transparent, 10px, lightgrey 10px, lightgrey 20px);} /* see 10px steps */
<span style="--m-t:50px">one</span>
<span style="--m-t:85px">two</span>
<span style="--m-t:110px;">three</span>
Maybe you are looking for SCSS or LESS. It have mixins, variables, etc, and it autocompile real and long css. It was maded to this purposes and write less and less css with the same result.
http://sass-lang.com/guide
http://lesscss.org/
#size: 10px;
.class { font-size: #size; }
Good luck!
It isn't possible to directly pass parameters using just CSS but you're not the first person to ask - check out this question which looks at CSS and JavaScript options and also this might be helpful regarding attribute selection.
This will only help if you are looking at a few variables of margin-top but I don't know what context you're using this in. Depending on what you're using it for there might be better ways.
The simplest way would probably be just to add the style inline to your span <span style="margin-top:10px"> but I try to stay away from inline CSS!
no your code is wrong
but you can write css inside the tag
*<span style="margin-top:Xpx;">*

Priorizing CSS properties

I am building websites for a while, and I have a question about CSS I can't really rid over. So there is that frequent situation when multiple classes affect a DOM element, and both classes declare the same properties. For example:
.first {
color:white;
}
.second {
color:black;
}
I know that if I have an element with class="first second" in that the text will be black. If I rather want it to be white, I have several options:
Using !important: I know this one is handy and I use it, but sometimes, if I use it too often, my CSS may become messy. I mean, multiple !important's can result the same basic situation.
Reordering the classes inline: if I am correct, which class comes first, it will be the priority one. This is nice, but i often work with environments where I can't affect that. Secondly, this is not a global but a local solution.
Reorder the CSS itself: well, this sounds interesting, but if I work with many stylesheets (and I do), it is hard to track, especially when it is WIP.
Actually what I am looking for is some workaround like z-index but for priorizing which class is stronger. Because I can't really find anything useful in this topic, I am just curious maybe it is a user error, and you guys know something I don't. How do you manage this? What do you suggest?
class="first second" is the same as class="second first". The priority is based on the position of the declarations in your css and not in their position on the html element.
So, if you want priority of a class against another, put the top priority class LAST on the css file.
.first {
color:white;
}
.second {
color:black;
}
in this example, class second has always priority over class first. This happens because browser scans through the css top-to-bottom and always applying the rules of matched classes that finds. So, the last matched class has priority over the previous matched classes.
see this fiddle: http://jsfiddle.net/5c29dzrr/
At the same specificity level, the CSS selector that is furthest down the stylesheet will be applied. So in your example, if you wanted in that situation to have the element with the white colour you would have to order your properties like so:
.second {
color: black;
}
.first {
color: white;
}
The order of the classes in the HTML tag is not important; it is the order in which they appear in your CSS.
The better way to handle this is to go with some better naming convention such as BEM or SMACSS so that you don't have the issue of conflicting class names.
Edit: It might be worth reading up on specificity and the cascade for a better understanding of this. I found this calculator to be pretty handy in determining which rules will take precendence, although these days you can just use the developer tools to find out that information.

Is there a way to apply a CSS class from within a style?

I'm trying to be more modular in my CSS style sheets and was wondering if there is some feature like an include or apply that allows the author to apply a set of styles dynamically.
Since I am having a hard time wording the question, perhaps an example will make more sense.
Let's say, for example, I have the following CSS:
.red {color:#e00b0b}
#footer a {font-size:0.8em}
h2 {font-size:1.4em; font-weight:bold;}
In my page, let's say that I want both the footer links and h2 elements to use the special red color (there may be other locations I would like to use it as well). Ideally, I would like to do something like the following:
.red {color:#e00b0b}
#footer a {font-size:0.8em; apply-class:".red";}
h2 {font-size:1.4em; font-weight:bold; apply-class:".red";}
To me, this feels "modular" in a way because I can make modifications to the .red class without having to worry so much about where it is used, and other locations can use the styles in that class without worrying about, specifically, what they are.
I understand that I have the following options and have included why, in my fairly inexperienced opinion, they are less-than-perfect:
Add the color property to every element I want to be that color. Not ideal because, if I change the color, I have to update every rule to match the new color.
Add the red class to every element I want to be red. Not ideal because it means that my HTML is dictating presentation.
Create an additional rule that selects every element I want to be red and apply the color property to that. Not ideal because it is harder to find all of the rules that style a specific element, making maintenance more of a challenge
Maybe I'm just being an ass and the following options are the only options and I should stick with them. I'm wondering, however, if the "ideal" (well, my ideal) method exists and, if so, what is the proper syntax?
If it doesn't exist, option 3 above seems like my best bet. However, I would like to get confirmation.
First of all you cannot do apply-class:".red";
to perform this type of action i will suggest you to use this method
.red {color:#e00b0b;}
h2 {font-size:1.4em; font-weight:bold;}
.mymargin{margin:5px;}
<h2 class="red mymargin">This is h2</h2>
and to use in div
<div id="div1" class="red mymargin"></div>
In this case if you will change in .red class.it will be changed everywhere
Short answer: There's no way to do this in pure CSS.
Longer answer: Sass solves this problem via the #extend directive.
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
#extend .error;
border-width: 3px;
}
This lets you keep your CSS modular in development, though it does require a precompilation step before you use it. It works very nicely though.
You can use the DOM in javascript to edit the id and/or class attributes of HTML tags dynamically.
I agree with DarthCaesar and jhonraymos. To update a class using JavaScript, all you would need is a simple:
function toggleColorClass(e){
var redClass = document.getElementsByClassName('red');
redClass.removeAttribute('class', 'red');
/*Set the class to some other color class*/
redClass.setAttribute('class', 'blue');
}
Of course, to make this work, you would need to include the above function in your document somewhere... if this is all the JS you're using you can probably stick it in the head or even use it inline. You would probably also want to write it so that the toggle goes in both directions, i.e. turning red on and off. Furthermore, jhonray's snippet is probably how you would want to mark up your CSS.

CSS 'schema' how-to

How does one go about establishing a CSS 'schema', or hierarchy, of general element styles, nested element styles, and classed element styles. For a rank novice like me, the amount of information in stylesheets I view is completely overwhelming. What process does one follow in creating a well factored stylesheet or sheets, compared to inline style attributes?
I'm a big fan of naming my CSS classes by their contents or content types, for example a <ul> containing navigational "tabs" would have class="tabs". A header containing a date could be class="date" or an ordered list containing a top 10 list could have class="chart". Similarly, for IDs, one could give the page footer id="footer" or the logo of the website id="mainLogo". I find that it not only makes classes easy to remember but also encourages proper cascading of the CSS. Things like ol.chart {font-weight: bold; color: blue;} #footer ol.chart {color: green;} are quite readable and takes into account how CSS selectors gain weight by being more specific.
Proper indenting is also a great help. Your CSS is likely to grow quite a lot unless you want to refactor your HTML templates evertime you add a new section to your site or want to publish a new type of content. However hard you try you will inevitably have to add a few new rules (or exceptions) that you didn't anticipate in your original schema. Indeting will allow you to scan a large CSS file a lot quicker. My personal preference is to indent on how specific and/or nested the selector is, something like this:
ul.tabs {
list-style-type: none;
}
ul.tabs li {
float: left;
}
ul.tabs li img {
border: none;
}
That way the "parent" is always furthest to the left and so the text gets broken up into blocks by parent containers. I also like to split the stylesheet into a few sections; first comes all the selectors for HTML elements. I consider these so generic that they should come first really. Here I put "body { font-size: 77%; }" and "a { color: #FFCC00; }" etc. After that I would put selectors for the main framework parts of the page, for instance "ul#mainMenu { float: left; }" and "div#footer { height: 4em; }". Then on to common object classes, "td.price { text-align: right; }", finally followed by extra little bits like ".clear { clear: both; }". Now that's just how I like to do it - I'm sure there are better ways but it works for me.
Finally, a couple of tips:
Make best use of cascades and don't "overclass" stuff. If you give a <ul> class="textNav" then you can access its <li>s and their children without having to add any additional class assignments. ul.textNav li a:hover {}
Don't be afraid to use multiple classes on a single object. This is perfectly valid and very useful. You then have control of the CSS for groups of objects from more than one axis. Also giving the object an ID adds yet a third axis. For example:
<style>
div.box {
float: left;
border: 1px solid blue;
padding: 1em;
}
div.wide {
width: 15em;
}
div.narrow {
width: 8em;
}
div#oddOneOut {
float: right;
}
</style>
<div class="box wide">a wide box</div>
<div class="box narrow">a narrow box</div>
<div class="box wide" id="oddOneOut">an odd box</div>
Giving a class to your document <body> tag (or ID since there should only ever be one...) enables some nifty overrides for individual pages, like hilighting the menu item for the page you're currently on or getting rid of that redundant second sign-in form on the sign-in page, all using CSS only. "body.signIn div#mainMenu form.signIn { display: none; }"
I hope you find at least some of my ramblings useful and wish you the best with your projects!
There are a number of different things you can do to aid in the organisation of your CSS. For example:
Split your CSS up into multiple files. For example: have one file for layout, one for text, one for reset styles etc.
Comment your CSS code.
Why not add a table of contents?
Try using a CSS framework like 960.gs to get your started.
It's all down to personal taste really. But here are a few links that you might find useful:
http://www.smashingmagazine.com/2008/08/18/7-principles-of-clean-and-optimized-css-code/
http://www.smashingmagazine.com/2008/05/02/improving-code-readability-with-css-styleguides/
http://www.louddog.com/bloggity/2008/03/css-best-practices.php
http://natbat.net/2008/Sep/28/css-systems/
Think of the CSS as creating a 'toolkit' that the HTML can refer to. The following rules will help:
Make class names unambiguous. In most cases this means prefixing them in a predicatable way. For example, rather than left, use something like header_links_object2_left.
Use id rather than class only if you know there will only ever be one of an object on a page. Again, make the id unambiguous.
Consider side effects. Rules like margin and padding, float and clear, and so on can all have unexpected consequences on other elements.
If your stylesheet is to be used my several HTML coders, consider writing them a small, clear guide to how to write HTML to match your scheme. Keep it simple, or you'll bore them.
And as always, test it in multiple browsers, on multiple operating systems, on lots of different pages, and under any other unusual conditions you can think of.
Putting all of your CSS declarations in roughly the same order as they will land in the document hierarchy is generally a good thing. This makes it fairly easy for future readers to see what attributes will be inherited, since those classes will be higher up in the file.
Also, this is sort of orthogonal to your question, but if you are looking for a tool to help you read a CSS file and see how everything shakes out, I cannot recommend Firebug enough.
The best organizational advice I've ever received came from a presentation at An Event Apart.
Assuming you're keeping everything in a single stylesheet, there's basically five parts to it:
Reset rules (may be as simple as the
* {margin: 0; padding: 0} rule,
Eric Meyer's reset, or the YUI
reset)
Basic element styling; this
is the stuff like basic typography
for paragraphs, spacing for lists,
etc.
Universal classes; this section
for me generally contains things
like .error, .left (I'm only 80%
semantic), etc.
Universal
layout/IDs; #content, #header,
or whatever you've cut your page up
into.
Page-specific rules; if you
need to modify an existing style
just for one or a few pages, stick a
unique ID high up (body tag is
usually good) and toss your
overrides at the end of the document
I don't recommend using a CSS framework unless you need to mock something up in HTML fast. They're far too bloated, and I've never met one whose semantics made sense to me; it's much better practice to create your own "framework" as you figure out what code is shared by your projects over time.
Reading other people's code is a whole other issue, and with that I wish you the best of luck. There's some truly horrific CSS out there.
Cop-out line of the year: it depends.
How much do you need to be styling? Do you need to change the aspects of alomost every element, or is it only a few?
My favorite place to go for information like this is CSS Zen Garden & A List Apart.
There are two worlds:
The human editor perspective: Where CSS is most easily understand, when it has clear structure, good formatting, verbose names, structured into layout, color and typesetting...
The consumer perspective: The visitor is most happy if your site loades quickly, if it look perfect in his browser, so the css has to be small, in one file (to save further connections) and contain CSS hacks to support all browsers.
I recommend you to start with a CSS framework:
Blueprint if you like smaller things
or YAML for a big and functional one
There is also a list of CSS Frameworks...
And then bring it in shape (for the browser) with a CSS Optimizer (p.e. CSS Form.&Opti.)
You can measure the Results (unpotimized <-> optimized) with YSlow.
A few more tips for keeping organized:
Within each declaration, adopt an order of attributes that you stick to. For example, I usually list margins, padding, height, width, border, fonts, display/float/other, in that order, allowing for easier readability in my next tip
Write your CSS like you would any other code: indent! It's easy to scan a CSS file for high level elements and then drill down rather than simply going by source order of your HTML.
Semantic HTML with good class names can help a lot with remembering what styles apply to which elements.

Resources