FOUC is a common user experience problem for sites with a lot of CSS (especially after you start combining your CSS files), and the common solution is to separate important layout rules in a small standalone file which is loaded first. That leads to code which is hard to read and maintain because related rules are at very distant places. I am wondering if there is any CSS preprocessor which supports separating code into different files? That is, you would write something like
.main-content { #FOUC
position: absolute;
top: 10px;
left: 15px;
}
.main-content h1 {
font-weight: bold;
}
and .main-content and .main-content h1 end up in different files. (Or maybe the same on a per-rule level.)
Related
At the moment, my usual approach to supporting right-to-left (RTL) languages in a template is to simply add a .rtl class to the body tag, then go through all my existing left-to-right CSS and add left/right overrides as appropriate.
For example, my site menu might be positioned like so by default as below:
.site-nav {
position: absolute;
left: 0;
top: 0;
}
...and then manually overridden for RTL languages this way (using some template logic at a CMS level to add the .rtl class to body):
.rtl .site-nav {
left: auto;
right: 0;
}
My issue is that this seems labour-intensive and not very effecient. I was wondering what solutions others might have come up with to make this simpler.
As an aside, I'm using a Compass environment to generate my CSS. But I don't know how to escape back from the current nesting to write a .rtl modifier adjacent to the current element's default styles. This in theory would be extremely useful, however, but I simply don't know if it's possible to perform a lookup all the way back to the body element or not whilst within a deeply-nested Sass rule.
Add your .rtl-class whereever you want to change the textflow. Even when you don't want to change it (for "normal" languages).
Don't use the class in your default css-file.
Add a css-file which only includes
.rtl {
left: auto;
right: 0;
}
whenever you have a rtl-language. In case you want all your divs to behave that you you could replace .rtl with div as well.
I've recently played around with CSS grids, including great frameworks like Susy (http://susy.oddbird.net/), Foundation (http://foundation.zurb.com/) & the semantic grid system (http://semantic.gs/).
They all share this option of "including" a grid mixin instead of specifying a html class e.g.
.some-div{
#include grid-column(4);
}
While this seems like a good semantic approach, i was wondering about the cost in terms of css weight, css logic and if it's really worth it just to be semantic?
What are the pros and cons of using a mixin grid vs html classes?
Why HTML/CSS semantics are important
There are some much articles on the web about this! Just google it and you'll find a lot of invaluable information.
Here's a good one: How Important Is Semantic HTML?
Semantic html is important because it’s:
Clean — It’s easier to read and edit, which saves time and money during maintenance, and you don't have to force all your users to download a bloated library of styles many of which are not even used on the website
More accessible — It can be better understood by a greater variety of devices. Those devices can then add their own style and presentation based on what’s best for the device. It's also more appropriate for JS frameworks.
Search engine friendly — This is still debatable as search engines rank content and not code, but search engines are making greater use of things like microformats to understand content.
The most important argument for me is that semantic approach is just... the right thing to do. Follow this methodology carefully and you'll have so less causes for regrets.
Why i don't agree with #Mohamad's answer
Google is a bad example
Google's approach to semantics is extremist and violates their own style guide so many times that it's ridiculous. Just have a look at the HTML code of Google search results or HTML and you'll feel sick. It is necessary to understand that Google is an ultra high load website and they trade everything in favor of milliseconds of loading.
CSS is bulky to work with, use SASS
The main Mohamad's argument is that semantic approach is difficult on large projects. In fact, that's only true for old school CSS.
Indeed, it is counter productive to use semantic style with pure CSS. The larger the project, the more effort it requires to go for semantic approach.
But there's SASS. Whoever has tried SASS, never returns to vanilla CSS. SASS offers an incredible lot of powerful improvements, some of which make coding semantically effortless.
SASS code is compiled into normal CSS code. The most important thing to understand about SASS is that you only have to care about the structure and readability of your SASS code. The resulting CSS code may be hard to read and contain duplicates, but it is not a problem because CSS is gzipped by server.
#extend
The most important SASS feature in concern of HTML/CSS semantics is the #extend directive. It allows you injecting a reusable block of styles into semantic selectors, while producing efficient CSS.
First, declare a block of styles to be reused, for example:
%glyph {
display: inline;
width: 16px;
height: 16px;
background-repeat: no-repeat; }
You can later include it into different selectors semantically:
.star {
#extend %glyph;
background-image: url('../images/star.png'); }
.extenral-link {
#extend %glyph;
background-image: url('../images/external-link.png'); }
The resulting CSS will be very efficient:
.star, .extenral-link {
display: inline;
width: 16px;
height: 16px;
background-repeat: no-repeat; }
.star {
background-image: url("../images/star.png"); }
.extenral-link {
background-image: url("../images/external-link.png"); }
#include
Unfortunately, you can't use the beautiful #extend feature within media queries. So if you do responsive design, you'll have to produce CSS code with duplicate fragments. As i said earlier, duplication in CSS is not a problem thanks to gzip, it's the cleanness of SASS that matters.
Mixins (#include) allow you to inject blocks of reusable styles into selectors. They are not grouped effectively, but they accept arguments and can produce varying styles for different semantic selectors:
#import 'singularitygs';
$breakpoint: 300px;
$grids: 2 3;
$grids: add-grid(6 at $breakpoint);
%column {
background-color: pink;
min-height: 5em;
margin-bottom: 1em;}
#welcome {
#extend %column;
#include grid-span(1, 1);
#include breakpoint($breakpoint) {
#include grid-span(2,1); }}
#product-features {
#extend %column;
#include grid-span(1, 2);
#include breakpoint($breakpoint) {
#include grid-span(2,3); }}
#description {
#extend %column;
clear: both;
#include breakpoint($breakpoint) {
#include grid-span(2,5); }}
Produces:
#welcome, #product-features, #description {
background-color: pink;
min-height: 5em;
margin-bottom: 1em;
}
#welcome {
width: 38.09524%;
float: left;
margin-right: -100%;
margin-left: 0%;
clear: none;
}
#media (min-width: 300px) {
#welcome {
width: 31.03448%;
float: left;
margin-right: -100%;
margin-left: 0%;
clear: none;
}
}
#product-features {
width: 57.14286%;
float: right;
margin-left: 0;
margin-right: 0;
clear: none;
}
#media (min-width: 300px) {
#product-features {
width: 31.03448%;
float: left;
margin-right: -100%;
margin-left: 34.48276%;
clear: none;
}
}
#description {
clear: both;
}
#media (min-width: 300px) {
#description {
width: 31.03448%;
float: right;
margin-left: 0;
margin-right: 0;
clear: none;
}
}
Demo: http://sassbin.com/gist/5883243/
Compass extensions
As you noticed above, i use a grid-span mixin that is not declared in code. That's because it comes from the awesome Singularity extension.
The ecosystem of numerous Compass extensions provides you a great set of tools for all needs: semantic grid systems, responsive design, colors, math, all kinds of styles... You don't have to reinvent a thousand of wheels for every project you build!
What to read about SASS
This is a great starting point for SASS newcomers: https://github.com/Snugug/training-glossary/wiki , created by Sam Richard aka Snugug.
I often feel that some advocates of semantic grids have never written complex applications. The answer, as ever, is the proverbial "depends."
It depends on your style, your team, and your application. In some projects that required modular design, being semantic required extra code and effort for very little return. In others, simpler ones, it was fine. Take a look at the CSS that Google uses. Not everyone is Google-size, but that illustrates my "depends" point.
The advent of HTML 5 has solved some of these problems with tags such as section, header, and article. I tend to use those semantically. But my CSS class names tend to describe abstract divisions of my design, not what the thing is specifically.
There are no straight answers, but careful not to waste too much time worrying about this stuff. It means very little if your application is late or does not make it out of the door.
Do what you and your team feel comfortable with.
I'm trying to override a particular widget's style using UiBinder. What am I overlooking?
<ui:style>
/*************
* Note #1
*************/
.btnVote {
display: inline-block;
width: 50px;
height: 50px;
background: #fff;
margin: 5px;
text-align: center;
outline: none;
cursor: pointer;
}
/*************
* Note #2
*************/
.btnVote-up-hovering, .btnVote-down-hovering {
background: #ddd;
}
.btnVote-up-disabled, .btnVote-down-disabled {
border-shadow: inset 0 1px 3px #aaa;
}
.lblName {
line-height: 50px;
font-size: 40px;
padding: 5px 10px;
}
.clear {
clear: both;
overflow: auto;
}
.floatLeft {
float: left;
}
</ui:style>
<g:HTMLPanel styleName="{style.clear}">
<g:FlowPanel styleName="{style.floatLeft}">
/*************
* Note #3
*************/
<g:PushButton ui:field="btnVoteUp" stylePrimaryName="{style.btnVote}">
(+)
</g:PushButton>
<g:PushButton ui:field="btnVoteDown" stylePrimaryName="{style.btnVote}">
(-)
</g:PushButton>
</g:FlowPanel>
<g:FlowPanel styleName="{style.floatLeft}">
<g:Label ui:field="lblName" stylePrimaryName="{style.lblName}"/>
</g:FlowPanel>
</g:HTMLPanel>
Note 1: This rule is being applied and works fine
Note 2: This other rules seem to be getting ignored (they don't take effect)
Note 3: The default naming for the widget is being reset, hence Note 1 works fine. The base class is set to GOGXR1SCFI instead of gwt-PushButton
Why aren't they other rules working? When I hover the widget, the class GOGXR1SCFI-up-hovering is indeed set to the widget, but no accompanying CSS.
Thanks for your help.
Update
Something I ran into that gave me a hard time for a while: when you use the #external keyword, you must place a semi-column at the end of the #external statement, as in:
<ui:style>
#external .btnVote;
.btnVote {
...
}
</ui:style>
<g:FlowPanel styleName="{style.btnVote}"/>
One thing you could do is to create your CSS using ClientBundle, define all the different states there, then handle the various states manually. This way you don't need to define classes as #external, and GWT will optimize the CSS for you (shorten the names, only ship what gets used, etc.). This is especially beneficial for custom widgets and such.
The easiest way to deal with this is to write #external .btnVote, .btnVote-up-hovering, .btnVote-down-hovering, .btnVote-up-disabled, .btnVote-down-disabled at the top of your <style> section.
The original GWT widgets do not work well with CSS resources (like the one you have in your UiBinder). They depend on a primary style name that they append things like "up-hovering" to. This is terrible for CSS resources and UiBinders because when you type "up-hovering" it becomes things like SDLFJKS.
The button styles do NOT get obfuscated (so you can read "up-hovering"). Your UiBinder styles DO get obfuscated. You can never make them match as long as obfuscation is going on.
So, the #external keyword tells UiBinder and CssResource not to obfuscate certain styles. Now, when you use {style.btnVote-up-hovering}, that will actually come through to the final HTML, which is where these old-fashioned GWT styles will be applied.
I suspect you have CSS stylenames being obfuscated by GWT in your UIBinder. Reference - garbled css name when styling within UiBinder
Chose the approach you find easier to integrate in your proces. Cheers :)
Is there any way that compass/sass can assist in minimizing the amount of duplicate css code when making your layout work both for rtl and ltr languages?
It seems that Bi-App-Sass does exactly what I was looking for:
usually when writing stylesheets for bi-directional sites/apps, both ltr & rtl stylesheets mostly will look the same, except for direction related properties (float, text-align, padding, margin ..etc ), so when you write a float: left in some ltr stylesheet, you'll have to write it again as float: right for the rtl one
when using bi-app-sass , all you have to do is to write your stylesheets once using a predefined mixins for those direction related properties, and once you compile your stylesheets, you'll have a ready two stylesheets for your bi-directional app
You could write a mixin utilizing the #content blocks feature of Sass 3.2.
Like so:
#mixin rtl {
[dir="rtl"] & {
#content;
}
}
.module {
float: left;
margin-left: 2em;
// Change directions and reverse the margin
#include rtl {
float: right;
margin-left: 0;
margin-right: 2em;
}
}
I've been educating myself. Reading this:
The engine evaluates each rule from right to left, starting from the rightmost selector (called the "key") and moving through each selector until it finds a match or discards the rule. (The "selector" is the document element to which the rule should apply.)
For example:
ul li a {...}
#footer h3 {...}
* html #atticPromo ul li a {...]
Now, some example code SASS outputs for me:
#content #blog {
/* ... */
}
/* line 85, ../sass/screen.scss */
#content #flickr {
/* ... */
}
#content #flickr div p {
/* ... */
}
This seems a bit awkward.. am I doing something wrong? Is this a communication problem between me and Sass? Are we losing it?
Edit:
Some SCSS code:
#flickr {
#include columns(5,8);
background: url('../img/ipadbg.png') no-repeat;
#ipod-gloss {
z-index: 999;
position: relative;
}
div {
margin-top: -80px;
margin-right: 20px;
h2 {
color: $white;
font-size: 24px;
}
p {
margin-top: 40px;
}
}
}
Side Bonus!: The article says browsers (or at least Firefox) search the selectors from right to left. I couldn't understand why this is a more efficient why. Any clues?
You have to find your compromise between maintainability (nesting makes it easier to find your way around in the stylesheet) and rendering performance.
A rule of thumb says you should try to restrict yourself to a three-level nesting and you should avoid to nest IDs if it's not necessary.
However, I think nesting too much is not the biggest issue. As soon as I became aware of the power of mixins, I used them a lot.
For example, this is my often used button mixin:
#mixin small-button($active-color: $active-color, $hover-color: $button-hover-color, $shadow: true)
display: inline-block
padding: 4px 10px
margin:
right: 10px
bottom: 10px
border: none
background-color: $button-color
color: $font-color-inv
+sans-serif-font(9px, 700)
text-align: center
text-transform: uppercase
cursor: pointer
#if $shadow
+light-shadow
&:hover
text-decoration: none
background-color: $hover-color
&:last-child
margin-right: 0
a
color: $font-color-inv
&, &:hover
text-decoration: none
&.disabled
+opacity(0.75)
&:hover
background-color: $button-color
&.active
background-color: $active-color
&.disabled:hover
background-color: $active-color
You see, quite a bit code. Applying such mixins to many elements on your page will result in a big CSS file which takes longer to be interpreted.
In the old fashioned CSS-way you would give each button element e.g. the class .small-button. But this method pollutes your markup with unsemantic classes.
Sass provides a solution though: selector inheritance via the #extend directive.
If you set defaults for your parameter of the mixin, you can also provide a simple class, which uses the mixins with your default:
// Use this mixin via #extend if you are fine with the parameter defaults
.small-button
+small-button
And then you can just inherit from this class in various contexts:
#admin-interface
input[type=submit]
#extend .small-button
The resulting CSS statement aggregates all usages of .small button into one rule with comma-separated selectors:
.small-button, #admin-interface input[type=submit] {
display: inline-block;
...
}
Concluding, a naive usage of Sass can effect your CSS performance. Used wisely, however, it is maintainable thanks to well-structured and DRY code, it leads to proper separation of markup and styling (semantic classes only) and allows for smart and performant CSS code.
SASS is only a language that compiles down to CSS. If you're concerned with SASS' performance in terms of how it runs in the browser, then SASS doesn't enter the equation -- it'll be compiled and served to the browser as regular CSS.
From what I can see of your usage of SASS, there's a couple of things I could suggest:
You don't have to nest everything.
The ability to nest rules inside each-other in SASS is a language feature, but you don't have to do it if it doesn't make sense to do so.
In terms of your general CSS usage:
If the nesting gets too severe/unwieldly, consider using classes where it makes sense.
When it's necessary to use the hierarchy of DOM elements, consider using the [child combinator]: .foo > .bar.
IDs are meant to be unique, thus should always only reference a single element. Most of the time, they can be CSS rules unto themselves -- #content #flickr would become just #flickr, for instance -- and browsers will optimise the lookup for a single ID. The only time you would need something like #id1 #id2 is if #id2 needs to appear in different contexts on different pages.
If your selector contains things like #id div p, that div is either superfluous or serving a specific purpose.
If it's superfluous, change the rule to #id p, which selects any <p> that occurs as a descendant of #id.
If it serves a specific purpose, consider classing the <div> with a class name that describes its purpose -- perhaps <div class="photos-list">. Then your CSS could become .photos-list p, which is far more maintainable and reusable.