Bricks notes
Grid / flexbox notes
Grid:
Grid template columns can be set as:
minmax(0,1fr) minmax(0,2fr) minmax(0,1fr)
to produce this:

(minmax with 0 stops overflow issues when shrinking screen)
repeat(2, minmax(0, 1fr))
produces this:

repeat(4, minmax(0, 1fr))
produces this:

Flexbox:
Used to justify and align content within a container.
Axis is column or row. Options are related to main axis or cross axis.
Layout notes
If using basic text and need to modify some words to be bold or different colour, can use < span >. But why not just use Rich Text?
When designing, you can use ipsum just to get the layout all done.
In a Rich Text you can set the custom CSS to:
%root% {
columns: 2 200px;
}
And now you will see that the text is spread across 2 columns rather than 1. No column will be squished smaller than 200px. It is automatically responsive as if the screen can’t hold both columns it will put them on top of eachother (eg this page on a mobile). You can make it columns 3, 4 , etc.
Here goes your text … Select any part of your text to access the formatting toolbar.
When you add a Basic Text, be sure to set the type to < p >.
block aligns things up and down (in a column). inline aligns things left and right (in a row).
It is best to wrap images in a wrapper so you can do pseudo stuff on them if needed.

Note if the feature card was nested in a service card, we wouldn’t call it service-card__feature-card__icon. BEM doesn’t have grandparents, we keep it flat. So just feature-card__icon.
border-radius of 50% makes a circle
overlay is present on section/Container (actually all elements) to add an overlay transparency. It is under Gradient / Overlay

Put text colour on the container. Then all text elements inherit that colour (rather than you having to add it to each element).
max width media queries (what the breakpoints do in Bricks) affect that width and everything below.
@media (max-width: 767px)
min width media queries affect that width and above (e.g. when designing mobile first which you shouldn’t do in a page builder.
@media (min-width: 991px)
Bricks custom breakpoints can be turned on in the Bricks > settings (general tab) > custom breakpoints.
You can do min width in the custom css, e.g. this text has:
@media (min-width: 991px) {
%root% {
color: firebrick;
}
}
%root% references the currently selected item (ID or class)
. is class
# is ID
More specific selector takes precedence.
In the below, the — is a modifier, it doesn’t give it any precedence over the normal my-box, it is just for organisational reasons.
.my-box {
background-color: hotpink;
}
.my-box–dark {
background-color: black;
}
Here is how you can use a dark modifier:
.team-card–dark {
background-color: #111;
}
.team-card–dark .team-card__name {
color: #fff;
}
.team-card–dark .team-card__title,
.team-card–dark .team-card__bio, {
color: #999;
}
.team-card–dark .team-card__icon {
background-color: #444;
border-color: #444;
color: #999;
}

Positioning notes
Fixed: Stays fixed in place so you can scroll but the element remains where it is.
top: 0 attaches to the top of the device
left: 0 attaches to the left of the device
Static: the default for image. Cannot have coordinates.
Relative: position relative to the static position. See below. The diagram on the left shows both images set to static. They stack on eachother in the container. On the right, the bottom image is still static. The top image is relative with a top of -2em. Notice how nothing else on a page is influenced by relative.

Absolute: Attached itself to the first parent it can find with a position of relative (actually to first with any position other than static).
Setting top 0, left 0, bottom 0, right 0 stretches to the size of the container.
When setting absolute, the “container” is no longer affected by its size as it is out of the stacking context. So you need to set a height for the container. And if there are other things in the container, you need to set a z index on your absolutely positioned element of -1, otherwise it will just cover those other elements (as it is out of the stacking context).
Sticky: Needs a top value. When scrolling down, will move to this top value, until you get to the bottom of the container, and then it will go off the screen like everything else.
Best to put an image set to sticky in a container (div). Then set the container to stretch vertically (when there are 2 columns, so it will stretch from the top row to the bottom row). Now, when you scroll, the image will behave sticky as expected. But if reducing the screen width (i.e. mobile), those 2 columns will collapse to 1, so that stretch will just be the height of the image, not all those images in the right column. So it will just scroll off the top as expected rather than remaining sticky and blocking view of other things. You can see in the left image, the container stretched (green) and sticky image (red). In the right, the container is size of the image, so effectively no sticky.

Navigation notes
Add the nav menu element, select Menu (WordPress).
To create a menu, go to the WordPress dashboard and either:
Appearance > menus
or preferably, Appearance > Customize > menus.
To style, there the options in Bricks. You can also choose the hover arrow at the top and set the hover colour.
Images notes
Unsplash for royalty free images. Logoipsum for logos. Emojipedia for emojis.
JPEG no transparency. PNG has transparency is a raster image type meaning not scalalable. When scaling, it is pixelated (also plugins and even WordPress try to optimise them so they can look fuzzy). Use SVG when you can, you can insert an SVG in Bricks (there is an SVG element) and it converts to code, so you can then change the colour in the stylesheets.
Use Squoosh to pre-optimise images.
HappyFiles Pro to organise the files (to avoid the junk drawer nightmare).
ShortPixel Image Optimizer: reoptimises every image that is uploaded. Serves images in next gen format like webp (jpeg and pngs need to be served as webp for optimisation and performance, not all navigators support this, so ShortPixel provides webp when it can, otherwise jpeg or png).
srcset: added automatically by Bricks. Defines all the image sizes and lets the browser choose the appropriate one.
You can wrap an image tag with a figure tag (means it is important).
Don’t use design tool to add accent items, background colours or gradients to image, do everything you can in CSS.
Below is how to create an image and overlay text the right way (not setting a background image to a container, an overlay then adding the text to it).
Image container contains a .real-image class. Set height to 50rem. Set positioning to relative. Padding 5 rem all sides. Content > Align main and cross axis to end. Typography > colour white
Image is uploaded, select the 1536×1024 version of the image. Select figure tag. Give it some Custom alt text. No caption. Give a class of real-image__image (we are using BEM class structure as container is called real-image). Set positioning: absolute. Top left right bottom all 0. Height and width to 100%. (Content) Object fit > Cover. Object positioning 50% 100% to see bottom, 50% 0% to see top. Set to 50% 50% for middle. Layout > Z Index = -1
Add a basic text and give it the class overlay-text (font size 3.8rem, font weight 600). Type the content “Snorkeling Lessons”
Add a div, name overlay, add class real-image__overlay. Positioning absolute. Top left right bottom = 0. Add background colour of #212121, drop transparency. Set Z index to -1.

If things overflow from a container (e.g. rounded corners not clean because an overlay is standing out) you can set on the container under Layout > MISC: overflow to be hidden.
Units notes
px: only for media query screen sizes
rem: fox fixed sizes + font sizes (1 rem = 10px at 62.5% root font size)
em: like a ratio. 1.5em is 1.5 times the font size. Good for things that need to respond to changes in calculated font size (e.g. buttons padding). NEVER use for font size
e.g. root is 1px. You use 2rem in a button. If padding = 1rem it is always 10px even if you make button font size 3rem. But 1em means padding at 2rem is 20px and at 3 rem is 30px.
percent: relative to dimensions of parent element
ch: width of the zero character. Text should be 50-75 ch wide (max-width)
vh: percent of viewport height
vw: percent of viewport width (e.g. 60vw is 60 percent of viewport width)
vmin: smaller of viewport width or viewport height
vmax: larger of viewport width or viewport height
Functions notes
clamp(min, preferred range, max)
for a min screen width of 320px (32rem) and max of 1366px (136.6rem) an item that you want to have a size of 5rem on smallest width and 10rem on largest width:
clamp(5rem, calc(5rem + ((1vw-0.32rem)*4.7801)), 10rem)
To calculate the clamp function, set up an Excel as below:

Paste headings as follows:
| Min device size | Max device size | Min value (rem) | Max value (rem) | Calc Slope | Calc offset | Calc function |
then calc slope paste this:
=((E3-D3) / (C3-B3)) * 1000
calc offset:
=D3 – (F3 * (B3 / 1000))
calc function:
= “clamp(” & D3 & “rem, ” & FIXED(F3, 3) & “vw + ” & FIXED(G3, 3) & “rem, ” & E3 & “rem)”
You can set the section gutter by setting the max_width (don’t do this, it is just to illustrate, you should just set the padding to 6 rem instead) to:
min(1366px, 100vw-12rem)
This will set the section be set to at most the smaller of 1366 (when screen large) or viewport width – 12 rem (when screen small, 6 rem each side if centred).
min or max?
- If I need an element to be dynamically sized, but never smaller than x, use max.
- If I need an element to be dynamically sized, but never larger than x, use min.
e.g. If I have a section and I want to just have a sneak peak of the next section at the bottom, set the min_height to:
calc(100vh – 6rem)
HSL (Hue Saturation, Lightness)
E.g. with this colour:
hsl(145, 60%, 60%)
we can find the complimentary colour (other side of the colour wheel) with:
hsl(calc(145+180), 60%, 60%)
Variables notes
Create a global stylesheet in wpcodebox.
:root {
–radius: 2rem; // Border radius for ALL elements (the rounded corners)
–section-block-padding: clamp(5rem, calc(5rem + ((lw – 0.32rem)*4.7801)), 10rem);
— section-inline-padding: clamp(5rem, calc(5rem + ((lw – 0.32rem)*4.7801)), 10rem);
–h1: clamp(…);
–h2: clamp(…);
}
img {
border-radius: var(–radius);
}
In the root we define the variables, then use them in img.
We can set a font size then by using the variable, e.g.
var(–h1)
To set font size 10% bigger than h2, we could set it to:
calc(var(–h2)*1.1)
BEM stands for:
Block
Element
–Modifier
Note the double dash for the modifier instead of double underscore, e.g. for dark mode
Selectors notes
Imagine we have this setup:
< div class=”parent”>< div >< / div >< div >< / div >< div >< / div >< / div >
We can access the parent with this:
.parent {
}
And all the children with this (* is the wildcard)
.parent > * {
}
So for example, in the custom CSS of a section, we can make each odd container have a red border with this:
%root% > *:nth-child(odd) {
border: 5px solid red;
}
And we can get circle each element within that like this (this is what I’ve done with this section):
%root% > *:nth-child(odd) > *:last-of-type {
border: 5px solid red;
}
Custom Post Types notes
Used to create a new drawer instead of just using one junk drawer.
For Media files: Happy Files Pro
For Pages and posts (very if ever use pages as can use custom pages), use MetaBox AIO (All In One) or Advanced Custom Fields. Seems second one is preferred but first has LTD. Check around Black Friday.
Templates and Components notes
Templates (full or partial) are for page layout (blog posts, service pages, archives page, search results etc).
Components are individual reusable elements (header, footer, card, form, gallery).
Templates can contain components.
Components can contain components.
There is a template area in Bricks menu from the dashboard screen (where you create and edit templates (and components)).
In the page editor, you can add an element, then select the template you have created (to add a component).
DO NOT USE THE PAGE BUILDER TO WRITE BLOG POSTS.
Instead, create a template, set to Single under template type, then settings > template settings > condition > Post type, then set post type to posts.
Under the heading, choose the lightning bolt for dynamic content and choose post_title.
Then add an element (post content) and set the data source to Word Press.
You can set it to Bricks if you are creating a partial template (top part is a real template, then each post is designed in Bricks).
Pseudo elements notes
::before and ::after
Allow you to dynamically manipulate elements inside the box. Before or after other elements that happen to be inside the box too. Can only have one before and after on each element. If you need more, add another wrapper. E.g. If you wanted an accent and an overlay from below, would need another wrapper.
Needs content, dimension, colour, position.
Divider: define on class .pseudo-divider:
%root%::after {
content: “”; // even if you don’t have content, you have to define content.
width: 100%;
height: 2px;
background-color: red;
margin-top: 2rem;
}
Example modifier of above (always use modifiers in combination with the original, i.e. attach the original class, and attach the modifier if needed too). Note you don’t need to copy all the other css, just the differences. For .pseudo-divider–top
%root%::after {
order: -1; // because we know our container is flex, this will move it to the top
}
note to centre something, you can use the transform and margin-left as below:
.pseudo-divider–wide
%root%::after {
width: calc(100% + 8vw);
transform: translateX(-50%);
margin-left: 50%;
}
On a section to apply a divider to all containers except the last one, you can add the css to the section:
%root% > *:not(:last-child)::after { }
Accent box: Create a Media wrapper (div) and in that the image. Define a class .media-accent on the media wrapper (note that pseudo elements don’t work directly on images hence the wrapper). See how you can define local variables in %root%, then the common things in %root%::before, %root::after, then things explicitly for before in its own part and after also in its own part.
%root% {
position: relative;
–border-size: 300px;
–border-width: 2px;
–border-style: solid;
–border-color: red;
–border-offset: -1em;
z-index: -1;
}
%root%::before, %root::after {
content: “”;
width: var(–border-size);
height: var(–border-size);
background-color: transparent;
position: absolute; // don’t forget we are inside the box here. So on root (the parent), it is relative.
}
%root%::before {
border-left: var(–border-width) var(–border-style) var(–border-color);
border-top: var(–border-width) var(–border-style) var(–border-color);
top: var(–border-offset);
left: var(–border-offset);
}
%root%::after{
border-right: var(–border-width) var(–border-style) var(–border-color);
border-bottom: var(–border-width) var(–border-style) var(–border-color);
bottom: var(–border-offset);
right: var(–border-offset);
}
Overlay (create class .my-custom-overlay):
%root% {
position: relative;
isolation: isolate; // creates a new stacking context. With z index, makes sure writing on top is shown without this overlay affecting it.
}
%root%::before {
content: “”;
position: absolute;
inset: 0; // shortcut to set top, left, bottom, right
width: 100%; // might not need this
height 100%; // might not need this
background-color: red;
opacity: .5;
z-index: -1;
}
::marker – create a .marker-custom class on a rich text.
%root% li ::marker {
content: “❤️”;
colour: red;
}
::first-letter and ::first-line – create a dropcap class on a richtext
%root%::first-letter {
colour: red;
font-weight: 700;
float: left;
font-size: 150%
}
Pseudo classes notes
E.g. .button:hover { } .button:focus { }
On a button you could add:
%root%:hover {
background-color: black;
}
:first-child, :last-child, :nth-child(),
:first-of-type, :last-of-type, nth-of-type()
To select first child of a container:
%root% > *:first-child {
border: 5px solid red;
}
To select 2nd child:
%root% > *:nth-child(2) {
border: 5px solid red;
}
To select 2nd figure:
%root% figure:nth-of-type(2) {
border: 5px solid red;
}
to count backwards: nth-last-child() and nth-last-of-type()
%root% > *:nth-child(3n) // every 3rd element
%root% > *:nth-child(3n+2) // offset of 2, then every 3rd element
%root% > *:nth-child(-n+4) // Only first 4 elements (can use nth-last-child with this for last 4 elements
%root% > *:nth-child(even) // or odd
%root% > *:nth-child(-n+4),
%root% > *:last-child // first 4 and last element
:not()
%root% > li:not(nav li, .exclude li) // not means select this but not that. So here, we select li, but not the nav li and not the exclude classes li
:is() and :where() do the opposite (where resets specificity making it easier to override)
%root%:is(nav li) // only selects the nav li
:has() is very powerful as it allows you to style the parent.
.brxe-container:has(> figure:nth-child(2) // select all bricks containers with a figure in position 2
:focus style of element in focus
:focus-within elements that contain a focusable element
To make a whole card focusable that contains a button (which is clickable):
%root%:focus-within {
box-shadow: 0 0 0 5px black;
}
%root%:focus-within :focus {
box-shadow: none; // sets the button’s focus to nothing
}
If a 4 column grid has nothing in 4th column, we can hide the column like this:
.grid–4 :empty() {
display: none; // removes the empty cell
}
.grid–4:has( > :empty) {
grid-template-columns: var(–grid-3); // sets to 3 columns
}
Other pseudo classes:
:action :visited :enabled :disabled :valid :invalid :root, a bunch related to forms, and many more.
Data attributes notes
You can give attributes to elements and then use these for styling. The attribute always needs the “data” prefix
<div class=”profile-card” data-profile-name=”Bob Duck”>
<!– Content –>
</div>
We can select the above with:
[data-profile-name=”Bob Duck”] {
border: 5px solid red;
}
To set this up in Bricks:
Choose the card, Style, Attributes, then add attribute.
Name: data-profile-name. Value (choose lightning bolt): select post_title.
Add another:
Name: data-profile-title. Value (choose lightning bolt): select acf_team_member_position.
Note after the %root% a space means on the child of this element, no space means attached to this element.
Now on the class attached to the card:
Below there is no space as the attribute is on our current class (the card). Here we put a border around the card. We also move these executives to the beginning.
%root%[data-profile-title=”Executive”] {
border: 5px solid red;
order: -1;
}
Below there is a space before :is, because we are looking for the classname__title and classname_name, which are children of our classname (items inside our card). See how %root% means classname, as we’re using BEM, we know we have a classname__title and __name. Here we turn the text white.
%root%[data-profile-title=”Executive”] :is(%root%__title, %root%__name {
color: white
}
%root%[data-profile-name=”Jake”]
order -2; // here we make Jake appear first, before the executives
}
On a button, go to Style, Attributes. Add name: data-notification-value. Value: 8. This should be set on the backend to update correctly, then we can dynamically link to that value.
%root% {
position: relative;
}
%root%::before {
content: attr(data-notification-value);
position: absolute;
background-color: red;
color: white;
font-size: calc(var(–text-s) * 1.1);
font-weight:700;
aspect-ratio: 1/1;
width: 3ch;
height: 3ch;
display: grid;
place-items: center;
border-radius: 50vw;
top: -1ch;
right: -1ch;
}
Interactions
On the interactions section at the top of a button set up:
Trigger: click. Action: Set attribute. Key: data-status. Value: success. Target: CSS Selector. CSS Selector: .status.
You can duplicate this for a warning and a danger button.
Add a basic text with a class of .status. Now add the following to the .status class. Note the i after “success” makes it case insensitive:
%root%[data-status] {text-transform: capitalize;}%root%[data-status=”success” i] {background-color: green;color: white;}%root%[data-status=”warning” i] {background-color: orange;color: white;}%root%[data-status=”danger” i] {background-color: red;color: white;}

To target elements with a specific attribute:
%root% a[title] {} // target links with a title
%root% [class] {} // target anything in the section with a class
%root% a[class=”btn”] {} // target anything with only 1 class and it is called button
%root% a[class*=”btn–“] {} // target anything with a class containing the word btn–
%root% [data-name~=”Bob”] {} // target anything with a data attribute with Bob. “Bob Duck”: OK. “BobDuck”: Not OK.
%root% a[href^=”http://”] {} // target anything beginning with http://.
%root% a[href$=”dark”] {} // target anything ending with dark.
More examples:
- [src] for image sources (e.g. find jpegs, gifs etc)
- [alt] for image alt text
- [width] and [height] dimensions
- [lang] – eg if doing a multi language site, can style if language = us, or es etc.
- [style] inline styles
- [title]
- [datetime]
- [disabled]
Remember, can be used with :is(), :where(), :has(), :not() etc.
Breakpoints and Media Queries notes
To manage these dynamically with SCSS:
// Step #1: Create a map for our breakpoints
$breakpoints: (
xl: 1279px,
l: 991px,
m: 767px,
s: 479px,
);
// Step #2: Create mixins to generate the @media queries
@mixin breakpoint($name) {
@media (max-width: map-get($breakpoints, $name)) {
@content;
}
}
@mixin breakpoint-up($name) {
@media (min-width: map-get($breakpoints, $name)) {
@content;
}
}
// Step #3: use the Mixins
.logo {
width: 20rem;
margin-inline: auto;
@include breakpoint-up(l) {
border: 5px solid red;
}
}