2.4 The Most Important CSS Concepts You Need First
A detailed foundation for understanding GSAP and Glaze 🚀
Before GSAP can animate anything well, you need to understand what exactly is being animated. GSAP does not replace CSS fundamentals — it builds on top of them.
If CSS is unclear, animation will feel confusing.
For example:
- You try to move something with GSAP, but it doesn’t go where you expect.
- You scale an element, but it grows from a strange point.
- You animate
x, but the item disappears outside its container. - You change
z-index, but nothing happens. - You animate a hidden element, but it still doesn’t show.
These are usually not GSAP problems. They are CSS structure problems.
So this chapter is extremely important. Think of it as your animation preflight checklist.
Why these CSS concepts matter for animation
When you animate in GSAP or Glaze, you are often changing things like:
- position
- opacity
- scale
- rotation
- visibility
- layering
- size
- movement inside or outside a container
To understand those, you need to know:
- How elements are selected
- How elements are placed in the page layout
- How elements behave inside containers
- How transforms work
- How overlapping works
That is exactly what we cover here.
2.4.1 Classes
What a class is
A class is a reusable label you give to one or more HTML elements.
Example:
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
All three elements have the class card.
In CSS, you target a class with a dot:
.card {
background: #eee;
padding: 20px;
}
That means: “apply this styling to all elements with the class card.”
Why classes matter for GSAP
Classes are one of the most common ways to target elements for animation.
Example with GSAP:
gsap.to(".card", {
y: -20,
duration: 1
});
This tells GSAP to animate all elements with the class .card.
This is incredibly useful because animation often applies to:
- multiple cards
- buttons
- images
- headings
- sections
- icons
- repeated items in a list or grid
So classes are usually your main animation hooks.
Why classes are especially useful in WordPress and BricksBuilder
In WordPress and BricksBuilder, you often work with:
- reusable components
- repeated content
- loops
- builder-generated elements
Using classes lets you apply animation logic to many items at once.
Examples:
.feature-card.fade-in.hero-title.cta-button.grid-item
This is much better than targeting random auto-generated builder selectors.
Good mental model
Think of a class as:
If 8 elements should behave similarly, give them a class.
Example
<section class="services">
<div class="service-card"></div>
<div class="service-card"></div>
<div class="service-card"></div>
</section>
gsap.from(".service-card", {
opacity: 0,
y: 40,
duration: 0.8,
stagger: 0.2
});
Here the class makes staggered animation easy.
Common beginner mistakes with classes
1. Forgetting the dot in CSS or GSAP selector
Correct:
gsap.to(".box", { x: 100 });
Incorrect:
gsap.to("box", { x: 100 });
Without the dot, GSAP looks for an HTML tag named box.
2. Using classes that are too generic
Avoid class names like:
.blue.big.left
These describe appearance, not purpose.
Better:
.hero-image.testimonial-card.pricing-item
This is cleaner and easier to maintain.
3. Depending only on builder-generated class names
Page builders often create classes that are not memorable or stable enough for your animation logic.
Prefer adding your own classes intentionally.
Best practice
Use classes for:
- Styling groups
- Animation targeting
- Reusable elements
In animation work, classes are usually more useful than IDs.
2.4.2 IDs
What an ID is
An ID is a unique label for a single HTML element.
Example:
<section id="hero"></section>
In CSS, you target an ID with #:
#hero {
min-height: 100vh;
}
In GSAP:
gsap.from("#hero", {
opacity: 0,
duration: 1
});
Main difference between classes and IDs
- A class can be used on many elements.
- An ID should be used only once on the page.
So:
<div class="card"></div>
<div class="card"></div>
is normal, but:
<div id="card"></div>
<div id="card"></div>
is wrong.
IDs must be unique.
Why IDs matter in animation
IDs are useful when:
- You need to target one specific element
- That element is important and unique
- You want a very clear selector
Examples:
When IDs are useful in WordPress and BricksBuilder
They can be useful for:
- unique sections
- anchor links
- one-off animation targets
- page-specific interactions
For example, if you have exactly one hero section on a page, #hero may be fine.
Why classes are often better than IDs for animation
Even though IDs are valid, classes are often more flexible because:
- They can be reused
- They work better for multiple elements
- They are easier for staggered animation
- They fit component-based design better
For example, if later you add another hero-like section, an ID will not scale well.
Important caution about IDs
IDs have historically had stronger CSS specificity than classes.
That means styles attached to IDs can be harder to override.
This matters because if your CSS becomes difficult to override, your animation debugging becomes harder too.
You do not need to become a specificity expert yet, but remember:
- classes are usually safer and more reusable
- IDs should be reserved for truly unique elements
Simple rule of thumb
Use:
- Class for reusable styling and animation
- ID for one unique element when it truly makes sense
2.4.3 Nesting and hierarchy
What nesting means
HTML elements live inside other elements.
Example:
<section class="hero">
<div class="hero-inner">
<h1 class="hero-title">Welcome</h1>
<p class="hero-text">Hello world</p>
</div>
</section>
Here the structure is:
.hero- contains
.hero-inner- contains
.hero-title - contains
.hero-text
- contains
- contains
This is called nesting or hierarchy.
Why hierarchy matters for animation
Animation almost always happens inside a structure.
For example:
- a child moves inside a parent
- text reveals inside a masked container
- an image scales inside a card
- a button animates when its parent is hovered
- items stagger because they share the same parent context
If you do not understand parent-child relationships, animation logic gets messy very quickly.
Parent and child
In HTML/CSS:
- The outer element is the parent
- The inner element is the child
Example:
<div class="card">
<img class="card-image" src="image.jpg" alt="">
</div>
.cardis the parent.card-imageis the child
Why this matters in practice
Imagine you animate the image:
gsap.to(".card-image", {
scale: 1.2,
duration: 1
});
If the parent .card has:
.card {
overflow: hidden;
}
then the scaled image stays visually clipped inside the card.
If the parent does not have overflow: hidden, the image may grow outside the card.
That is hierarchy affecting animation.
Descendant targeting
You can target nested elements in CSS using spaces:
.hero .hero-title {
color: white;
}
This means: any .hero-title inside .hero.
In GSAP you can also use nested selectors:
gsap.from(".hero .hero-title", {
y: 40,
opacity: 0
});
This helps you target specific elements in a specific context.
Why hierarchy is important for cleaner animations
Let’s say your site has multiple headings with class .title.
If you animate:
gsap.from(".title", { opacity: 0 });
you may animate every title on the whole page.
But if you target:
gsap.from(".hero .title", { opacity: 0 });
you only animate titles inside .hero.
This gives you control.
Containers are extremely important
A lot of animation setups are based on the idea of a wrapper.
Example:
<div class="mask">
<div class="text">Animated Text</div>
</div>
The outer wrapper controls behavior such as:
- clipping
- positioning reference
- alignment
- spacing
The inner element is the thing that moves.
This pattern appears constantly in animation.
Very important beginner idea
Often the thing you animate is not the same thing that controls layout.
For example:
- Parent handles width, height, clipping, positioning
- Child handles movement, rotation, scale
This separation makes animation much easier.
2.4.4 Display types
What display means
The display property controls how an element behaves in layout.
This is one of the most important CSS properties in general.
Common values include:
blockinlineinline-blockflexgridnone
block
Block elements usually:
- take up the full available width
- start on a new line
- stack vertically
Examples of block-like elements:
divsectionph1
Example:
.box {
display: block;
}
For animation, block elements are often easy to work with because they behave predictably in layout.
inline
Inline elements:
- flow within text
- do not naturally start on a new line
- do not behave like boxes in the same way as block elements
Examples:
spanastrong
If you try to animate width, height, or transform behavior on inline elements, results can sometimes be confusing.
That is why animated text spans are often changed to:
display: inline-block;
inline-block
This is a very useful middle ground.
An inline-block element:
- stays inline with text
- but behaves more like a box
- can be transformed more predictably
This is common for:
- animated letters
- animated words
- badges
- buttons
- icons
Example:
.word {
display: inline-block;
}
Now scaling or translating .word is usually more reliable.
flex
Flexbox is used to align and arrange items in a row or column.
Example:
.container {
display: flex;
gap: 20px;
}
This makes child elements line up more easily.
For animation, flex matters because:
- item positioning depends on flex rules
- spacing can affect motion perception
- flex containers are common in modern layouts
- animating items inside a flex layout is extremely common
If something “moves strangely,” the parent flex rules may be part of the reason.
grid
CSS Grid is another layout system.
Example:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
This creates a structured grid.
For animation:
- grid items often animate in sequence
- staggered entrance effects are common
- layout is controlled by the grid, while transforms affect visual movement
Again, layout and animation are related but not identical.
none
.element {
display: none;
}
This removes the element from layout completely.
Important: if an element is display: none, it is effectively not present for visual animation.
This is crucial.
If you try:
gsap.to(".element", { opacity: 1 });
but the element is display: none, it still won’t show as expected until display is changed.
Animation-related warning about display
display is generally not smoothly animatable like opacity or transform.
You usually do not tween it visually from one state to another.
Instead, a common strategy is:
- Set
displayso the element can exist - Animate
opacity,y,scale, etc.
For example:
- bad idea: trying to smoothly animate from
display: nonetodisplay: block - better idea: switch display, then fade in with opacity
A practical example
Suppose you have a popup.
Instead of relying on display animation, you might think in steps:
- Make it present in layout
- Fade it in
- Move it slightly upward
- Scale it subtly
This feels much smoother.
2.4.5 Positioning basics
Why positioning is essential for animation
A huge amount of animation depends on where an element is located and what reference point it uses.
CSS positioning tells the browser how to place an element.
The main values are:
staticrelativeabsolutefixedsticky
static
This is the default.
.box {
position: static;
}
A statically positioned element sits in normal document flow.
Properties like top, left, right, and bottom generally do not work in the usual way here.
For animation, static is often fine if you only animate transforms such as x, y, scale, and rotate.
relative
.box {
position: relative;
}
This does two important things:
- The element remains in normal flow
- It becomes a reference point for absolutely positioned children
This is extremely important.
absolute
.child {
position: absolute;
top: 0;
left: 0;
}
An absolutely positioned element is removed from normal document flow and positioned relative to its nearest positioned ancestor.
That means:
- if no parent has
position: relativeor another positioning value, it may position relative to the page or another ancestor - if the parent is positioned, the child can align inside that parent
Classic animation pattern
<div class="card">
<div class="badge"></div>
</div>
.card {
position: relative;
}
.badge {
position: absolute;
top: 10px;
right: 10px;
}
Now the badge sits relative to the card.
This matters because if you animate the badge, you usually want it anchored to the card, not the whole page.
fixed
.menu {
position: fixed;
top: 0;
left: 0;
}
A fixed element is positioned relative to the viewport.
It stays in place while the page scrolls.
Common uses:
- sticky headers
- floating buttons
- overlays
- back-to-top buttons
Animation-wise, fixed elements are often used in:
sticky
.sidebar {
position: sticky;
top: 20px;
}
A sticky element behaves like a normal element until a scroll threshold is reached, then it sticks.
This is useful for:
When using GSAP with scroll interactions, understanding sticky behavior helps avoid confusion.
Positioning and GSAP movement
Very important: when you animate with GSAP using properties like x and y, you are usually animating transform-based movement, not changing top and left.
That is good.
Why?
Because transform-based movement is generally:
- smoother
- more performant
- less disruptive to layout
So even if positioning determines where the element starts, GSAP often moves it visually using transforms.
Common beginner confusion: top/left vs x/y
These are not the same idea.
top and left
- layout-position related
- depend strongly on positioning mode
- can affect layout behavior more directly
x and y in GSAP
- usually map to transforms
- move visually
- are often easier and smoother for animation
So in animation work, x and y are often preferred.
Practical rule
Use CSS positioning to establish where elements belong.
Use GSAP transforms to create how elements move.
That combination is powerful.
2.4.6 Overflow
What overflow means
overflow controls what happens when content extends beyond an element’s boundaries.
Common values:
visible
This is often the default.
If a child grows or moves beyond the parent, it can still be seen.
Example:
.card {
overflow: visible;
}
If you scale a child image up, it may spill outside the card.
hidden
.card {
overflow: hidden;
}
Anything outside the boundaries gets clipped.
This is one of the most important properties in animation.
Why?
Because many effects rely on clipping:
- image zoom inside a card
- text reveal from below
- wipe effects
- sliding content that should stay inside a container
Example: image zoom card
<div class="card">
<img class="card-image" src="image.jpg" alt="">
</div>
.card {
overflow: hidden;
}
.card-image {
width: 100%;
}
Now if GSAP scales .card-image, the image remains visually contained.
Without overflow: hidden, the effect often looks messy.
Example: text reveal
<div class="text-mask">
<div class="text-line">Hello World</div>
</div>
.text-mask {
overflow: hidden;
}
Then you can animate .text-line upward into view.
The mask hides the extra part until it slides in.
This is a very common professional animation pattern.
auto and scroll
These are more related to scrollbars.
autoshows scrollbars when neededscrollforces them
These matter less for simple animation, but become relevant when dealing with scroll containers.
Why overflow often causes confusion
You animate an element and wonder:
- Why is it cut off?
- Why does it disappear at the edge?
- Why can’t I see the full movement?
Very often the answer is:
- a parent has
overflow: hidden
Or the opposite:
- the parent does not have
overflow: hidden, so the effect leaks outside
So when debugging animation, always inspect parent containers.
Not just the animated element itself.
2.4.7 Transform
What transform is
transform lets you visually change an element without altering normal layout in the same heavy way as many other properties.
This is one of the most important animation concepts in all of front-end development.
Common transform functions include:
translatescalerotateskew
translate
Moves an element visually.
Example:
.box {
transform: translateX(100px);
}
This moves it 100 pixels to the right visually.
GSAP equivalents are often:
xy
Example:
gsap.to(".box", {
x: 100
});
This is extremely common.
scale
Changes size visually.
.box {
transform: scale(1.2);
}
This makes the element 20% larger.
GSAP:
gsap.to(".box", {
scale: 1.2
});
Great for:
- hover effects
- image zooms
- pop-in entrances
- emphasis effects
rotate
Rotates an element.
.box {
transform: rotate(45deg);
}
GSAP:
gsap.to(".box", {
rotation: 45
});
Useful for:
- icons
- decorative elements
- playful motion
- directional reveals
skew
Tilts the element.
.box {
transform: skewX(10deg);
}
GSAP can animate skew too.
This is less common for beginners, but useful in stylized motion.
Why transform is so important for GSAP
GSAP often works best when animating transform-related properties because they are:
- smoother
- more performant
- visually flexible
- less disruptive to layout
This is one major reason GSAP feels so good.
Important concept: transforms are visual, not normal layout movement
If you move something with transform: translateX(100px), the browser still treats its original layout position as its normal place.
That means:
- the element appears moved
- but document flow does not rearrange around the moved result in the same way
This is very important.
For animation, this is usually excellent.
For layout assumptions, it can confuse beginners.
Transform order matters
If multiple transforms are combined, the result depends on order.
Example conceptually:
- move then rotate
- rotate then move
These can produce different visual results.
You do not need to master transform math right now, but you should know:
transforms are not just isolated effects — they interact.
GSAP helps manage this more easily than raw CSS.
Why transformed elements may look blurry or behave unexpectedly
Sometimes when scaling or moving:
- text may appear slightly softer
- edges may look different
- subpixel rendering may occur
This is normal in some situations.
It is not always a mistake.
Practical animation mindset
For most modern UI animation, transform is your best friend.
Especially:
xyscalerotationopacity
These are among the most common GSAP properties you will use.
2.4.8 Transform origin
What transform origin means
If transform changes an element, transform-origin defines the point from which the transformation happens.
This is another critical concept.
Example:
- If you scale an element, from where does it grow?
- If you rotate an element, around which point does it turn?
That is controlled by transform-origin.
Default behavior
By default, transforms usually happen around the center of the element.
So if you scale something up, it grows outward from the center.
That is often fine, but not always what you want.
Example
.box {
transform-origin: center center;
}
This means the center is the pivot point.
Other examples:
.box {
transform-origin: top left;
}
.box {
transform-origin: bottom center;
}
Why this matters for animation
If the transform origin is centered, it will grow in both directions.
If the transform origin is left center, it grows from left to right.
That changes the feel completely.
Example: reveal line
.line {
transform: scaleX(0);
transform-origin: left center;
}
Then animate to full width.
Now it feels like a line drawing from left to right.
If origin were center, the line would expand both ways.
Example: card flip or hinge-like effect
If you rotate an element and want it to feel like a door opening, the origin should often be on one edge:
.panel {
transform-origin: left center;
}
Then rotation feels like a hinge.
Common use cases
Transform origin is very important for:
GSAP and transform origin
GSAP can control transform origin directly.
Example:
gsap.to(".line", {
scaleX: 1,
transformOrigin: "left center",
duration: 0.6
});
This is very useful because you can define not only what changes, but also how it feels spatially.
Beginner mistake
A lot of people scale or rotate something, then say:
- “Why is it growing from the wrong point?”
- “Why does it not swing naturally?”
- “Why does this reveal look weird?”
The answer is often: wrong transform origin.
2.4.9 Z-index
What z-index means
z-index controls the stacking order of overlapping elements.
Think of it as deciding which element appears:
- in front
- behind
The higher value is generally placed above the lower value.
Example:
.box-a {
z-index: 1;
}
.box-b {
z-index: 2;
}
Here .box-b will appear in front of .box-a, assuming they overlap and positioning conditions are met.
Why z-index matters for animation
Animations often involve overlapping elements:
- modals over content
- text over images
- decorative shapes behind headings
- cards passing over each other
- menus opening above sections
- overlays fading in over the page
If layering is wrong, the animation may technically work but look broken.
Very important: z-index does not work in isolation
This is a huge beginner issue.
z-index usually matters on elements that are positioned, such as:
relativeabsolutefixedsticky
If an element is not participating in the right stacking context behavior, changing z-index may appear to do nothing.
Example
.card {
position: relative;
z-index: 2;
}
This makes more sense than setting z-index on a fully static element and expecting overlap behavior automatically.
Overlapping example
<div class="section">
<div class="background-shape"></div>
<h2 class="title">Hello</h2>
</div>
.section {
position: relative;
}
.background-shape {
position: absolute;
z-index: 1;
}
.title {
position: relative;
z-index: 2;
}
Now the title sits above the shape.
Why this matters for animated overlays
Imagine you animate a modal:
gsap.to(".modal", {
opacity: 1,
scale: 1,
duration: 0.5
});
If the modal has the wrong z-index, it may appear behind page content.
Then it looks like your animation failed, even though the real issue is stacking.
Stacking contexts
This is a more advanced topic, but you should at least know the term.
A stacking context is like a local layering world.
Sometimes an element with a high z-index still appears underneath another element because they belong to different stacking contexts.
This is one of the most frustrating CSS issues for beginners.
You do not need full mastery yet, but remember:
- z-index is not always globally simple
- parent elements can affect stacking behavior
- transforms and positioned ancestors can create unexpected layering situations
Simple beginner debugging rule
If z-index is not working:
- Check whether the element has a positioning value like
relativeorabsolute - Check whether a parent creates a stacking context
- Check whether another overlapping element is in a different stacking context
- Inspect the parent structure, not just the single element
How all of these concepts connect to GSAP and Glaze
Now let’s connect the CSS fundamentals directly to animation tools.
With GSAP
GSAP commonly animates:
xyscalerotationopacityclip-like reveal setups through CSS structure- timing and sequencing
But GSAP depends on CSS for:
-
Selecting the right element
- classes and IDs
-
Understanding element relationships
- nesting and hierarchy
-
Knowing how the element behaves in layout
- display types
-
Establishing reference points
- positioning
-
Clipping animation visually
- overflow
-
Moving and resizing smoothly
- transform
-
Defining pivot behavior
- transform origin
-
Layering elements correctly
- z-index
Without these, GSAP animation becomes trial-and-error.
With them, GSAP becomes logical.
With Glaze
Because Glaze simplifies GSAP usage, it can feel “easier” at first — and it is easier in many cases.
But Glaze still relies on the same underlying browser behavior.
So even if Glaze lets you apply animation more simply, you still need to understand:
- why an element is not visible
- why movement gets clipped
- why an item overlaps incorrectly
- why a reveal effect leaks out of its container
- why scale comes from the wrong point
So this CSS knowledge is just as important with Glaze as with raw GSAP.
A simple real-world example combining many concepts
Let’s imagine a card with an image and title animation.
HTML
<div class="card">
<div class="card-image-wrap">
<img class="card-image" src="image.jpg" alt="">
</div>
<h3 class="card-title">Project Title</h3>
</div>
CSS
.card {
position: relative;
}
.card-image-wrap {
overflow: hidden;
}
.card-image {
display: block;
width: 100%;
transform-origin: center center;
}
.card-title {
position: relative;
z-index: 2;
}
GSAP idea
gsap.from(".card-image", {
scale: 1.2,
duration: 1.2
});
gsap.from(".card-title", {
y: 30,
opacity: 0,
duration: 0.8
});
What CSS concepts are involved here?
-
Classes
.card,.card-image,.card-title
-
Nesting and hierarchy
- image is inside image wrapper
- wrapper is inside card
-
Display
- image is
display: block
- image is
-
Positioning
- card and title can participate in layering
-
Overflow
- image wrapper clips scaled image
-
Transform
- image scales
- title moves with
y
-
Transform origin
- image scales from center
-
Z-index
- title stays above visual content if needed
This is why CSS fundamentals are the base of motion design on the web.
Practical beginner rules you should remember ✅
If you remember nothing else from this lesson, remember these:
-
Use classes for most animation targets
- They are reusable and flexible.
-
Use IDs only for truly unique elements
- Don’t overuse them.
-
Always pay attention to parent-child structure
- Animation behavior often depends on wrappers.
-
Know the display type of the element
- Especially for text, spans, flex items, and hidden elements.
-
Use CSS positioning to define spatial relationships
- Especially
relativeon parents andabsoluteon children.
- Especially
-
Check overflow when something is clipped or leaking
- This is one of the most common issues.
-
Use transforms for movement and scaling
- This is the heart of smooth GSAP animation.
-
Set transform origin intentionally
- Especially for scaling and rotation.
-
Use z-index carefully when things overlap
- And remember that stacking contexts exist.
Typical animation debugging checklist 🛠️
When an animation doesn’t behave correctly, ask:
-
Am I targeting the correct element?
- Class or ID typo?
- Wrong selector?
-
Is the element nested inside a parent affecting it?
- Wrapper issue?
- Wrong hierarchy?
-
What is its display type?
- Is it inline when it should be inline-block or block?
- Is it
display: none?
-
Is positioning affecting placement?
- Does the child need an ancestor with
position: relative?
- Does the child need an ancestor with
-
Is overflow clipping the animation?
- Or should overflow be hidden and currently isn’t?
-
Am I animating transform-related properties?
- Better than top/left in many cases.
-
Is transform origin correct?
- Is it growing, rotating, or revealing from the right point?
-
Is z-index or stacking context the real problem?
- Is it behind something else?
This checklist alone will save you a lot of time.
Final summary
These CSS concepts are not “extra theory.” They are the practical mechanics behind animation.
GSAP gives you powerful control over motion.
Glaze gives you simpler ways to apply that motion.
But CSS determines:
- what the element is
- where it is
- how it behaves
- how it is clipped
- how it moves
- where it pivots
- what sits in front
So if you want to become confident with GSAP and Glaze, mastering these CSS basics is one of the smartest things you can do first.