Skip to content

A CSS framework add-on to Bootstrap

RS

RS is a CSS add-on for building websites using Bootstrap as the grid framework. It contains reusable classes that help standardize the building and styling of a website and takes advantage of Bootstrap's existing classes, grid and utilities. RS is a working project and receives updates regularly. See release notes for more information. Note: RS is fully compatible across all modern browsers and devices.

Normalization

Before creating new classes, RS takes normalization a step further and adds standardization for semantically correct and ADA compliant HTML.

  • Commonly interactive elements have a transition applied by default.
  • Scrollbars are hidden by default and the page is set to scroll-behavior: smooth.
  • The :focus style is changed to a dashed outline in a brand color.
  • The "Skip to Content" link is styled by default using .skip-to-content which is added as the first direct child of the <header> and linked to <main id="content">.
  • The <body> is styled so that the <footer> will always be at the bottom of the viewport if the content is not long enough to reach the bottom naturally.
  • Images within <header>, <main> and <footer> will be forced to be 100% width of their container.
  • All common HTML elements that would contain text (paragraphs, headers, lists, etc.) are set with margin-bottom: 0; if they are the last child. This makes sure all sections are exactly the height they are intended to be and consistent spacing is maintained.
  • <form> elements are set to appearance: none; and cleared of all borders and backgrounds. All form field :placeholder attributes have been set to 100% opacity.

Variables

RS takes advantage of CSS variables for flexible and resuable styling. Below is a list of the variables and how they are used.

Icons

RS comes with a small package of preloaded commonly used icons.

  • Arrows (down, left, right, up)
  • Chevrons (down, left, right, up)
  • Social (Facebook, Instagram, LinkedIn, Pinterest, TikTok, Twitter, Vimeo, Youtube)

The icon font is created using IcoMoon. If more icons need to be added you can upload /assets/css/icons/selections.json to IcoMoon and add icons to the existing set.

Icon Classes

Icons can be added inline to elements by using classes. The class .icon changes the font of the :before pseudo class to the icon font and a second class calls the icon to be displayed.

<a href="https://www.facebook.com/" target="_blank" class="icon facebook"></a>

If you added icons to the font in IcoMoon they need to be assigned as both new variables and classes. IcoMoon has a code value for each icon which is used to set the icon variable. like --facebook: "\e904". Once the variable is set the class needs to be created:

:root {
	--facebook: "\e904";
}
.icon.facebook {
	content: var(--facebook);
}

Brand Settings

Variables should be created for your brand's global styles, fonts, colors, etc. By setting these values as variables it reduces the chance of misspellings or other inconsistencies by defining the value in a single location. Below are the brand variables for this site.

:root {
	/* - - Fonts - - */
	--museo: Museo, Helvetica, Arial, sans-serif;
	--sans: Museo Sans, Helvetica, Arial, sans-serif;

	--weight-normal: 300;
	--weight-bold: 700;

	--font-scale: 1.125;
	--font-factor: 1;
	--font-size: 1rem;

	/* - - Colors - - */
	--black: oklch(from #171717 l c h / a);

	--white: oklch(from #FFFFFF l c h / a);

	--grey-lt: oklch(from #F4F4F4 l c h / a);

	--grey-dk: oklch(from #747474 l c h / a);

	--orange: oklch(from #E36F1E l c h / a);

	--orange-dk: oklch(from #C6470A l c h / a);

	--gradient: linear-gradient(90deg, var(--orange) 0%, var(--orange-dk) 100%);

	/* - - Global Assignments - - */
	--navbar-toggler: var(--black);
	--navbar-accent: var(--orange);

	--placeholder: var(--black);

	--focus: var(--orange);

	--list-color: var(--orange);

	--skip-background: var(--white);
	--skip-border: var(--orange);
	--skip-color: var(--orange);

	--selection-background: var(--orange);
	--selection-color: var(--orange);

	--body-color: var(--black);
	--body-font: var(--sans);
	--body-weight: var(--weight-normal);

	--heading-color: var(--black);
	--heading-font: var(--museo);
	--heading-weight: var(--weight-bold);

	--transition: .25s all;
}

Colors

Colors are defined using OKLCH which uses the Oklab color space for more vibrant colors. Additionally OKLCH has built in functions for manipulating your colors. The main use for the oklch() function is to adjust the alpha (opacity) value of the color.

Below is an example of setting one <p> color to var(--black) and adjusting the alpha of the second by using the oklch() function.

p:first-child {
	color: var(--black);
}

p:last-child {
	color: oklch(from var(--black) l c h / 50%);
}

The color of this text is equal to the var(--black) variable.

The color of this text is equal to the var(--black) variable at 50% opacity.

Assignments

After defining the brand variables you can use them to assign values to other features of RS.

  • --navbar variables define the color of the mobile menu icon by default and when expanded.
  • --placeholder sets the color of form placeholder text.
  • --focus is the outline color when an interactive element is in a focused state.
  • --list-color defines the default color of the base list style markers.
  • --skip variables style the "Skip to Content" button.
  • --selection variables set the background color and text color when text is highlighted.
  • --body variables are the base values of body copy.
  • --heading variables are the base values of headers.
  • --transition defines the default transition style and length.

Font Scaling

The body and heading font sizes are set using a scale to create consistent size ratios. By using a scale, the relative font sizes of heading elements can be adjusted in a single place.

:root {
	--font-factor: 1;
	--font-scale: 1.5;
	--font-size: 1rem;
}

body {
	font-size: var(--font-size);
}

h1, .h1,
h2, .h2,
h3, .h3,
h4, .h4,
h5, .h5,
h6, .h6 {
	font-size: calc(var(--font-size) * pow(var(--font-scale), var(--font-factor)));
}

h1, .h1 {
	--font-factor: 6;
}

h2, .h2 {
	--font-factor: 5;
}

h3, .h3 {
	--font-factor: 4;
}

h4, .h4 {
	--font-factor: 3;
}

h5, .h5 {
	--font-factor: 2;
}

h6, .h6 {
	--font-factor: 1;
}

By default, the <body> font size is set to 1rem using var(--font-size). The var(--font-factor) starts at 1. To set your scaling ratio, assign the value to var(--font-scale).

<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5>Heading 5</h5>
<h6>Heading 6</h6>
<p>Paragraph</p>

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Paragraph

Once all the variables are set, the heading sizes can be calculated. Each heading size is equal to the base font size multiplied by the font scale to the power of the var(--font-factor).

As an example of how the math works, the sizing for <h5> has been broken out below:

/* Original calculation */
var(--font-size) * pow(var(--font-scale), var(--font-factor)) = 2.25rem

/* Replacing variables for their values and converting the function to math equation */
1rem * 1.5^2 = 2.25rem

/* Expanding out the factor of the scale */
(1rem * 1.5) * 1.5 = 2.25rem

Spacing

The variable --gutter is used as the space between stacked columns on smaller devices.

The variables --spacer and --subspacer are reusable measurements used for spacing between .section elements and add padding to .section elements with backgrounds by adding the class .wrapper. In addition there are negative versions of these variables as well. Note: This is set to different values at different breakpoints making it responsive and scalable.

--content-margin sets the margin-bottom of all content elements like p, ul, ol, and img within a content block while --heading-margin sets that value for all heading elements.

--align-items, --justify-content, --row-x and --row-y overwrite Bootstrap's default column spacing. This is so the variables can be controlled at a broader specificity level.

:root {
	--gutter: 2rem;
	--negative-gutter: calc(var(--gutter) * -1);

	--spacer: 4rem;
	--negative-spacer: calc(var(--spacer) * -1);

	--subspacer: calc(var(--spacer) / 2);
	--negative-subspacer: calc(var(--subspacer) * -1);

	--content-margin: 1.5rem;
	--heading-margin: 1rem;

	--align-items: normal;
	--justify-content: normal;
	--row-x: 1.5rem;
	--row-y: 0;
}
@media (min-width: 768px) {
	:root {
		--spacer: 5rem;
	}
}
@media (min-width: 992px) {
	:root {
		--spacer: 6rem;
	}
}

Header and Footer

In some instances the header and/or footer element sizes are used in the CSS (Ex: Padding top of <main> to offset a fixed header). These values can be set as variable as well.

:root {
	--header: 3rem;
	--scroll-header: 3rem;
	--footer: 3rem;
}

Existing Variables

RS comes with default values of all the above variables but also includes variables based off Bootstrap's grid that can be used when styling sections of your website.

:root {
	--col-1: 8.3333333333%;
	--col-2: 16.6666666667%;
	--col-3: 25%;
	--col-4: 33.3333333333%;
	--col-5: 41.6666666667%;
	--col-6: 50%;
	--col-7: 58.3333333333%;
	--col-8: 66.6666666667%;
	--col-9: 75%;
	--col-10: 83.3333333333%;
	--col-11: 91.6666666667%;

	--container-col-1: calc(var(--container-width) * (1 / 12));
	--container-col-2: calc(var(--container-width) * (2 / 12));
	--container-col-3: calc(var(--container-width) * (3 / 12));
	--container-col-4: calc(var(--container-width) * (4 / 12));
	--container-col-5: calc(var(--container-width) * (5 / 12));
	--container-col-6: calc(var(--container-width) * (6 / 12));
	--container-col-7: calc(var(--container-width) * (7 / 12));
	--container-col-8: calc(var(--container-width) * (8 / 12));
	--container-col-9: calc(var(--container-width) * (9 / 12));
	--container-col-10: calc(var(--container-width) * (10 / 12));
	--container-col-11: calc(var(--container-width) * (11 / 12));

	--container-width: 100%;
	--container-padding: 2rem;

	--page-gutters: calc(100vw - (var(--container-padding) * 2));
	--single-gutter: var(--container-padding);
	--padded-gutter: var(--container-padding);
}
@media (min-width: 576px) {
	:root {
		--single-gutter: calc(var(--page-gutters) / 2);
		--padded-gutter: calc(var(--single-gutter) + var(--container-padding));
	}
}
  • --col-# is equal to the raw percentage of a column value relative to the page width based on Bootstrap's 12 column grid. This resolves as a percentage.
  • --container-col-# calculates the column value relative to the --container-width. This resolves as a pixel value.
  • --container-width is set at each breakpoint to the values of Bootstrap's .container.
  • --container-padding is exactly the same as Bootstraps standard padding except on mobile where the value is increased for a larger margin on small screens.
  • --page-gutters is the space on the page outside the container (left and right).
  • --single-gutter is the space outside the container on one side (left or right).
  • --padded-gutter is equal to --single-gutter plus --container-padding. This is used for absolute positioning of elements to maintain alignment with relative elements inside the .container.

Variables in Use

After defining all your variables (across breakpoints as well) they can be set to the elements. By default .container is redefined using --container-padding and --container-width.

Sections & Wrappers

.section is used for breaking up sections of the website, most typically used on elements directly inside <main>, and adds margin-bottom: --spacer;.

.section {
	margin-bottom: var(--spacer);
}

.wrapper is used for sections that have a background to create equal padding at the top and bottom by using --spacer.

.wrapper {
	padding-bottom: var(--spacer);
	padding-top: var(--spacer);
}
<main id="content">
 <div class="section">
  This section has margin-bottom.
 </div>
 <div class="section wrapper">
  This section has padding and margin-bottom.
 </div>
 <div class="section wrapper">
  This section has padding and margin-bottom while being flush with the wrapper above.
 </div>
</main>
This section has margin-bottom.
This section has padding and margin-bottom.
This section has padding and margin-bottom while being flush with the wrapper above.

For use in modular code there are additional styles for .section and .wrapper to prevent unwanted spacing between elements. If elements with .section.wrapper are direct siblings, the subsequent .wrapper element will have margin removed from the top equal to the --spacer so the sections are flush.

Features

RS comes with various features that are commonly used when building and styling websites. All the features are optional to use and can be adjusted within the stylesheet if necessary.

Lazy Loading Images

For better page speed optimization RS includes Lazy Loading images. Lazy Loaded images are only loaded once they are needed on screen and defers loading for all offscreen images. This can be used by adding the class .lazy to either <img> elements or <div> elements to set the image source with the appropriate data- attribute. For <img> elements use data-src and for <div> elements use data-bg. By default, all elements with the class .lazy have been given the var(--transition) styles to make loading smoother visually.

<img alt="RS" class="lazy" data-src="assets/img/rs-color.svg">
RS
<div class="lazy" data-bg="assets/img/rs-color.svg">
  <p>This element has a lazy loaded background image.</p>
</div>

This element has a lazy loaded background image.

Responsive iFrames

RS has responsive <iframe> styles built in by default to match the aspect-ratio of YouTube videos. For elements that use a different aspect ratio, the aspect-ratio can be adjusted on that element.

iframe {
	aspect-ratio: 16 / 9;
	height: auto;
	position: relative;
	width: 100%;
}
<iframe width="560" height="315" src="https://rs.greaterthan.agency/assets/mp4/video.mp4" title="Video" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"></iframe>

Page Interaction Classes

RSdds classes to the <html> element when certain page interactions happen.

  • When the user opens the collapsed navigation the class .open-menu is added. When this class is added the page will be set to position: static; to prevent background scrolling when the navigation is open in the foreground.
  • When the user scrolls down farther than the height of the <header> the class .scroll is added. This can be used to style the static <header> when the user is scrolled on the page.

Hiding Sticky Navigation

By default, RS's <header> is set to position: static;. Adding the class .hideable to your <header> element will hide the <header> when the user scrolls down and reveal itself when the user scrolls up. Note: This is done by adding additional interactive classes of .up and .down in conjunction with .scroll for the users respective scroll direction.

<header class="hideable">
	...
</header>

Column & Row Add-ons

Inset

.inset[-xl|-xxl] adds one column of padding to each side of the container on large devices and up. Utilities of -xl or -xxl will remove the padding below the specified size.

<div class="wrapper">
 <div class="container inset">
  This container is inset.
 </div>
</div>
This container is inset.

List Columns

.two-col and .three-col are used most commonly on list elements to break into multiple columns on large devices and up

<ul class="two-col">
 <li>List Item 1</li>
 <li>List Item 2</li>
 <li>List Item 3</li>
 <li>List Item 4</li>
</ul>
  • List Item 1
  • List Item 2
  • List Item 3
  • List Item 4

Getting Started

After you have downloaded RS you can start updating the base styles and variables. RS comes with simple default styling for buttons (.btn), the <header>, mobile navigation and a placeholder <footer>. These elements should be updated at the start of each project along with your variables. Some variables may need to be updated after your project is built and styled like --header or --footer.

As you work with RS you will learn more ways to take advantage of the classes and utilities that are included.

Release Notes

RS will be updated as new techniques are learned, properties become fully compatible or as any other changes happen to the font-end development world.

  • 4.1.1

    Theme color change

  • 4.1.0

    Colors are now defined using oklch().

  • 4.0.2

    Default styling of ul and ol elements with the new variable --list-color.

  • 4.0.1

    Default styling added for navigation including dropdown menu styles.

  • 4.0.0

    Complete reorganization of RS files for more simplicity in use.

    RS now uses type scaling for headings.

  • 3.2.0

    Refactored to remove unnecessary styles.

    .row and the direct children now use overriding variables for spacing that can be controlled at a broader specificity level.

    Reorganization of template files.

  • 3.1.0

    New spacing variables --negative-spacer, --negative-subspacer, --negative-gutter added.

    New global variables added for more consistent styling of basic HTML elements.

    Updated transition properties on global elements.

    Reorganization of template files.

  • 3.0.11

    skip-to-content styles updated from id to class to accommodate multiple skip to links.

  • 3.0.10

    Added variable to define li chevron color.

    Added transition support for static button elements like div.btn.

  • 3.0.09

    [element]-margin variable added to define margin-bottom of content elements.

  • 3.0.08

    line-height: 1.5 added explicitly to p tags for ADA compliance.

  • 3.0.07

    Adjusted transition property values and header.

  • 3.0.06

    Adjusted transition property values.

  • 3.0.04

    Removed global ul and li styles and moved them to style.css with the other styles.

  • 3.0.04

    Fully optimized rs.min.css called into style.css as an @import to it's proper layer.

  • 3.0.03

    Fully optimized rs.min.css called into style.css as an @import to it's proper layer.

  • 3.0.02

    Reorganization of properties within editable and non editable sections.

  • 3.0.01

    Adjusted layers for better ease of use.

  • 3.0.0

    RS now uses CSS Layers for more precise control of styles.

  • 2.0.0

    1.6 Beta version is now the primary framework.

  • 1.0.6

    Added new variables and documentation. Beta version added with aspect-ratio, inset, :is(), and :where() which are supported on only the most up to date versions of Safari (16).

  • 1.0.5

    Updated to Bootstrap 5.2 and jQuery 3.6.1

  • 1.0.4

    aspect-ratio, :is(), and :where() added temporarily hidden until more versions of Safari support them.

    header has changed to use position: sticky;, eliminating the need for main to have padding-top: var(--header);.

    Color variables are now defined with RGB. Those RGB values are set to a final variable using the rgba() function for alpha (opacity) support.

  • 1.0.3

    aspect-ratio, :is(), and :where() added.

  • 1.0.2

    Documentation updates and tweaks to various classes.

  • 1.0.1

    Documentation added for features that were included but not mentioned (Lazy Load, Page Interaction Classes, Hideable Navigation, etc.)

  • 1.0.0

    Official release

Coming Soon

Here you can keep up to date with what new features will be coming to RS in the future.

  • padding-inline, padding-block and writing-mode.