What is the best way of defining general non-block-specific styles throughout the site?
For example:
html
<div class="intro">
<p class="intro__text">foo</p>
</div>
<div class="profile">
<p class="profile__text">bar</p>
</div>
sass/css
.intro__text {
}
.profile__text {
}
.text {
margin-bottom: 0.5em;
}
If I wanted the text to be styled the same, would I (given I am using a pre-processor) #extend .text into the .intro__text and .profile__text classes, or just have all paragraphs throughout the site have a class of text?
Both those solutions seem slightly incorrect to me.
If I have a very common style, it feels like I'm going to be duplicating a lot of styles throughout my rendered css (bumping up the filesize) but having a class of text repeated all throughout my markup seems unnecessarily verbose and untidy.
Is there a best practice for this situation?
I can't say that there is the best way to do it. It depends on the structure of your project and what style your prefer. Both approaches are used in mostly code.
If you like to manage styles through css files - write #extend. However in case you want an element without common style you have to create a modifier for the el. For example - .profile__text--reset.
If you want declare common styles, your class list with common classes may become too long. But it is more clear and specific. And you have a possibility to manage it via javascript.
One improvement for this code is that it is better to use helpers with modifiers. For example, instead of simple .text use .text--sm or .text--m-sm. Or if you want only margin - .m-sm. But it is up to you.
You have several options:
Preprocessor (Sass/LESS/etc) mixins + clean-css/postcss cleaner — this way is simple and powerful, but not flexible, since it's not useful for dynamic landing pages, SPA, etc.;
Element of outer block mix (BEM/runtime mixin): class="intro__text grid__text" — in that way you just splitting manually visual and positioning styles and use their classes together;
Other block mix: class="intro__text paragraph paragraph--valuable" — almost like the previous variant but without linking to the abstract grid block, the best and the most flexible way (IMHO).
NB: Also you can extend BEM mixes with modifiers even in runtime, it's VERY powerful tool.
NB2: If you don't need dynamic web pages, you can freely use sass mixins. Personally I don't use sass/less mixins, only global variables for colors, grid, gaps, etc used in my own classes.
Related
I've just started my first project which is building an admin panel. My task is to create HTML and CSS - sort of a base of design to process further to the back-end developers.
I was asked to keep CSS simple and classes as descriptive as possible ( could be long ) and to use Bootstrap.
To avoid creating unnecessary classes which could be used once or twice I decided to go with :nth-child since I thought giving new class to each column is too much. Additionally I created few base classes that might be used for adding 0px padding and margin.
Unfortunately, as I was writing more and more code I've noticed that some CSS code looks like this:
.print-history-advanced-search > [class*='col-']:nth-child(5) > .form-group > .form-horizontal > .form-group > [class*='col-']:first-child
And it is not a single line.
Additionally, I've noticed that sometimes that when I am making a new class and it has lots of parent elements, I cannot write the CSS selector by its own, but I need to state the parents of the this particular element and put the class at the end, which does not make sense.
Is there any solution I could use to avoid creating classes that are simply used in one or two divs, but also make the CSS code less chaotic and avoid very long names? Or maybe I should just give up on children and nesting and work with just classes?
Thank you for your help!
Have a nice day!
If you want to write good CSS, then I'd suggest the BEM model is a good route to go down.
The essentials are;
No element/selector heirachy
No use of elements in selectors
Class based styles only
BEM stands for Block, Element, Modifier - which is how your class names are formed. Borrowing an example from their site;
.form { }
.form--theme-xmas { }
.form--simple { }
.form__input { }
.form__submit { }
.form__submit--disabled { }
<form class="form form--theme-xmas form--simple">
<input class="form__input" type="text" />
<input
class="form__submit form__submit--disabled"
type="submit" />
</form>
You can see there's a form Block, and then a form__input and form__submit Element, and then a form__submit--disabled Modifier.
Depending on your needs I would recommend using css preprocessors like SASS,LESS.
You’ll find that as a website grows, you’ll develop a pretty long, scrolling list of various elements and CSS rules. Some of the rules might overlap or override each other eventually (in that case, usually the more specific rule will win).
You can end up with a lot more code than you expected, especially considering the different variations of a rule you need for different browsers and screen sizes.
There are many ways to refactor your CSS code to make it easier to navigate and use. Some of the easiest methods are the most effective and have the most mileage. Here are some of the quickest ones:
Keep your spacing uniform: Maintain the same spacing between rules
and within declarations throughout your file so that it’s easier to
read.
Use semantic or “familiar” class/id names: Instead of using a class
name like “bottom_menu”, try using the semantic tag “footer”. Or
when you have an image in your “contact” section, make sure you’re
using a class on your image like “contact_image”
Keep it DRY (Don’t Repeat Yourself): Ideally you want to repeat as
little of your code as possible. Do you find the declaration
“background-color: #000″ repeated throughout your CSS file? Consider
typing it once and instead, using multiple selectors on the one
declaration.
Put your tidiness to the test with these tools: Run your CSS through
CSS Lint or W3C—these will help to parse your CSS file correctly,
and highlight problem areas. Your web browser’s developer tools are
also extremely useful for pinpointing specific elements on your
website and using the area as a sandbox to experiment with different
styles and positioning.
Have a look here for more info
I've often seen css with classes that only modify a single property. For example,
.ns-center-text{
text-align: center;
}
What are the advantages and disadvantages of this technique?
Advantages
You can add a class in the HTML for quick and easy presentational things.
You only have to add this declaration once in your CSS, instead of many times for each selector (or grouping a whole bunch of them).
Disadvantages
You tie presentation to the information layer.
You may end up with many classes on your elements.
Classes should be descriptive of content, not their presentation.
Have to touch the HTML to affect the website's presentation.
I'd recommend against using this.
You can combine them.
<div class="center block red one_third">
...
</div>
So you can mix and match properties for elements that have similar properties.
Separation and consistency.
I prefer to have all CSS styles separated in a .css file, independent from the pages that they provide styles for, and this is a pattern I apply consistently.
It can get a bit messy when you start having a mixture of CSS specified in both .css files and as style attributes within pages.
Maintenance in future and ease to change/add.
After working on several large web applications, and seeing gigantic style sheets with no clear structure, I'd really love to know if people have found ways to keep their css clean for large and complicated web apps.
How do you move from a legacy, mess of css to cleaned up, nicely cascading, DRY stylesheets?
The app I'm currently working on has 12000 lines of css. It's grown to this size organically as early on there were no standards or review of the css, the only rule was to make the app match the design. Some of the problems we constantly have:
Conflicting styles: one developer adds a .header { font-weight: bold;} but .header was already used in other modules and shouldn't be bold in those.
Cascading problems: Foo widget has a .header but it also contains a list of Bar widgets with .header classes.
If we define .foo .header { ... } and .bar .header { ... } anything not explicitly overwritten in foo will show up in bar.
If we define .foo > .header and .bar > .header but later need to modify foo to wrap header in a div, our styles break.
Inheritance problems, we constantly redefine widget fonts to 11px/normal because some top container uses a 12px / 18 px line height.
Fighting against widget libraries, using libraries such as dojo/dijit or jquery ui that add tons of styles to be functional means that our code is littered with places where we have to override the library styles to get things looking just right. There are ~2000 lines of css just for tweaking the builtin dijit styles
We're at a point where we're thinking of implementing the following rules:
Namespace all new widget classes - if you have a widget foo all sub-classnames will be .foo_ so we get: .foo, .foo_header, .foo_content, .foo_footer. This makes our css essentially FLAT, but we see no other way to organize our code going forward without running into the legacy styles or the cascading problems I mentioned above.
Police generic styles - have a small handful of generic classes that are only to be applied in very specific situations. e.g. .editable - apply to portions of a sentence that should invoke an editor - should only contain text nodes.
Leverage css compiler mixins To avoid repeatedly defining the same styles in different widgets, define and use mixins. Although we worry the mixins will get out of control too.
How else can we move from css mess that constantly introduces regressions to something maintainable going forward.
We're using a style guide in the form of a simple HTML page with examples of every CSS rule in the stylesheet. It's very easy to tell if you add a new, incompatible rule since the examples are aligned on top of eachother.
An example I like: http://getbootstrap.com/components/ (added 2015)
The other pro you get from this method is reusability: you know what you got and you know that you want the style guide to be as small as possible - therefore: reuse.
When you make changes to styles already in use: check the style guide. If it doesn't change it's probably good (you might need to browse around a bit if you've just changed something including box model-issues, or width, height, padding, margin in general).
How do you move from a legacy, mess of
css to cleaned up, nicely cascading,
DRY stylesheets?
Use the style guide as a unit test. Once you got the essential parts in it: reduce, refactor and combine (you most probably will find some collissions between .campaign_1 span and your regular rules, inheritance can be your friend).
Conflicting styles: one developer adds
a .header { font-weight: bold;} but
.header was already used in other
modules and shouldn't be bold in
those.
In reply to Adriano Varoli Piazza's comment and the quote above: I don't recall this as a problem fully belonging to the CSS but more to the HTML markup. No matter what you do, it will be some heavy lifting. Decide which rule you'd want to keep and take actions towards cleaning out the lesser-used-ones; for example: via inheritance: #news a .header { ... } or renaming the HTML-class a .stand_out_header { ... }.
About the following idea
Namespace all new widget classes - if
you have a widget foo all
sub-classnames will be .foo_ so we
get: .foo, .foo_header, .foo_content,
.foo_footer. This makes our css
essentially FLAT, but we see no other
way to organize our code going forward
without running into the legacy styles
or the cascading problems I mentioned
above.
Use a containing element instead, which will be much more easy to maintain:
<div id="widget_email">
<h2>One type of h2</h2>
</div>
<div id="widget_twitter">
<h2>Another h2</h2>
</div>
I find that the method for "namespacing" and limiting conflict in CSS is separate into different includes what you want to apply, so each page calls only what it needs. Conflicting rules can then be made more specific simply by defining them in a more particular include:
general css for all pages
css for pages in section A
css for pages in section B
So if you find a .header modification you added in the general css works in A but doesn't in B, you simply move it to the lower CSS file.
Yes, this implies more files to load. There are ways around it with server-side languages, like reading all files with php and sending only one block of content.
Quite often when I design a website for a customer, I design his website with one (or multiple) CSS files that makes up the entire presentation layer. The thing is, usually, the customer's needs change drastically in terms of "website theming". He may end up asking to change from a blue/green color-based theme to a red/orange based one according to his tastes. The thing is, my file contains all the information including:
the positioning of elements
the background images of containers
the font size, color
What are the best practices for "decoupling" a CSS file to make it "theme" aware, while maintaining all its information on positioning?
My list of possible practices are as follow:
Use a default CSS file containing generic information and positioning, use child CSS files that implement only the background images, font-sizes and colors
Name your first CSS file (say here the blue/green one will be named "sky"). Implement another theme based on sky, overriding any CSS attributes needed to change the theme and name it (red/orange would be "crimson" for example).
EDIT: according to the great answers provided below, I updated the list of other possible solutions adding up to my list:
Use SASS, (best authored with Compass #see Andrew Vit) specifically their "Mixins" feature. It takes CSS and introduces a very DRY programmatic approach. You can override existing classes with it. -treefrog
Use an OOCSS approach. -Andrew Vit
A technique called independent blocks (article in Russian) that mimics a sort of namespacing using class prefix to seperate specific blocks. -angryobject
Three based stylesheets. Separating typography, position, and the reset stylesheet provided by Eric Meyer. -David Thomas
Use already standardized approaches used by known organisations such as the Dojo library, jQuery UI, etc.
-S .Jones
Which would be better in which possible case? Are there any other easily maintainable and flexible ways?
Best answer to date: Using SASS to make very flexible stylesheets. Of course this implies the slight learning curve, but according to a few reviews, SASS seems to be the next approach for dynamic stylesheets (along with HAML).
You should look into SASS, specifically their "Mixins" feature. It takes CSS and introduces a very DRY programmatic approach. You can override existing classes with it, making it perfect for what I think you're trying to do.
Link
Consider the approach suggested by OOCSS. The general idea is to separate the style concerns of your classes into more granular units, so that you end up using more classes in your markup instead of hanging all of your styling on too few classes with overlapping concerns.
This can be combined with some of the other suggestions. (I highly recommend authoring SASS with Compass!)
In situations where a theme is required I, personally, tend to use three base-stylesheets:
A reset stylesheet (typically Eric Meyer's)
A stylesheet for positioning of elements (margins, paddings, floats, etc)
Typography and colours
There is an awful lot of repetition in this approach, though, so #treefrog's answer may well be a better approach. The one saving grace I can offer for my approach, which is why it works well for me, is that it's easy to know where to go to change the title font from Arial to Times New Roman (or whatever), and where to find the background-colours for the page. Typically these are stored in a Wordpress-like arrangement:
http://www.example.com/css/reset.css
http://www.example.com/css/themeName/typography.css
http://www.example.com/css/themeName/layout.css
I know about a techniques based on using so-called independent blocks. A block here is a part of the page that can be described by its own layout and its own styles. There are some principles of that techniques like using only class attribute, not id; each block has a prefix; no styles outside blocks or minimum global styles. But those are optional more or less. Suppose you have a block:
<div class="b-my-block">
<span>some more content</span>
</div>
And a style for that block:
.b-my-block{
width:100%;
height:300px;
}
.b-my-block span{
background:red;
}
'b' here is the prefix for the block. You can have different prefixes for you needs. You may want to use prefix 'g' for some global classes that can be applied to and modify any other elements.
Then, if you want to extend this block or change it somehow, you can create a modification of this block with a class 'b-my-block_blue' for example:
<div class="b-my-block b-my-block_blue">
<span>some more content</span>
</div>
and a piece of css:
.b-my-block_blue span{
background:blue;
}
This a very very rude example. And i'm not sure if i was explanatory enough. But i'm trying to use this technique in my current project and it feels pretty good so far. There is an article on this in russian. Maybe someone could translate it in english, if it has some interest for the people here.
Good Question. +1
I think for simpler layouts, where you can get away with theme changes based only on colors defined within CSS, then it makes sense to separate your CSS files into a core 'structural' file and several themed versions.
For more complicated themes, where images are imported as key parts of the layout or theme, it's better to completely nest your resources under a theme. You can see examples of this by exploring the directory structures of Javascript packages like Dojo that allow you switch between multiple themes. If you look through "Tundra" or "Soria" directory structures within the Dijit library, you'll see which 'best practices' they employed in dividing up their CSS files.
This question is about an approach to css structuring, and so is more discussion oriented.
I'm working with some outsourced css where the body tags have multiple classes assigned, up to half a dozen. (To make things a little worse, none of the css selectors include an html tag which is making it confusing to analyze the css.) These body classes are then used to modify classed or id'd widgets within.
It seems like this approach is like adding an additional dimension to the css, perhaps in some attempt to create a structured css approach. Documentation might have helped, had we been provided any.
This differs from my approach where widgets are styled primarily via id'd divs, perhaps extracting the more generic elements into a class, i.e. div#MyWidget.widgets.
Any ideas on whether such an approach is maintainable, especially considering I am dealing with websites with thousands of pages including tons of legacy stuff, all done by different people with different skill levels? Thanks...
I find nothing particularly wrong with this approach, provided you are conceptually using the body tags to apply very general style rules. The higher up the class is in the DOM, the more generic it should be.
It's hard to answer specifically without examples. One I frequently use is to turn the URL segments into classes for body tag in my pages, for relatively small sites:
// mysite.com/users/show/
<body class="users show">
<div id="Content">
...
</div>
</body>
I use this almost exclusively for overriding default styles on very specific pages:
#Content {
width:500px;
}
.users.show #Content {
width:600px;
}