Your privacy matters: This site uses cookies to analyze site usage and provide social media features. Learn More.

Can We Fix CSS?

August 09, 2016 in JavaScript Articles

Written by Chris Minnick


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

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.

webpage example

CSS Libraries and Frameworks

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.

Is there a better way to style web applications?

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.

JavaScript and CSS

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 for groups and instructor-led online JavaScript classes for individuals.


Written by Chris Minnick

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.


Contact Us:

Accelebrate’s training classes are available for private groups of 3 or more people at your site or online anywhere worldwide.

Don't settle for a "one size fits all" public class! Have Accelebrate deliver exactly the training you want, privately at your site or online, for less than the cost of a public class.

For pricing and to learn more, please contact us.

Contact Us

Toll-free in US/Canada:
877 849 1850
International:
+1 678 648 3113

Toll-free in US/Canada:
866 566 1228
International:
+1 404 420 2491

925B Peachtree Street, NE
PMB 378
Atlanta, GA 30309-3918
USA

Subscribe to our Newsletter:

Never miss the latest news and information from Accelebrate:

Microsoft Partner

Please see our complete list of
Microsoft Official Courses

Recent Training Locations

Alabama

Huntsville

Montgomery

Birmingham

Alaska

Anchorage

Arizona

Phoenix

Tucson

Arkansas

Fayetteville

Little Rock

California

San Francisco

Oakland

San Jose

Orange County

Los Angeles

Sacramento

San Diego

Colorado

Denver

Boulder

Colorado Springs

Connecticut

Hartford

DC

Washington

Florida

Fort Lauderdale

Miami

Jacksonville

Orlando

Saint Petersburg

Tampa

Georgia

Atlanta

Augusta

Savannah

Idaho

Boise

Illinois

Chicago

Indiana

Indianapolis

Iowa

Ceder Rapids

Des Moines

Kansas

Wichita

Kentucky

Lexington

Louisville

Louisiana

Banton Rouge

New Orleans

Maine

Portland

Maryland

Annapolis

Baltimore

Hagerstown

Frederick

Massachusetts

Springfield

Boston

Cambridge

Michigan

Ann Arbor

Detroit

Grand Rapids

Minnesota

Saint Paul

Minneapolis

Mississippi

Jackson

Missouri

Kansas City

St. Louis

Nebraska

Lincoln

Omaha

Nevada

Reno

Las Vegas

New Jersey

Princeton

New Mexico

Albuquerque

New York

Buffalo

Albany

White Plains

New York City

North Carolina

Charlotte

Durham

Raleigh

Ohio

Canton

Akron

Cincinnati

Cleveland

Columbus

Dayton

Oklahoma

Tulsa

Oklahoma City

Oregon

Portland

Pennsylvania

Pittsburgh

Philadelphia

Rhode Island

Providence

South Carolina

Columbia

Charleston

Spartanburg

Greenville

Tennessee

Memphis

Nashville

Knoxville

Texas

Dallas

El Paso

Houston

San Antonio

Austin

Utah

Salt Lake City

Virginia

Richmond

Alexandria

Arlington

Washington

Tacoma

Seattle

West Virginia

Charleston

Wisconsin

Madison

Milwaukee

Alberta

Edmonton

Calgary

British Columbia

Vancouver

Nova Scotia

Halifax

Ontario

Ottawa

Toronto

Quebec

Montreal

Puerto Rico

San Juan

© 2013-2019 Accelebrate, Inc. All Rights Reserved. All trademarks are owned by their respective owners.