18 January 2023
CATEGORY
WebDev
TAGS
WebDevJavaScriptCSS

CSS LayoutMode

Responsive CSS made easy

Introduction

CSS is hard. Well, actually, what I meant was that real-world CSS is hard. It's not hard because the syntax is difficult or because of a lack of documentation. In fact, there are countless resources on all aspects of CSS. What makes real-world CSS hard is the "C" in CSS - the cascade. To be clear, the cascade part is what makes CSS so flexible and powerful, but it also makes it difficult to manage when a project grows larger. On top of that, we have to deal with multiple modes such as media types and screen sizes.

LayoutMode

LayoutMode(LM) allows CSS rules to be organized into modes which are in turn controlled by media queries. In the nutshell, LM decouples media queries and the CSS rules. With LM, media queries can be created to select named modes. The modes are then translated to classes of the body element. The actual style CSS rules can then be tied to the modes of the body.

Before

{MediaQuery} ==> {CSS rules}

With LayoutMode

{MediaQuery} ==> {modes (body.mode-XXX)} ==> {CSS rules}

As the mode appears the class on the body element, you can use that as a qualifier to style anything under body ... and that is everything.

You can also have multiple mode at the same time as they are independent. For example, you may have 'compact' and 'spacious' for different resoluation and also have 'normal-contrast' and 'high-contrast' for font size and color scheme. Then at one time, the mode might be ['spacious', 'high-contrast'].

DEMO

Try the above out here Live demo on jsFiddle

How to use

First you need to include the library to your page. See below for CDN or NPM options.

Initiate the modes using the name you think reperesenting the look you want and it can be use in both conversation and code.

<script src='layout-mode.min.js'>
...
var layoutMode = LayoutMode.init(['mobile', 'desktop', 'ie'])

You can specify the default mode (the mode that is not subject to any media query) using ...

body > .css-layout-mode-selector > div.mode-mobile {
    display: block;
}

The following code will cause the mode to change to desktop mode when the width is 800px or wider

@media(min-width: 800px) {
    body > .css-layout-mode-selector > div.mode-mobile { display: none; }
    body > .css-layout-mode-selector > div.mode-desktop { display: block; }
}

That is when the page is 800px or narrower the body element will have 'mode-mobile' class and it will have 'mode-desktop' class when the page is wider than 800px.

Why use LayoutMode

Mode names represent intentions

Each mode has a name associated with it. This is far different from having to interpret the media queries and the CSS rules. The team members can use the name to communication. The names such as 'mobile', 'desktop', 'reader' modes directly communicate what sort of look you are trying to achieve.

Jack: Jill, I think the header text has too much padding on my phone, can you fix that.

Jill: One second.

body.mode-mobile h1 {
    padding: 0px;
}

Jill: Done!

Current Mode

You can check exactly what the current mode is.

Adam: Why?! Why the menu bar still appear, the screen is very narrow already. It should change to hidden by now with this width.

Ben: Why don't you check what is the current mode is.

Adam: Right, let me open the developer tool

console.log(layoutMode.currentModes())

Adam: Umm. It is the right mode. Why the menu is not ... Oh wait .. I spell 'position' wrong on this rule.

With one more line of code, you can also tell LayoutMode to display the current mode.

<link rel="stylesheet" type="text/css" href="layout-mode.min.css">

By default, with the above mode, the current mode name is shown on the left-buttom corner of the screen.

Notify when mode change

You can ask LayoutMode to notify when the mode has changed. This is useful if you need to programmatically do something when mode change from one to another.

layoutMode.watch(function(modes) {
    console.log(modes)
})

Decouple MediaQuery and CSS Rules

Putting the mode in between, the media queries decoupled from the rules. That means you do not need to make the media to fit the query to see the effect of the rules. You can ask LayoutMode to change the mode programmatically.

layoutMode.changeModes(['compact'])

with above mode, media queries are detached from the modes and only response to programatically change of modes. To re-attach the media query to the mode, use clearModes.

layoutMode.clearModes()

Separation of works

A team member can be given responsibility to ensure the proper media queries for selecting modes. Other team members can also work independently on different modes. With the names clearly spell out on the rules, it is harder to step on each other's toes. You can even go further and separate css files for each modes.

Interested?

Use it with NPM simply with:
npm install layoutmode
Or use it with directly CDN links:

Minified

Non-Minified

Happy coding!
Nawa Man


Links

GitHub

https://github.com/NawaMan/LayoutMode

GitHub Page

https://nawaman.github.io/LayoutMode/

NPM page

https://www.npmjs.com/package/layoutmode

DEMO

https://jsfiddle.net/gb7ymq8x/2/

Comments

Thank you for keeping the comment section positive, constructive and respectful environment. I do appreciate constructive criticism & respectful disagreement! I have ZERO tolerant for disrespect, harassment, threats, cyber-bullying, racism, sexism attacks, foul language, and spam. Comments will be actively moderated and abusive users will be blocked. Keep it civil! :-)