A guide to using Primer.css
Tags: css, webdev
Published: 2023-03-09 14:25:28

**Written by [Onuorah Bonaventure](https://blog.logrocket.com/author/onuorahbonaventure/)✏️**

Primer.css is the internal framework that GitHub uses to handle styles and organize its CSS. The primary purpose of Primer.css is to enforce consistent styles across a website. In this article, we will learn about Primer.css, how to use it, and what it takes from BEM. We will begin by learning about what it comprises before we build a landing page and evaluate its resemblance to BEM. 

_Jump ahead:_

*   [Getting started with Primer.css](#getting-started-primer-css)
*   [The Primer.css key concepts](#primer-css-key-concepts)
    *   [Breakpoints and spacing](#breakpoints-spacing)
    *   [Theming](#theming)
*   [Understanding Primer.css utilities](#primer-css-utilities)
    *   [Padding](#padding)
    *   [Margins and typography](#margins-typography)
    *   [Text alignment and font utilities](#text-alignment-font)
    *   [Colors](#colors)
    *   [Borders](#borders)
    *   [Box shadows and flex](#box-shadows-flex)
*   [Exploring the Primer.css components](#primer-css-components)
    *   [`Buttons`](#buttons)
    *   [`Alerts`](#alerts)
    *   [`Box` and `loaders`](#box-loaders)
*   [Building a landing page with Primer.css](#building-landing-page-primer-css)
    *   [Adding a container](#adding-container)
    *   [Adding a `hero` section](#adding-hero-section)
    *   [Creating the sections](#creating-sections)
*   [What does Primer.css take from BEM?](#primer-css-bem)
    *   [How Primer.css is different](#primer-css)

## Getting started with Primer.css <a name="getting-started-primer-css">

We can install Primer.css via npm or Yarn by running `npm install @primer/css`. After that, set up [Sass](https://blog.logrocket.com/a-beginners-guide-to-programming-for-css-with-sass/) and import it into our main [SCSS](https://blog.logrocket.com/the-definitive-guide-to-scss/) file with the `@import "@primer/css/index.scss";` command. 

Similarly, you can download the minified version and host it in your code via [this link](https://unpkg.com/@primer/css@20.8.0/dist/primer.css). However, for this article, we will use the CDN version, so make sure to create a new folder named `primercss-cdn`. Then, create a new `index.html` file and add the following link to the `head` tag:

```html
<link href="https://unpkg.com/@primer/css@^20.2.4/dist/primer.css" rel="stylesheet" />
```

Your code should look similar to this:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      href="https://unpkg.com/@primer/css@^20.2.4/dist/primer.css"
      rel="stylesheet"
    />
    <title>Primer CSS cdn</title>
  </head>
  <body></body>
</html>
```

## The Primer.css key concepts <a name="primer-css-key-concepts">

Primer.css is a fantastic framework that has been divided into subsections covering utilities, components, and marketing styles. However, we need to understand how breakpoints, spacing, and theming work to get started with the subsections.

### Breakpoints and spacing <a name="breakpoints-spacing">

Like other [popular CSS frameworks](https://blog.logrocket.com/comparing-bootstrap-vs-tailwind-css-vs-material-ui-mui/) like Tailwind CSS, Primer.css uses four breakpoints that rely on a `min-width` property set in the media query. The breakpoints are `sm`, `md`, `lg` and `xl` which represents a minimum width of `544px`, `768px`, `1012px`, and `1280px`. 

To specify a breakpoint, you can use a syntax similar to setting the display on a small and medium screen. Primer.css uses a scale from `0-12` that represents values from `0` to `4px`, `8px`, `16px`, `24px`, `32px`, `40px`, `48px`, `64px`, `80px`, `96px`, `112px` and `128px`. To set spacing for an element, you can specify your desired axis like this: <`h2 class="px-1 py-1">Content</h2>`.

### Theming <a name="theming">

These days, users have a list of basically two preferences for [theming](https://blog.logrocket.com/a-guide-to-theming-in-css/). These preferences are light and dark modes. Primer.css has provided a set of data attributes that can be used to set the theme for your website. These data attributes are expected to be added to the <`html>` which is the root tag of the entire page. Here’s what they look like:

- Light theme:```html
 <html data-color-mode="light" data-light-theme="light">
<!-- Other tags go in here -->
</html>
```
- Dark theme: ```html
 <html data-color-mode="dark" data-dark-theme="dark">
<!-- Other tags go in here --> 
</html>
```
- Dark dimmed: ```html
 <html data-color-mode="dark" data-dark-theme="dark_dimmed">
<!-- Other tags go in here -->
</html>
```
- Dark high contrast: ```html
 <html data-color-mode="dark" data-dark-theme="dark_high_contrast">
<!-- Other tags go in here -->
</html>
```

## Understanding Primer.css utilities <a name="primer-css-utilities">

The Primer.css utility styles include [`colors`](https://blog.logrocket.com/advanced-guide-setting-colors-css/), [`box-shadows`](https://blog.logrocket.com/three-ways-style-css-box-shadow-effects/), and [CSS grids](https://blog.logrocket.com/css-grid-guide/) that are used most frequently in our code. Essentially, these styles help us maintain a more consistent style on our website. Primer.css has provided a set of utilities we can use, which we will discuss below.

### Padding <a name="padding">

Padding is used to specify the internal spacing of an element. Primer.css provides shorthands that can be used together to set padding. For instance, we can set the padding for all the sides of an element in combination with any of the spacing we discussed above like this: `p-2`. Similarly, we can set the padding for the left, right, top, bottom, vertical, and horizontal axes using the following class names: `pl-2`, `pr-2`, `pt-2`, `pb-2`, `py-2`, and `px-2`. 

Primer.css is focused on responsiveness, and staying in line with that goal, the Primer.css team has provided a set of classes for setting the padding for different screen sizes. All you have to do is to attach `sm`, `md`, `lg`, or `xl` to the padding. It should look similar to this: `p-sm-2 py-md-3 pt-lg-4`.

### Margins and typography <a name="margins-typography">

Generally, with margins, we can set the spacing between an element and another element. The class names look very similar to padding except for replacing `p` with `m`. Moreover, the class name `mx-auto` is used to center `block` elements only when they have a set width while `mb-auto`, `ml-auto`, `mr-auto` and `mt-auto` are used to move a `block` element to the top, right, left, and bottom. 

It is also important to note that we can set negative margins with class names similar to `mr-n6 m-n2 my-n9 my-md-n7`. The secret is to precede the letter spacing number with the letter `n`. 

Typography, in this case, includes the styles for setting text alignment, font size, line height, word break, list styles, typographic styles, and more. You can learn more about typography in Primer.css in the [official docs](https://primer.style/css/support/typography).

### Text alignment and font utilities <a name="text-alignment-font">

The text alignment utility can be used alight the right, center, or left of the text and images inside an element using the following styles: `text-right`, `text-center`, and `text-right` respectively. Heading and type scale utilities are used to specify the font size of a text or SVG. 

The heading utilities set the `font size` and the `font-weight` to match the default heading styles. These styles range from `h1` to `h6` with the former being the largest and the later the smallest:

```html
<p class="h4">I love primer.css</p>
```

The type scale only sets the font size and ranges from `f1` to `f6`. Here’s an example:

```html
<p class="f5">I love my Life</p>
```

### Colors <a name="colors">

Primer.css comes with 13 colors to choose from, including: `default`, `muted`, `subtle`, `accent`, `success`, `attention`, `severe`, `danger`, `open`, `closed`, `done`, `sponsors`, and `on`. 

The CSS classes for setting colors are broadly divided into four parts: `text`, `background`, `border`, and `link`. The class name for text color is written like this: `color-fg-danger`. Essentially, the last text can be any of the colors listed above, which includes `success`, `muted`, and more. 

To use the `on` text color, it should be written like this: `color-fg-on-emphasis`. The background color is similar to the text color, as `color-bg-subtle`. However, it has another deeper color set with `emphasis` attached to its class name. 

Meanwhile, the class name for setting border colors also resembles that of background colors with the following: `color-border-open`, `color-border-closed-emphasis`, and `color-border-sponsors`. 

However, `Links` are a little bit different. It can allow classes for `primary`, `secondary`, `muted`, and states such as `hover` and `nested`. The primary link can be written like this:

```html
<a class="Link--primary" href="/home">Link--primary</a>
```

While the secondary link can be written like this:

```html
<a class="Link--secondary" href="/home">Link--secondary</a>
```

Muted links can be indicated using the `Link--muted` class. The `on-hover` link class is used to make any text color used within the links to turn blue on hover. It can be used like this:

```html
<a class="color-fg-secondary no-underline" href="#url">
 This is a link <span class="Link--onHover">Link--onHover</span>
</a>
```

Finally, the nested link is used to show emphasis on some text inside a link, as shown below:

```html
<a class="color-fg-secondary no-underline" href="#url">
 This is a link <span class="Link">Link</span>
</a>
```

### Borders <a name="borders">

The class names for setting borders are divided into five parts: setting default borders, border style, border radius, border colors, and responsive borders. To set the default border, we can use any of the following class names such as: `border`, `border-left`, `border-bottom`, `border-right`, `border-x`, and `border-y`. Meanwhile, Primer.css allows attaching a scale of `0-3` to the border, such as `border-2`. It is worth noting that the following class names: `border-top-0`, `border-right-1`, `border-bottom-2`, and `border-left-3` can be used to set the border for the edges of an element. 

To set the border style of an element, the class name of `border` must always be provided like this: `border dashed`. Similarly, we can also provide the border radius of an element using the `rounded` class name with a scale of `0-3` or the class name of `circle` to make the element circular. It can be used like this:

```html
<div class="border rounded-2>
 .border .rounded-2
</div>
```

Or:

```html
<div class="border circle" style="width: 80px; height: 80px;">
.border .circle
</div>
```

Finally, just like with padding and margin, we can also set the border of an element on different breakpoints. We can do it on any of the border patterns mentioned above, such as: `border-sm`, `border-md`, `border-lg`, `border-xl`, `border-sm-2`, `border-sm-top`, and `border-sm-bottom-3`.

### Box shadows and flex <a name="box-shadows-flex">

Primer.css provides five class names to control the box shadow of an element, including: `color-shadow-small`, `color-shadow-medium`, `color-shadow-large`, `color-shadow-extra-large`, and `box-shadow-none`. 

It can be used as follows:

```html
<div class="color-shadow-extra-large p-3">
  .color-shadow-extra-large
</div>
```

The class name for handling CSS flexbox essentially reflects what the style does. To make an element a flexbox, we can use `d-flex` and `d-inline-flex` which stands for:

```css
{ display: flex; }
```

And:

```css
 { display: inline-flex; }
```

Meanwhile, you can use the `flex-row`, `flex-row-reverse`, `flex-column`, and `flex-column-reverse` classes to set the flex directions. Interestingly, the same naming convention exists for `flex-wrap`. This means that you can use `flex-wrap`, `flex-nowrap`, and `flex-wrap-reverse` to choose whether flex items should be wrapped into multiple lines when they overflow or into a single line. 

It’s worth noting that you should have already made an element a flexbox before you can apply the other flex classes like this:

```html
<div class="border d-flex flex-wrap">
  <span class="p-4 border">Item 1</span>
  <span class="p-4 border">Item 2</span>
  <span class="p-4 border">Item 3</span>
</div>
```

To apply the `justify-content` style that is used to distribute the space around and between flex items, we can use the following class names: `flex-justify-start`, `flex-justify-end`, `flex-justify-center`, `flex-justify-between`, and `flex-justify-around`. 

Furthermore, you can use the following class names to apply the `align item` style: `flex-justify-around`, `flex-items-end`, `flex-items-end`, `flex-items-baseline`, and `flex-items-stretch`. 

Although we can create simple and complex layouts using the styles above, there may be times when we want a bit more control over our flex items. The `flex-1` class name instructs a flex item to fill up any available space. The `flex-auto` class can be used to make a flex item fill up open space and auto-resize it if its content changes. While the `flex-grow-0` and `flex-shrink-0` can be used to prevent the growing and shrinking of a flex item. 

Other class names provided by Primer.css are used to adjust the alignment of an individual flex item:

```css
.flex-content-start    { align-content: flex-start; }

.flex-content-end      { align-content: flex-end; }

.flex-content-center   { align-content: center; }

.flex-content-between  { align-content: space-between; }

.flex-content-around   { align-content: space-around; }

.flex-content-stretch  { align-content: stretch; }
```

And to set the order:

```css
.flex-order-1    { order: 1; }

.flex-order-2    { order: 2; }

.flex-order-none { order: inherit; }
```

We can even add and apply a responsive style to items by appending any breakpoints to the flexbox class names mentioned above. It generally follows two rules:

*   `d-[sm or md or lg or xl]-[the property]`
*   `flex-[sm or md or lg or xl]-[the property]-[the behavior]`

An excellent example of this is setting an item to a flexbox in a particular breakpoint like this: `d-md-flex`; or specifying justified content style for only a breakpoint: `flex-lg-justify-center`.

## Exploring the Primer.css components <a name="primer-css-components">

Components in Primer.css are already-built items that look the same regardless of where they are placed on the webpage. They follow patterns that only work when you combine the appropriate modifiers and class names.

### `Buttons` <a name="buttons">

The Primer.css default `button` component can be created by adding `btn` class to a `button` element, as shown below:

```html
 <button class="btn" type="button">Default button>
```

Essentially, we can add more classes to a `button` to set its type, state, and variations. The class names that can be used to specify the button type are `btn-primary`, `btn-outline`, and `btn-danger`. As for the state, we can use the `aria-disabled="true"` and `aria-selected="true"` attributes to disable or enable a button. The attributes can be used as follows:

```css
 <button class="btn mr-2" type="button" aria-disabled="true">Disabled
```

Also, we can specify `btn-sm` or `btn-large` to set the size of the button:

```html
  <button class="btn btn-large">Large button</a>
```

Similarly, we can make a button grow to the width of its parent when we set `btn-block` class name to it and remove the borders around the button using the `btn-invisible` class name.

### `Alerts` <a name="alerts">

Alerts are used to inform users about the status of their actions. In Primer.css, alerts can be created by adding the `flash` class name to an element. By default, this will generate an alert with a light blue background. However, we can vary the alert by appending the `flash-warn`, `flash-error`, or `flash-success` classes. 

Most of the time, alerts are dismissable and have a `close` button. We can use the `flash-close js-flash-close` to properly add to it and position the icon for the action. To create the UI of a dismissible alert, your markup should look similar to this:

```html
    <div class="flash mt-3 flash-error">

      Alert message

      <button

        class="flash-close js-flash-close"

        type="button"

        aria-label="Close"

      >

        Close

      </button>

    </div>
```

### `Box` and `Loaders` <a name="box-loaders">

A `Box` in Primer.css is a container with a background color, borders, and rounded corners. It has no extra styles by default. To create a `Box`, we can use the `Box` class:

```html
<div class="Box">

  Box Content

</div>
```

A `Box` can have a header, body, and footer. The following class names can be used to indicate the function of an element inside a box: `Box-header`, `Box-body`, and `Box-footer`. We can use the class name to add emphasis on the title of a `Box`. 

We can use modifiers to further enhance the look and feel of our `Box`. The `Box-header--blue` can be used to change the background and border color of an element with the `Box-header` class name:

```html
<div class="Box">

  <div class="Box-header Box-header--blue">

    <h3 class="Box-title">This is the title</h3>

  </div>

  <div class="Box-body">

  This is  Box body

  </div>

</div>
```

Other modifiers, such as `Box--danger` and `Box-row--unread` can be set to the `Box` container and the `Box` item. They essentially add a red border to the `Box` and a left border to the `Box` item, respectively. 

`Loaders` are used to indicate a pending state. It should be used with other components and can be triggered using the `AnimatedEllipsis` class name:

```html
<h2><span>Loading</span><span class="AnimatedEllipsis"></span></h2>
```

## Building a landing page with Primer.css <a name="building-landing-page-primer-css">

In this section, we will build a landing page that we can use to demonstrate how to combine components and utilities available in Primer.css. Here is what the result will look like:<iframe style="width: 100%; height: 500px; border: 0; border-radius: 4px; overflow: hidden;" title="A guide to using Primer.css" src="https://codesandbox.io/embed/a-guide-to-using-primer-css-k3fdu?fontsize=14&amp;hidenavigation=1&amp;theme=dark" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe>

### Adding a container <a name="adding-container">

The first step in building our landing page is to open the `primercss-cdn/index.html` that we created earlier. Then, we will create a `div` that will wrap our app:

```html
  <div style="max-width: 1200px" class="mx-auto py-1 px-2">

  <!-- Content will go here -->

  </div>
```

Next, we will add our navbar:

```html
      <div>

        <nav class="UnderlineNav" aria-label="Nav bar">

          <div class="UnderlineNav-body">

            <a

              class="UnderlineNav-item app-link"

              href="#home"

              aria-current="page"

              onclick="handleClick(this)"

              >Home</a

            >

            <a

              class="UnderlineNav-item app-link"

              href="#about"

              onclick="handleClick(this)"

              >About</a

            >

            <a

              class="UnderlineNav-item app-link"

              href="#newsletter"

              onclick="handleClick(this)"

              >Newsletter</a

            >

          </div>

          <div class="UnderlineNav-actions">

            <a href="mailto:bonarhyme@gmail.com" class="btn btn-sm">Reach Us</a>

          </div>

        </nav>

      </div>
```

Let's break it down: 

Our navbar is made up of a `div` that wraps a `nav` element. The `nav` contains an `UnderlineNav` class and wraps two `div` with an `UnderlineNav-body` and `UnderlineNav-actions` that signify two parts of the navbar. 

Meanwhile, the `UnderlineNav-body` contains three `a` elements that all have the `UnderlineNav-item` class from Primer.css, `app-link` class, and `aria-current="page"` that we will be used to show the currently selected item. Also, each item has an `onClick` handler, which we will handle with JavaScript.

### Adding a `hero` section <a name="adding-hero-section">

After that, we can add our `hero` section:

```html
     <div id="hero" class="py-8 blankslate">

        <div

          style="width: 90%; max-height: 200px"

          class="mx-auto border p-3 rounded-2"

        >

          <h1>I love Primer.css</h1>

          <p>Click on the buttons below to find out why:</p>

          <div class="d-flex flex-wrap px-3 my-4" style="gap: 0.5rem">

            <!-- Pop up example -->

            <div class="position-relative text-center">

              <div

                class="Popover position-relative app-popover"

                style="display: none"

              >

                <div

                  class="Popover-message Popover-message--bottom p-4 mx-auto mb-2 text-left Box color-shadow-large"

                >

                  <h4 class="mb-2">Yes, this is the heading</h4>

                  <p>You are not out of luck! This is the message</p>

                  <button

                    type="submit"

                    class="btn btn-outline mt-2 text-bold app-popover-btn"

                    onclick="handlePopover()"

                  >

                    Got it!

                  </button>

                </div>

              </div>

              <button class="btn btn-primary" onclick="handlePopover()">

                View Popup

              </button>

            </div>

            <!-- End Pop up example -->

            <!-- Loading example -->

            <div class="position-relative text-center">

              <div

                class="Popover position-relative app-popover2"

                style="display: none"

              >

                <div

                  class="Popover-message Popover-message--bottom p-4 mx-auto mb-2 text-left Box color-shadow-large"

                >

                  <h2>

                    <span>Loading</span

                    ><span class="AnimatedEllipsis mb-2"></span>

                  </h2>

                 <button

                    type="submit"

                    class="btn btn-outline mt-2 text-bold app-popover-btn"

                    onclick="handlePopover2()"

                  >

                    Got it!

                  </button>

                </div>

              </div>

              <button

                class="btn-mktg btn-small-mktg mx-3"

                type="button"

                onclick="handlePopover2()"

              >

                View Others

              </button>

            </div>

            <!-- End loading example -->

            <!-- Dialog Example -->

            <details

              class="details-reset details-overlay details-overlay-light"

            >

              <summary class="btn" aria-haspopup="dialog">Open dialog</summary>

              <details-dialog

                class="Box Box--overlay d-flex flex-column anim-fade-in fast"

              >

                <div class="Box-header">

                  <button

                    class="Box-btn-octicon btn-octicon float-right"

                    type="button"

                    aria-label="Close dialog"

                    data-close-dialog

                  >

                    <!-- <%= octicon "x" %> -->

                    <svg

                      class="octicon octicon-x"

                      viewBox="0 0 12 16"

                      version="1.1"

                      width="12"

                      height="16"

                      aria-hidden="true"

                    >

                      <path

                        fill-rule="evenodd"

                        d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z"

                      </path>

                    </svg>

                  </button>

                  <h3 class="Box-title">What do you think about this?</h3>

                </div>

                <div class="overflow-auto">

                  <div class="Box-body overflow-auto">

                    <p>

                      You see how cool this CSS framework is??

                      <br />

                      It is what it is!

                    </p>

                  </div>

                  <ul>

                    <li class="Box-row">

                      <img

                        class="avatar v-align-middle mr-2"

                        src="https://avatars.githubusercontent.com/bonarhyme?s=48"

                        alt="bonarhyme"

                        width="24"

                        height="24"

                      />

                      @bonarhyme

                    </li>

                    <li class="Box-row border-bottom">

                      <img

                        class="avatar v-align-middle mr-2"

                        src="https://avatars.githubusercontent.com/bonarhyme?s=48"

                        alt="bonarhyme"

                        width="24"

                        height="24"

                      />

                      @bonarhyme

                    </li>

                    <li class="Box-row border-bottom">

                      <img

                        class="avatar v-align-middle mr-2"

                        src="https://avatars.githubusercontent.com/bonarhyme?s=48"

                        alt="bonarhyme"

                        width="24"

                        height="24"

                      />

                      @bonarhyme

                    </li>

                  </ul>

                </div>

                <div class="Box-footer">

                  <button type="button" class="btn btn-block" data-close-dialog>

                    Close

                  </button>

                </div>

              </details-dialog>

            </details>

            <!-- End of Dialog example -->

          </div>

        </div>

      </div>
```

Let's break it down: 

The hero page is made up of a `div` that contains a `hero` ID and `py-8 blankslate` class names. It wraps around another `div` with the following styles and class names:

```html
  style="width: 90%; max-height: 200px"

  class="mx-auto border p-3 rounded-2"
```

The inner `div` contains an `h1`, `p`, and a `div` with the following style and classes:

```html
 class="d-flex flex-wrap px-3 my-4"

 style="gap: 0.5rem"
```

Inside the `div` we have a popup, loading, and dialog example. The secret to creating a popup with Primer.css is adding the `position-relative text-center` class to the element you want to make a popup. Then, it should have the `div` and `button` children that will be used to display the contents and trigger the popup. For our example, our `button` should have the following attributes:

```html
 class="btn btn-primary"

 onclick="handlePopover()"
```

The `div` containing the content should have the following attributes:

```html
  class="Popover position-relative app-popover"

  style="display: none"
```

It should also have an inner `div` of the classes: `Popover-message Popover-message--bottom p-4 mx-auto mb-2 text-left Box color-shadow-large` that will eventually contain the contents. We can also add an `onclick` to a `button` inside the `Popover-message` with `onclick="handlePopover()"`.

### Creating the sections <a name="creating-sections">

Next, we will add the about us section to our landing page. The about section contains an `h2` that is actually a [tooltip](https://blog.logrocket.com/controlling-tooltips-pop-up-menus-using-compound-components-in-react-ccedc15c7526/). It also includes another `div` with a colorful `timeline` with four items in it. For brevity, here’s the link to the [GitHub repo](https://github.com/bonarhyme/chunks-code-holder/blob/main/primercss/about.html). 

The first `timeline` item contains `breadcrumbs`. While the second, third, and fourth timelines have [truncated](https://blog.logrocket.com/ways-truncate-text-css/) links, normal links with a hover state style, and a `toast` component. 

Next, we have the `newsletter` section which we can add with the following:

```html
     <div id="newsletter">

        <h2 class="py-2 h3-mktg">Subscribe to my Newsletter</h2>

        <form>

          <div class="form-group">

            <div class="form-group-header">

              <label for="example-text">Email address</label>

            </div>

            <div class="form-group-body">

              <input

                class="form-control"

                type="text"

                placeholder="Email address"

                id="example-text"

              />

            </div>

          </div>

          <button class="btn btn-block btn-primary" style="max-width: 440px">

            Submit

          </button>

        </form>

      </div>
```

Let's break it down. The `newsletter` section contains an `h2` and a `form`. The `form` contains a `label`, `input`, and a `button`. Next, we have the footer, as shown below:

```html
  <div>

    <p class="text-center py-4">

      Made by

      <a href="https://github.com/bonarhyme">bonarhyme</a>

    </p>

  </div>
```

Finally, we have our `script` that handles `onclick` events in our code:

```javascript
// Internal JavaScript written inside the body of HTML

    <script>

      function handleClick(e) {

        document.querySelectorAll('.app-link').forEach((x) => {

          x.removeAttribute('aria-current');

        });

        e.setAttribute('aria-current', 'page');

      }

      function handlePopover() {

        const popup = document.querySelector('.app-popover');

        if (popup.style.display === 'none') {

          popup.style.display = 'block';

        } else {

          popup.style.display = 'none';

        }

      }

      function handlePopover2() {

        const popup = document.querySelector('.app-popover2');

        if (popup.style.display === 'none') {

          popup.style.display = 'block';

        } else {

          popup.style.display = 'none';

        }

      }

    </script>
```

## What does Primer.css take from BEM? <a name="primer-css-bem">

Primer.css has a unique architecture that uses object-oriented CSS programming techniques and is influenced by the BEM model. BEM stands for block, element, and modifiers. Essentially, BEM is a method of writing CSS and structuring HTML that helps create components that are cleaner and easier to share across the team. To learn more about BEM and its methodologies, check out this [article](https://blog.logrocket.com/bem-vs-smacss-comparing-css-methodologies/). 

Generally, a block is a standalone entity or component that stands and is meaningful on its own. A great example of a block is a menu, navigation, box, and so on. It should be written like this:

```html
<div class=”card”>

<!-- elements and modifiers go here –>

</div>
```

An element is part of a block semantically tied to its block. Mostly, it has no standalone meaning and should always be tied to a block. Navigation items, box headers, and menu items are all great examples of an element. It can be written with double underscore like so:

```html
<div class="navigation__item">A navigation item</div>
```

Or like this:

```html
<div class="card__header">This is a card header</div>
```

As the name implies, a modifier is used to change the behavior and appearance of a block or an element. This means that a modifier can be tied directly to a block or an element. Examples of applying a modifier to a block include: `navigation disabled`, `box danger`, `button large`, etc. An example of appending a modifier to an element includes: `navigation item disabled`, `box header danger`, and more. Generally, a modifier should be written like this:

```html
<div class=”card__button–danger”>A card button that indicates an error that has occurred</div>
```

Furthermore, The syntax for writing BEM using a card as an example is as follows:

```html
 <section class="card">

      <h1 class="card__title">The Title</h1>

      <div class="card__imageContainer">

 <img src="https://images.unsplash.com/photo-1676136358787-6510632d3e30?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387&q=80"

          alt="an amazing landscape"

          class="card__image"

        />

      </div>

      <div class="card__content">

       <p class="card__description">

          Lorem ipsum dolor sit amet consectetur adipiscing elit. Aperiam porro

          quidem iure natus consequatur. A dolorum quis mollitia veritatis

          nostrum excepturi eligendi impedit doloremque, autem non reiciendis

          nemo, error quidem.

        </p>

        <div class="card__buttonGroup">

          <button class="card__button">Proceed</button>

          <button class="card__button card__button--disabled">Cancel</button>

          <button class="card__button card__button--danger">Delete</button>

        </div>

      </div>

    </section>
```

And CSS:

```css
.card {

        width: 100%;

        max-width: 400px;

        margin-left: auto;

        margin-right: auto;

        border: 1px solid gray;

        padding: 0.8rem;

        border-radius: 0.5rem;

      }

      .card__title {

        color: rgb(31, 31, 31);

      }

      .card__imageContainer {

        width: 100%;

        height: 300px;

      }

      .card__image {

        width: 100%;

        height: 100%;

        object-fit: cover;

      }

      .card__buttonGroup {

        display: flex;

        gap: 0.5rem;

      }

      .card__button {

        padding: 0.4rem 0.8rem;

        cursor: pointer;

        outline: none;

        border-radius: 0.3rem;

        border: 1px solid;

      }

      .card__button--disabled {

        cursor: not-allowed;

        background-color: gray;

        border-color: gray;

      }

      .card__button--danger {

        background-color: rgb(231, 36, 36);

        color: white;

        border-color: rgb(231, 36, 36);

      }
```

### How Primer.css is different <a name="primer-css">

Primer.css makes use of the same pattern BEM uses. However, instead of double underscores, which are used to identify elements, it uses a hyphen. But for modifiers, it makes use of an [ARIA](https://blog.logrocket.com/using-ariakit-components-react-apps/) for `button` components and a double hyphen for some other components, like a `Box`. 

A block in Primer.css includes components such as `Dropdowns`, `Pagination`, `Popovers`, and `menu`. It should be noted that some blocks are capitalized while some are lowercase. With BEM, elements shouldn't be standalone and should instead be inside of a block. The same applies to Primer.css; an element must be inside a component to work as expected. Also, modifiers must be combined with a block or an element to work correctly. 

BEM methodology ensures that our CSS code is more structured and easily reused across the team in various application parts by enforcing a more consistent pattern of generating class names. This particular approach is what Primer.css uses under the hood to ensure that our app UI is consistent across the board.

## Conclusion

The simplicity of Primer.css makes it an excellent choice for building your next project and should be adopted because it comes with many components and utilities that are very responsive and clean. Thank you for reading through. I hope you enjoyed this article, and be sure to comment if you have any questions. Happy coding!

---

## Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, [try LogRocket] (https://logrocket.com/signup/).

[![LogRocket Dashboard Free Trial Banner] (https://blog.logrocket.com/wp-content/uploads/2019/12/cpu-memory-usage.png)](https://logrocket.com/signup/)

[LogRocket] (https://logrocket.com/signup/) is like a DVR for web apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web apps — [Start monitoring for free] (https://logrocket.com/signup/).