In my head, I've always known to use classes over inline styles for any project. But are there any effective differences between the two?
First of all:
If the HTML is built or generated independent of the overall site design (e.g. shared template code), then add reasonably-named classes and IDs, linked exclusively to external stylesheet(s). Use sufficient elements to allow for arbitrary CSS manipulation. For example, see the CSS Zen Garden. This applies to ALL CMSes, programs, scripts, and other dynamically-generated site content. The HTML output must contain absolutely no styling or layout of any sort at all. No exceptions.
Assuming you're dealing with static content, then:
If there's any way you can reuse the style, make it a class and link to a stylesheet.
If there's no way would ever reuse the style (it's a one-off thing that doesn't make sense anywhere else) then use a <style> block that references the element's #id.
If the CSS attribute only makes sense in the context of the surrounding HTML (e.g. some usages of clear:) then I inline the style into the element.
A lot of people call this heresy, just like a lot of people denounce any use of goto in modern programming languages.
However, rather than subscribing to stylistic dogma, my view is you should choose the method based on your circumstances that decreases your overall workload the most. Stylesheets add a level of indirection that makes site-level changes easy and helps build consistency. But if you have several dozen classes on each page that are only used in one place, then you're actually increasing your workload, not decreasing it.
In other words, don't do something dumb and confusing just because people tell you it's the right way to do it.
There is a simple reason. The point of CSS is to separate the content (HTML) from the presentation (CSS). It's all about accessibility and code reuse.
If the choice was there, my first preference will be classes/other selectors. However, there are situations where inline styles are the only way to go. In other situations, just a CSS class by itself requires too much work, and other types of CSS selectors make more sense there.
Suppose you had to zebra stripe a given list or table. Instead of applying a particular class to each alternate element or row, you could simply use selectors to do the job. That will keep the code simple, but it won't be using CSS classes. To illustrate the three ways:
Using only class
.alternate {
background-color: #CCC;
}
<ul>
<li>first</li>
<li class="alternate">second</li>
<li>third</li>
<li class="alternate">fourth</li>
</ul>
Using class + structural selectors
.striped :nth-child(2n) {
background-color: #CCC;
}
<ul class="striped">
<li>first</li>
<li>second</li>
<li>third</li>
<li>fourth</li>
</ul>
Using inline styles
<ul>
<li>first</li>
<li style="background-color: #CCC">second</li>
<li>third</li>
<li style="background-color: #CCC">fourth</li>
</ul>
The second way looks the most portable and encapsulated to me. To add or remove stripes from any given container element, simply add or remove the striped class.
However, there are cases where inline styles not only make sense, but are the only way to go. When the set of possible values is huge, it will be stupid to try to make classes in advance for each possible state. For example, a UI that allows the user to dynamically place certain items anywhere on the screen by dragging. The item will have to be positioned absolutely or relatively with actual coordinates such as:
<div style="position: absolute; top: 20px; left: 49px;">..</div>
Surely, we could use classes for each possible position the div can take, but that's not recommended. And one can easily see why:
.pos_20_49 {
top: 20px;
left: 49px;
}
.pos_20_50 {
top: 20px;
left: 50px;
}
// keep going for a million such classes if the container size is 1000x1000 px
<div class="pos_20_49">..</div>
Use common sense.
Everyone knows that presentation and content should, in an ideal world, be separated. Everyone also knows that this doesn't work very well a lot of the time. We all know that you're supposed to use divs rather than tables for layout, but we also know that for any circumstance where you don't have full control over the content it just doesn't work properly.
Downloading a 500k style sheet to style one element because you've taken every possible style and stuck it in a style sheet will kill your page, downloading 500 smaller style sheets to style your page because you need them all will also kill your page.
Reuse is great in concept, but the reality is that it's only useful in certain contexts. This applies equally to pretty much anywhere the concept exists. If your project does what you want it to do, does so in every reasonable browser, does so in an efficient way, and does so reliably, then you're good to go, it's not dramatically harder to refactor css than is is code.
I can't think of any pros for inline styles.
CSS is all about Progressive Enhancement, and not repeating yourself (DRY).
With stylesheets, Changing the look becomes as easy as changing one line in the HTML code. Make a mistake or the client doesn't like the change? revert to the old stylesheet.
Other advantages:
Your site can automagically adjust to different media, such as for printout and for hand-held devices.
Conditionally-included CSS fixes, for that gawd-awful browser-that-shall-not-be-named, become a snap.
Your users can easily customize the site with plugins like Stylish.
You can more easily reuse or share code from site to site.
I can think of only two situations where inline styles are appropriate and/or reasonable.
If inline styles are programmatically applied. For example, showing and hiding elements with JavaScript, or applying content specific styles when rendering a page (see #2).
If inline styles complete a class definition for a single element in cases where id's are neither appropriate or reasonable. For example, setting the background-image of a element for a single image in a gallery:
HTML
<div id="gallery">
<div class="image" style="background-image:url(...)">...</div>
<div class="image" style="background-image:url(...)">...</div>
<div class="image" style="background-image:url(...)">...</div>
</div>
CSS
#gallery .image {
background: none center center;
}
With the addition of Custom properties to CSS, now there's another use case. One might want to use inline style to set custom properties.
For e.g. below i am using CSS grid to align HTML Lists and Div blocks and i wish to have flexibility in the HTML (Just the way BootStrap or any other framework provides) as this HTML is dynamically generated by application.
CSS :
:root{
--grid-col : 12;
--grid-col-gap:1em;
--grid-row-gap:1em;
--grid-col-span:1;
--grid-row-span:1;
--grid-cell-bg:lightgray;
}
.grid{
display: grid;
grid-template-columns: repeat(var(--grid-col), 1fr);
column-gap: var(--grid-col-gap);
row-gap: var(--grid-row-gap);
}
.grid-item{
grid-column-end: span var(--grid-col-span);
grid-row-end: span var(--grid-row-span);
background: var(--grid-cell-bg);
}
HTML :
<ul class="grid" style="--grid-col:4">
<li class="grid-item">Item 1</li>
<li class="grid-item">Item 2</li>
<li class="grid-item">Item 3</li>
<li class="grid-item">Item 4</li>
<li class="grid-item">Item 5</li>
<li class="grid-item">Item 6</li>
<li class="grid-item">Item 7</li>
<li class="grid-item">Item 8</li>
</ul>
In the above HTML to change the four columns to 3 i change the custom property using style attribute :
<ul class="grid" style="--grid-col:3">
<li class="grid-item">Item 1</li>
<li class="grid-item">Item 2</li>
<li class="grid-item">Item 3</li>
<li class="grid-item">Item 4</li>
<li class="grid-item">Item 5</li>
<li class="grid-item">Item 6</li>
<li class="grid-item">Item 7</li>
<li class="grid-item">Item 8</li>
</ul>
You can check the extended live example at https://codepen.io/anon/pen/KJWoqw
Assuming that you are using external stylesheets, an additional benefit on top of those previously mentioned is caching. The browser will download and cache your stylesheet once, and then use the local copy each additional time it is referenced. This allows your markup to be more compact. Less markup to transfer and parse means a more responsive feel and better experience for your users.
Classes are the re-usable styles that can be added to HTML elements. e.g-
<style>
.blue-text{color:Blue;}
</style>
you can use and re-use this blue-text class to any HTML element
Note that in your CSS style element, classes should start with a period. In your HTML elements' class declarations, classes shouldn't start with a period.
whereas inline style are like e.g-
<p style="color:Blue;">---</p>
So the difference between both is you can re-use classes whereas you can't re-use inline styles.
Inline Styles are definitely the way to go. Just look at http://www.csszengarden.com/ - that would never have been possible with classes and external style sheets...
or wait...
Related
Lately, I have been using data attributes for layout. For example:
<section data-ui-panels="vertical open" data-ui-accordion="stacked" class="primary new-products">
<ul data-area="nav" class="ui-list">
<li>Option 1</li>
<li>Option 2</li>
</ul>
<div data-area="body" class="journals">
<div class="unit">
<p>This is my text</p>
</div>
</div>
</section>
Benefits
Code is more readable: I can more easily spot the layout elements in both HTML and CSS. Options for the layout don't have to be verbose (e.g. stacked instead of ui-accordion-stacked).
Easier styling: The layout classes might get overridden by other classes. Attributes always take priority over classes, so then don't get overridden. Many of these layout attributes work with Jquery, so Jquery doesn't get overridden by anything else.
Easier re-usability: I can re-use the code between projects, without having to worry about site-specific code overriding the layout.
Works on older browsers such as IE8.
Are there any drawbacks to doing this?
I found this article that suggests there might be performance issues, but in the values it provides, the data-attributes perform quicker, so I don't quite understand it.
Say I have the following DOM tree:
<div class="box">
<ul class="gallery">
<li id="1">text</li>
<li id="2">text</li>
<li id="3">text</li>
<li id="4">text</li>
<li id="5">text</li>
<li id="6">text</li>
<li id="7">text</li>
<li id="8">text</li>
<li id="9">text</li>
</ul>
<div id="random"></div>
<ul class="gallery">
<li id="10">text</li>
<li id="11">text</li>
<li id="12">text</li>
<li id="13">text</li>
<li id="14">text</li>
<li id="15">text</li>
<li id="16">text</li>
<li id="17">text</li>
<li id="18">text</li>
<li id="19">text</li>
<li id="20">text</li>
</ul>
</div>
I want to create a CSS selector that will pick every 6th <li> tag under the div with the class "box". But I need the selector to take into account the entire <li> tags in the page and not to count them per <ul> tag. So in the end, the selector should pick the <li> with IDs 6,12,18. Currently I was only able to create a selector that picks IDs 6 & 15 when I used:
div.box li:nth-of-type(6n)
Notice 1: the IDs numbers are only added for reference. In reality the <li> tags don't have a class or an ID.
Notice 2: the number of <li> tags in each <ul> tag varies from site section to site section. Sometimes there can be even a 3rd and a 4th </ul> with more <li> tags.
Notice 3: I don't have control over the hard-coded HTML, which means I cannot unify tags, add IDs or CSS classes, etc. The selector will be called from an external JS file. While I can edit the DOM with jQuery after the page loads, I prefer to avoid such a solution to make the selector easier to handle.
Thanks
Generally Agree Impossible, except...
I basically agree with Sych and FabrÃcio that it is not currently possible to do as a pure CSS solution. However, there are always some exceptions, depending on actual html structure.
In your case, there may be an exception, but it does depend on the full constraints of your situation.
When Would it Be Possible?
Based off your given code, if these two constraints are true, then you can still get what you want via CSS:
All ul items that are direct children of .box are of class .gallery.
All gallery groups (except perhaps the very last one) consist of exactly nine li elements (both groups in your example do, but I don't know if that was coincidence or how you are actually setting up your code).
If the above two factors in your html are true, then this code gets what you want (using color to show selection here):
ul.gallery:nth-of-type(2n+1) li:nth-of-type(6n) {
color: red;
}
ul.gallery:nth-of-type(2n+2) li:nth-of-type(6n+3) {
color: red;
}
You can see it works on the code you gave in this fiddle, then you can see it continues to work given an expansion of the html as this fiddle shows, even if the final list is short of nine as both this fiddle and this fiddle shows, but it will fail if the .gallery varies in length at some midpoint of the sequence, as seen in this fiddle (notice how the last two selected texts are not 6 apart from each other because the second to last .gallery has only 7 items).
The Overarching Principle
So in general, if your dynamic html is output in some type of a regular pattern as demonstrated here, then it can open up the possibility of a pure css solution along the lines of that given. It is when the dynamic generation is also fully random (so in your case if either #1 or #2 condition above is not guaranteed true) that a pure css solution is impossible.
CSS does not provide such scope, it only provides traversing "deeper in to the DOM" tree. It does not even have a parent element selector.
If you are in jQuery environment, you can write your own selector, call it, say, ":nth-from-top(n)" that will work using jQuery's DOM traversing functions.
Note, that this type of selector will be much slower, because it cannot take advantage of the performance boost provided by the native DOM methods.
nth-child and nth-of-type match based in the element's position relative to its siblings only.
As far as I know there's currently no CSS-only solution for that unless all lis had the same parent. You will have to add a class to every 6th element or use some JavaScript.
So, constraining the answer to CSS selectors only without altering the markup and without hardcoding the nth start indexes: impossible. I'd like to be proven wrong though.
Looking by the bright side, adding a class will provide better selector performance. nth-child is already considered inefficient, now if what you want would be possible it'd mean that browsers would be forced to recursively evaluate selectors and count matches each time the DOM is updated. Though this would be terrible performance wise, I believe it'd still be possible to implement through new "scoped" nth selectors a la CSS Counters. Just food for thought.
I'm following this tutorial here http://www.kriesi.at/archives/create-a-multilevel-dropdown-menu-with-css-and-improve-it-via-jquery on adding a menu with jquery.
I've created my menu, but I'm having trouble adding it to wordpress. I opened up the header.php file since I want it to appear below the banner, and I paste it in it's own div, but it always "pushes" everything below it to the right.
How do I stop it from doing this?
Here's the code:
<ul id="nav">
<li>1 HTML</li>
<li>2 CSS</li>
<li>3 Javascript
<ul>
<li>3.1 jQuery
<ul>
<li>3.1.1 Download</li>
<li>3.1.2 Tutorial</li>
</ul>
</li>
<li>3.2 Mootools</li>
<li>3.3 Prototype</li>
</ul>
</li>
Hard to say without looking at the whole, but based on knowing very little of your problem, the only thing I can recommend you to try is this CSS property:
ul#nav {
position: absolute;
}
This way, it will not push other elements away. It might have other consequences tough, depending on other elements you might have.
Looks like you're missing a closing </ul>? You can also use The W3C Markup Validation Service to tack down errant tags.
I have an unordered list I'm displaying horizontally as the page's top menubar. I've gotten it to display relatively well, although I've been playing with the spacing for IE6 and IE7 cause it's not displaying properly. Shocking. In either case, is it better to use a table to display the menu or use some CSS hacks, which I can't find a way around? What is the best way to display the menu? I should add some of the options have dropdown menus using their own unordered lists.
Check out List-a-matic, it has a host of different menu templates that you can use as a base.
A simple horizontal list can be displayed using css and an unordered list
HTML
<div id="navcontainer">
<ul id="navlist">
<li id="active">Item one</li>
<li>Item two</li>
<li>Item three</li>
<li>Item four</li>
<li>Item five</li>
</ul>
</div>
CSS
#navlist li
{
display: inline;
list-style-type: none;
padding-right: 20px;
}
It's hard to give a definitive answer without an SSCCE from your side (a plain <html> document including doctype and embedded styles) which reproduces exactly the problem you have. But I can at least tell that the common problem is that you didn't get the doctype right and that IE's boxmodel bug plays a role here.
If that's not the root cause, then the next possible cause is the fail in understanding how to use floats and/or inline/block elements. To get good and solid code examples to start with, Google "suckerfish menu".
EDIT:
You cant depend on display: inline-block to handle this because cross browser support is problematic. Use floats instead with dispaly: inline; position: relative.
I would continue on with the UL's. Dont use hacks for IE* though - use IE Conditionals to add different stylesheets for different versions of IE.
I have a menu that will be automatically created in an asp.net page. I'm trying to use a pure CSS cross browser menu but how can i set it so that each subsequent child is autohiden/shown w/o having to define the style for each level of the menu.
Is this the only way to accomplish this with css?
Essentially im looking for a way to use css to show/hide the child menu items w/o having to define the style for every level - especially since i dont know how many levels there will be.
you should be able to do it by only specifying down to the second level
<html>
<head>
<style>
.mnusub li ul{ display:none; }
.mnusub li:hover > ul{ display: block; }
</style>
</head>
<body>
<ul class="mnusub">
<li>test1
<ul class="mnusub">
<li>test2</li>
<li>test11
<ul class="mnusub">
<li>test3</li>
<li>test4</li>
<li>test5</li>
</ul>
</li>
</ul>
</li>
<li>test5
<ul class="mnusub">
<li>test6</li>
<li>test7</li>
<li>test8</li>
</ul>
</li>
<li>test9</li>
<li>test10</li>
</ul>
</body>
</html>
The key here is the ">" selector as it specifies direct descendants and not sub-descendants
enjoy
When you want to affect each child individually, but without having to make style rules for each of those children, then you need more logic, which CSS doesn't provide. You could use something like PHP for that logic, or you could go with Javascript/jQuery. In that case, you can toggle CSS classes on child[x] through jQuery, and you only need to style those classes. Then it wouldn't matter which child got the class, it would be styled accordingly. Note that you should first make sure your menu is at least usable without Javascript, so users aren't dependent upon it.