This question likely has no single direct answer, but hopefully will lead to some best practices or common patterns to use when adapting an existing styles framework to new web component development.
For my case, I have a component <custom-avatar>, and it's all set up properly with self-contained styles and functionality, everything is just peachy.
In certain use cases, the application display needs to stack avatars, just one slightly overtop one other at a diagonal, and the pattern I'm following is using a simple component <custom-composite-avatar>. All this does is wrap the slotted content in a <div> with the correct styling class, but key aspect is retaining the composability for flexible re-use, like so:
<custom-composite-avatar>
<custom-avatar title="first"></custom-avatar>
<custom-avatar title="second"></custom-avatar>
</custom-composite-avatar>
The tricky bit lies in the styles, which are imported from a monorepo that provides the same BEM-ish CSS and component CSS modules to other flavors of the component library like React, Vue, etc. I have the avatar and composite-avatar styles imported just fine, but forcing the intended overlap display is defined with the hierarchical selector .my-composite-avatar.my-composite-avatar--medium .my-avatar {}
So with .my-composite-avatar class applied to the div wrapper within <custom-composite-avatar> and the .my-avatar class applied to the wrapper within the <custom-avatar> and it's own Shadow DOM, that parent/child CSS selector is no good.
I doubt there is a silver bullet for this, but this seems like it will be a rather common scenario as more people migrate to Web Components while using existing styling systems. What approach makes the most sense to ensure that the composite component remains composable, and adaptation of existing selectors pain-free (or at least easy to communicate to other devs)? can this be solved with ::host or ::slotted, or will these cases require significant re-work?
Thanks for reading, your ideas are appreciated!
I would advice to become good friends with CSS properties
because they trickle down into shadowDOMs following CSS selectors.
CSS Custom Properties(variables)
and getPropertyValue
and setProperty if you want to be brutal and make Custom Elements change the outside world.
example
I have an <SVG-ICON> element taking configuration from attributes OR CSS properties
with my favorite lines of code:
let val = this.getAttribute(attr)
||
getComputedStyle(this)
.getPropertyValue("--svg-icon-" + attr)
.replace(/"/g, "")
.trim();
Allows for your standard attribute configuration:
<svg-icon name="configuration" fill="grey"></svg-icon>
But more powerful (simplified example):
<style>
body {
--svg-icon-fill: "grey";
}
svg-icon[selected] {
--svg-icon-fill: "green";
}
</style>
<svg-icon name="messages" selected></svg-icon>
<svg-icon name="configuration"></svg-icon>
CSS = Custom String Scripting
It doesn't often happen, but sometimes the simplest code makes me very happy.
There is no Styling restriction!
These 2 lines allow any String you want in CSS properties:
.replace(/"/g, "")
.trim();
Example
<style>
[name*="globe"] {
--svg-icon-tile: "rect:0,0,24,24,0,fill='blue'";
--svg-icon-stroke: white;
}
</style>
<svg-icon name="feather-icons-globe"></svg-icon>
The --svg-icon-tile has nothing to do with CSS, it is read (and parsed) by the <SVG-ICON> connectedCallback() code to generate a SVG background/tile for all icons named globe.
The double-quotes aren't required, but without them your IDE will complain about invalid CSS.
Have fun coding... you will pull some hairs when you start with calc() in your CSS properties...
But you can take 'CSS' to another level.
PS.
And monitor the future of ConstructAble StyleSheets aka ConstructIble StyleSheets aka Constructed Sheets aka AdoptedStyleSheets:
https://developers.google.com/web/updates/2019/02/constructable-stylesheets
https://chromestatus.com/feature/5394843094220800
iconmeister
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
Is there a way to create a css group inside of a css selector.
Eg:
.SectionHeader
{
include: .foo;
include: .bar;
include: .baz .theta .gamma .alpha .omega .pi .phi;
}
Trying to see if there is a way to do this at the CSS level instead of inside of a class=".foo .bar .baz .theta .gamma .alpha .omega .pi .phi" tag. I have to use the combination of classes in a few places and want to avoid all that cut and paste.
No, you can't do this in pure CSS as things stand.
There are some moves afoot to extend CSS to allow things like this, but it's very early days Google has some demonstrated some extended syntax working in a dev version of Chrome, but it'll be a while before it goes live, and even longer before it has sufficient cross-browser support to be actually useful.
In the meanwhile though, there are a number of CSS extension products available which allow you to write stylesheets with nested rules, etc. You would then need to run your stylesheets through a parser to convert them into "real" CSS before you put them on your site, but it might be a compromise you're prepared to make.
If so, check out SASS and Less, among others.
[EDIT]
By the way, I mentioned that Google have been demonstrating some extended CSS syntax. Here's a link to a blog post about it: http://www.xanthir.com/blog/b49w0
No, but as you stated you can assign multiple classes to an element:
<div class="SectionHeader foo bar"></div>
So far, my experience in web design has been with very small scale sites and blogs (where there isn't much diversity in page styling). However, I am now beginning to tackle some significantly larger scale web sites and I want to start off on the right foot by creating a scalable and maintainable css file / structure.
Currently, my method for applying styles to web pages is to give every web page a distinct ID in the body, and then when I'm designing a page my css rule will look like this:
body#news section .top { rules }
Surely there is a more maintainable approach to applying CSS for a large-scale web site?
Avoid giving each page a body tag with a unique ID. Why? Because if a page needs to be styled uniquely, it should have its own stylesheet.
I will often have a main.css stylesheet, stylesheets for various similar portions of my website (like an administration.css for an admin section, assuming the pages in the admin section shared a similar look and feel), and then give certain unique pages their own stylesheets (like signup.css).
I then include the stylesheets in order from least-to-most specific, because if two otherwise-identical rules are encountered, the rule in the most "recently" included stylesheet will be used.
For example, if my main.css had:
a { color: red; }
... and for some reason, I wanted my signup page to have blue links:
a { color: blue; }
The second rule will overwrite the first if my signup.css were included after main.css.
<link rel="stylesheet" href="/stylesheets/main.css">
<link rel="stylesheet" href="/stylesheets/signup.css">
there is a very informative and detailed answer over here: Managing CSS Explosion
you could also check out object oriented css: http://www.slideshare.net/stubbornella/object-oriented-css
or css systems: http://www.slideshare.net/nataliedowne/css-systems-presentation
To sum up the above answers and give some additional comments:
You put everything in one CSS, and use unique body IDs for page-specific settings. This approach speeds up your site because you're saving HTTP requests (browser caches just one file)
You have one CSS per page, plus one global one to take care of global settings, header, footer and any other elements that appear everywhere. This is friendlier if you have more than one developer working - less chance of conflicts because of updates to the same file. Even if you use a versioning system like SVN (and with a big site you should), it's always safer to have different files.
You can have the best of both worlds by separating into files, and then using a minifier to merge and compress all of them into one "compiled" CSS. This is more complicated, you need to fit it into your workflow, and it makes frontend debugging harder. See Any recommendations for a CSS minifier?.
What you should find is that most pages will have similar design aspects like typography and basic formatting which means you dont need to apply and id to the body tag.
You should try and use ids that describe the structure of your page (header, footer, sidebar etc) which can be reused on each page where neccessary. Only when styling areas specific to news or project etc is when you should start using id=news.
At the end of the day there is no right and wrong answer. Just try to maintain resuable css styles whilst trying not to overload your markup with uneccessary tags.
Always use classes for CSS. This will allow you to reuse more of your code. Since you can have multiple duplicate classes per page this allows you to really create some small code.
CSS parses from right to left. So in the example above it will find your selector in this order:
elements with the classname .top
elements with the classname .top that are in the section tag
elements with the classname .top that are in a section tag also contained in the #news element
...etc.
Look at it this way you should really try to keep your selectors as short as possible. Create a base style for .top, then if you need to write something custom for the #news section you can use #news .top.
Always try to use the shortest possible rules.
margin:0 5px;
over
margin:0 5px 0 5px;
It's basic, but you'd be amazed at how many people don't do this.
Also learn what you can shorted:
ex: font:bold 12px Helvetica, Arial, sans-serif;
One thing that is very helpful is if you alphabetize your rules. Especially if you are using CSS3 -webkit- and -moz- properties. I get a lot of push back on this one, but I work with 12+ developers and I've seen
.myClass { color:#f00; /* more stuff */ color:#fff; }
If they are alphabetical then you'll avoid code duplication.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
We have a large ASP.Net website that has a single css stylesheet which is getting out of control.
I am thinking of using the following strategy (taken from http://www.techrepublic.com/article/developing-a-css-strategy/5437796/) which seems logical to me...
you might have one CSS file devoted to sitewide styles and separate CSS files for identifiable subsets of site pages (such as pages for a specific department or pages with a different layout style). For styles that are unique to a specific page, use a separate CSS file for each page (if there are too many styles to fit comfortably in the document header). You link or import the appropriate CSS files for each page, so that you load all the styles needed to display that page, but very few unnecessary styles that only appear on other pages.
Is this a good way to proceed? What are the alternatives?
I think the best option is to divide css in:
-layout.css
-content.css
Then if you need other more specific you can add more like an css for the ads: ads.css, or one css for a specific section.
I would also add ie.css for IE css hacks.
I would not speak about creating one css for only one page: the problem you can have if you use too many css, is that your page will have to do more requests to the server and this will slow your page.
This is why i recommend you to implement an HttpHandler which will create a cache copy in only one file of the css you need at the moment. Look here:
http://blog.madskristensen.dk/post/Combine-multiple-stylesheets-at-runtime.aspx
There are three principle methods used for breaking up stylesheets: property-based, structure-based, and hybrid. Which method you choose should most be based on workflow and personal preference.
Property-Based
The most basic, representative form of a property-based breakup would be to use two stylesheets: structure.css and style.css. The structure.css file would contain rules that only used properties like height, width, margin, padding, float, position, etc. This would effectively contain the "building blocks" necessary to arrange the elements of the page the way you want. The style.css file would contain rules with properties like background, font, color, text-decoration, etc. This effectively acts as a skin for the structure created in the other stylesheet.
Additional separation might include using a typography.css file, where you'd place all of your font properties. Or a colors.css file, where you'd place all of your color and background properties. Try not to go overboard because this method quickly becomes more trouble than it's worth.
Structure-Based
The structure-based method of breaking up stylesheets revolves around segregating rules based on what elements to which they apply. For example, you might see a masthead.css file for everything in the header, a body.css file for everything in the content area of the page, a sidebar.css file for everything in the sidebar, and a footer.css file for everything at the bottom of the page.
This method really helps when you have a site with lots of distinct sections on each page. It also helps minimize the number of rules found in each stylesheet. Unlike the property-based method, which tends to have a rule in each stylesheet for each element on the page, with this method you only have one rule in one stylesheet for any given element.
Hybrid
As you might expect, the hybrid method combines the best of both methods and it's my preferred choice. Here you create a structure.css file, just like in the property-based method, using only those properties that you need to create the basic layout. Then you create additional stylesheets like masthead.css, which skins the header; body.css, which skins the content; etc.
Other Considerations
One problem that plagues each of these methods is that by creating multiple stylesheets, you require that the client's browser fetches many files. This can have a negative effect on the user experience because most browsers will only make two concurrent requests to the same server. If you have seven stylesheets, that means adding potentially hundreds of milliseconds on the initial page load (this effect is lessened once the stylesheets have been cached, but you want to make a good first impression on those new visitors). It's for this reason that the CSS sprites technique was created. Breaking up your stylesheets may wipe out any gains made by using sprites.
The way around this is to compress your broken-up stylesheets back into one stylesheet when the user makes a page request.
To get the best of both worlds, consider using a CSS meta-language like Sass. This allows a CSS author to break one stylesheet into many while still only presenting one stylesheet to the browser. This adds a step to the CSS authoring workflow (though it could potentially be scripted to compile the Sass into CSS any time a Sass file is updated), but it can be worthwhile, especially when considering some of Sass' many other benefits.
What you can do is have lots of easy to manage, separate files for development, then smoosh them all together into one file and minify it on your live site.
This is a little more work to set up, but gives you the best of both worlds - easy to manage site + fast page loads.
Edit: Yahoo's YUI compressor seems to be the best minifier around. It can compress both CSS and Javascript.
My solution, amidst plenty:
base.css / reset.css: your foundation {base layout, type, color} -- 100% reusability
helper.css: basic layout rules for modules as well as 'utility classes' {grid variations, forms, tables, etc} -- 90+% reusability
module.css: complex layout rules for modules {semantic modules like .post or .comment} - 75% reusability
layout.css: template-based rules {#hd, #bd, #ft, #homePage, etc.}- almost no reusability
color.css: all color rules, combined - 50% reusability
type.css: all type rules, combined - 75% reusability (text styling has less variations)
this separation also allows mobile and print versions for the layout sheets, all controlled by #import via the stylesheet I link to the html.
I am using this for a medium-sized site. For extra organization, I keep each sheet sectioned basically the same {wrapper, general, unique, etc}. I also tag my selectors and properties, as well as indent them in order of dependency inside the same selector group, so I know what rules I am referencing or extending. This framework allows nearly infinite expansion while keeping things organized, understandable, and reusable. I've had to refactor a 7000+ line master.css file a month ago, so this is a new system I am trying out. I've found that 100% content-semantic CSS isn't as scalable and easy to understand as a semantic/layout hybrid, since that's what CSS is used for anyway.
1.25-yr-later-edit: Another method which might be more relevant is to just use a good CSS text editor. I'm positive VS is crap for working with CSS, unless you happen upon some extensions. If you're on windows, give E Text Editor a shot, b/c it's a TextMate Windows port and has bundles designed for CSS and markup that give you much better syntax highlighting and autocompletion. What you then can do is organize, even a 8000-line stylesheet, into collapsible folds:
/** Start Module 1 */
[css]
/* End Module 1 **/
And use the symbol list to display for you a quick TOC on the fly with a query like Start or Module 1 It also indexes lines with /** these types of comments **/ (great for tagging areas) and all CSS selector chains. You should have no trouble working with single big files with E. Besides, unless you're progressively enhancing your CSS it's all going to get minified anyway. I would also make sure to indent your CSS to somewhat mimic the structure of DOM section it is referring to.
.container {}
.container .inner {}
.container .head {}
.container .inner.alt {}
Otherwise, I agree with the '1 Base CSS and 1 Page/Section CSS` method, though it entirely depends on your business requirements.
I would check out YUI CSS. Maybe not the answer you were looking for, but YUI CSS removes much of the hassle with different browsers etc...
Work out some simple rules that work for you (or your company).
Divide your CSS into separate files, such as:
layout.css
content.css
menu.css
typography.css
Decide what declarations will go in each file, for example, ensure:
font-weight, text-decoration, font-family
and
h1, h2, h3, h4, h5, h6, a, p, li
All reside in the typography CSS file. Decide what to do for edge cases, such as border properties on headers, padding and margins on text elemants (layout or typography).
If your sets of declarations are getting unwieldy, some people like to organise them alphabetically.
Indent your css, for example:
#logo h1 {text-indent: -9999px}
#logo h1 a {display: block; width: 200px; height: 98px; backround...}
Comment your CSS, including references to other files if other rule for that specific selector reside there.
If you do divide you CSS into separate files, consider consolidating and compressing them into one file as part of your build & deployment process.
Make sure every developer is well aware of your standard for CSS.
Also, somewhat relevant, I've just been made aware of a Firefox plugin for finding unnecessary selectors. It's called Dust-Me Selectors.
netadictos makes some good points and I would concur. It's easy to seek reasons for more Css but the benefits of keeping them lean are far greater in the longer term.
In addition, have you looked at using themes and skin files within asp.net? The combination of .css and .skin can dramatically reduce the overall size of your Css, which is marginally good for performance but very good for easier administration.
Some exceptions could be contained within the one css file but if things are radically different within the one then you may consider a separate css or even a separate site if they are that different. Obviously you might load different versions of the themes depending on which user it is. This is where you could have an explosion of Css files. That is, say you had a css for each page and then you wanted to have different for different clients on your site, then you'd be growing exponentially. This of course assumes you have this challenge.
I wonder the same thing with regards to JavaScript files. If your site is highly dependent on Ajax to the point where almost every page requires some kind of custom Javascript then were do you stick it all?
Best practices oftern spout not having javascript in the page but as external files (as with css). But if you have a .js file per page then things will slowly get out of hand.
I'm not sure about Windows equivalents, but on the Mac you can get CSSEdit, which allows you to add folders to CSS files and manage them like that. There's a good explanation of it in this article.
Global css files have caused me headaches before. CSS usually isn't namespaced, so if two different modules create a div with a class of "box", then the intent of one overwrites the other. Also, styles on the [a] tag, [p] tag and other basic tags (ie. styles not based on classes or id's) will wreck havoc on 3rd party controls as your global style sheet cascades onto an html component that was designed assuming no other css on the page. Inappropriate usage of text centering to center elements can lead to hard to debug global centering. So I favor multiple css files. I've seen css managers (http modules that merge css together at request time), but decided the extra http requests is well worth limiting the scope of the damage ill considered css can do to my application.
We use Ruby on Rails so we have a clear controller/action pair, we use this to reference both CSS classes and Javascript views.
Specifically, grab the name of the controller+action name and embed this as a ID in the view, put it on the body tag or your main content div.
<body id="users_list_body">
Where "users" is the name of the controller, "list" is the action. Then in your CSS you have rules likes
#users_list_body
So you can scope all of your specific CSS to that view. Of course, you also have more general CSS to handle overall styling. But having this ID defined more easily allows you to create specific CSS for individual pages (since a controller/action maps to a specific page).
You end up having rules like this
#users_list_body table
#users_list_body table thead
Do the same for Javascript. So in the footer of every page you take your same controller/action name pair and embed it in a function call
//javascript
if(V.views.users_list) { V.views.user_list(); }
Then in your external Javascript you have something like
V = {};
V.views = {};
V.views.user_list = function() {
//any code you want to run for the Users controller / List action..
//jQuery or something
$('#save_button').click({ ... });
}
with all of your Javascript code scoped to a specific function, it ends up being all encapsulated. You can then combine all of your Javascript files into one, compress it and then serve it up as one file and none of your logic will conflict. One page's JS will not conflict with any other page's JS because each page is scoped by its method name.
Whatever your choice is, avoid using the #import directive.
Makes the browser load stylesheets sequentially, hence slowing down loading and rendering for your page.
Here is what I do: I keep my stylesheets separate, somewhat along the lines of what others have suggested. However, I have a script that concatenates them together, minifies them, adds the headers, and then gzips them. The resulting file is then used as the stylesheet and if it goes beyond the expiration date, it automatically recompiles. I do this on a sitewide basis for all the common files and then also on a page specific basis for CSS that will only appear on that page. At the most, I will only ever have 2 CSS files called per page and they will be compressed, which minimizes download time and size and the number of page requests, but I will still have the benefit of separating them in whatever way makes sense to me. The same strategy can also be used for JavaScript.