CSS will have its 20th anniversary as a W3C Recommendation later this year. During those 20 years, CSS has evolved from a single, fairly simple specification into a giant (and growing) collection of modules at different levels of standardization, as well as different levels of support in different browsers. The fundamental syntax of CSS hasn’t changed in those 20 years, although we have gained more ways to select elements and the number of CSS properties has grown from the original 53 to over 250.
Managing and organizing CSS has always been an issue. The fact is, no one expected that stylesheets would get as big as they are now (I’ve seen stylesheets that are 50,000 lines long!), and no one expected that so much CSS would continue to be written by hand.
CSS preprocessors were created to help make writing CSS less painful and to give it some sort of semblance of being a manageable technology. The most widely used preprocessor is Sass. Sass gives us the ability to write stylesheets in a more programmatic way, and then compile them to basic CSS. However, even with preprocessors, CSS continues to be problematic due to its global nature, the preponderance of selectors that are often poorly used, and no agreed upon methodologies for how to structure or organize CSS files.
Several patterns have been proposed over the years for how to organize CSS files including OOCSS, BEM, and SMACSS. However, none of these are perfect for every project, and CSS guidelines and usage vary greatly from organization to organization and from developer to developer, even in the best case scenarios.
What nearly everyone agrees upon is that developers should impose some sort of modularity onto CSS during development. Knowing, for example, that you’ll find styles related to font sizes and styles in the _typography.scss file is far better than browsing through thousands of lines of CSS to find the right spot and then debugging to figure out why your change didn’t have the intended effect.
However, even with a perfect and well-documented system for modularizing your CSS, you still have to contend with the fact that all CSS is global and that the order of CSS rules matters. Furthermore, it’s nearly impossible to get around the fact that once all of your CSS is compiled and minified into a single file, that file is going to contain far more CSS rule sets than any one page of your site needs, as well as a ton of duplication. CSS, when used as designed, forces you to violate the DRY (don’t repeat yourself) principle and there’s nothing you can do about it. Modern browsers will cache your CSS, of course, but downloading thousands of lines of CSS to display an entry page that only requires a small fraction of those is sub-optimal.
As a randomly chosen example, the whitehouse.gov homepage loads over 160k of compressed CSS, 92% of which isn’t used on the homepage.
CSS libraries and frameworks, such as the omnipresent Bootstrap, bring some order to the chaos. With a well-written and well-known library, you can manage layout and basic styling of a web app or web site and not worry that applying a certain class in one spot is going to have a different effect than if you apply it somewhere else.
That is, of course, until you decide to modify or override Bootstrap styles to fit your particular needs and site. The minute you start overriding Bootstrap styles, all of the same old CSS style management problems come back.
Facebook proposed one particularly bold solution as part of their ReactJS library. Because of the way React renders HTML pages from a collection of independent JavaScript modules, Facebook recommended that module styling be done using JavaScript applied directly to elements, rather than through the use of CSS selectors.
As unorthodox as this solution is, it does actually make sense. If your goal is to build your application from predictable components, then encapsulating the functionality, structure, and style into those modules is the only way to be sure that they’ll always render the same way when given the same data as input. Using inline style for components is the only way to make them truly portable as well.
React uses the DOM style object to manipulate element styles, as shown in the following code:
var headerStyle = { fontSize: '36px', fontFamily: 'sans-serif', color: 'blue' }; ReactDOM.render(<h1 style={headerStyle}>Welcome!</h1>, mountNode);
Can this strategy of doing all styling with JavaScript be applied outside of React?
If it can, the entire mess of CSS global scope and selector misuse can be completely eliminated — along with the need to learn, use, and maintain CSS preprocessors. With JavaScript styling, instead of having a global rule for how to style an h1 element, for example, and then overriding that later on in the stylesheet with a more specific selector, you could do something like the following:
function element (name,style,content){ return '<'+name+' style="'+style+'">'+content+'</'+name+'>'; } var headerH1Style = 'color:red;font-size:24px;'; var headerDivStyle = 'width:100%; text-align:center;'; var pageHeader = element('div',headerDivStyle, element('h1',headerH1Style,'Welcome!'));
Of course, this is an extremely simplistic example. But, if you flesh this out and work on creating a system of building style and HTML using JavaScript, you’ll end up with a dumbed-down version of React.
From a styling perspective, the benefits of building and styling web UIs using only JavaScript is that it gives you control over your CSS scope and you get all the benefits of a CSS preprocessor. Plus, JavaScript-styled web content is completely dynamic whereas Sass variables, function, and mixins get compiled to static CSS.
One possible objection to this approach to style is that today’s browsers are highly optimized for compiling, rendering, and drawing CSS. Using JavaScript to render styles may not be as efficient as using a stylesheet.
Another objection is that JavaScript styling requires knowledge of JavaScript. Since JavaScript is usually prerequisite for having a job as a front-end developer, this argument seems less important to me than the potential performance issue.
To long-time web developers, who were indoctrinated with the basic rules that style, content, and functionality should be kept strictly separate, styling with JavaScript is heresy. We were taught that the proper way to apply styles is through taking advantage of CSS cascading and selectors. Applying styles directly to elements using JavaScript violates this principle.
For now, the approach that I prefer is to use a known framework, such as Bootstrap, for global layout and styling. Inside of components that are meant to be reusable, however, I lean heavily towards using inline styles for local CSS.
Author: Chris Minnick, one of Accelebrate’s instructors.
Accelebrate offers private training in JavaScript, CSS, and React.js.
Written by Chris Minnick
Chris has authored and co-authored over a dozen books including titles in the For Dummies series, as well as several books teaching kids to code. Chris specializes in JavaScript technologies and writes and maintains courseware that’s used for training software developers at some of the largest companies in the world.
Our live, instructor-led lectures are far more effective than pre-recorded classes
If your team is not 100% satisfied with your training, we do what's necessary to make it right
Whether you are at home or in the office, we make learning interactive and engaging
We accept check, ACH/EFT, major credit cards, and most purchase orders
Alabama
Birmingham
Huntsville
Montgomery
Alaska
Anchorage
Arizona
Phoenix
Tucson
Arkansas
Fayetteville
Little Rock
California
Los Angeles
Oakland
Orange County
Sacramento
San Diego
San Francisco
San Jose
Colorado
Boulder
Colorado Springs
Denver
Connecticut
Hartford
DC
Washington
Florida
Fort Lauderdale
Jacksonville
Miami
Orlando
Tampa
Georgia
Atlanta
Augusta
Savannah
Hawaii
Honolulu
Idaho
Boise
Illinois
Chicago
Indiana
Indianapolis
Iowa
Cedar Rapids
Des Moines
Kansas
Wichita
Kentucky
Lexington
Louisville
Louisiana
New Orleans
Maine
Portland
Maryland
Annapolis
Baltimore
Frederick
Hagerstown
Massachusetts
Boston
Cambridge
Springfield
Michigan
Ann Arbor
Detroit
Grand Rapids
Minnesota
Minneapolis
Saint Paul
Mississippi
Jackson
Missouri
Kansas City
St. Louis
Nebraska
Lincoln
Omaha
Nevada
Las Vegas
Reno
New Jersey
Princeton
New Mexico
Albuquerque
New York
Albany
Buffalo
New York City
White Plains
North Carolina
Charlotte
Durham
Raleigh
Ohio
Akron
Canton
Cincinnati
Cleveland
Columbus
Dayton
Oklahoma
Oklahoma City
Tulsa
Oregon
Portland
Pennsylvania
Philadelphia
Pittsburgh
Rhode Island
Providence
South Carolina
Charleston
Columbia
Greenville
Tennessee
Knoxville
Memphis
Nashville
Texas
Austin
Dallas
El Paso
Houston
San Antonio
Utah
Salt Lake City
Virginia
Alexandria
Arlington
Norfolk
Richmond
Washington
Seattle
Tacoma
West Virginia
Charleston
Wisconsin
Madison
Milwaukee
Alberta
Calgary
Edmonton
British Columbia
Vancouver
Manitoba
Winnipeg
Nova Scotia
Halifax
Ontario
Ottawa
Toronto
Quebec
Montreal
Puerto Rico
San Juan