Full-Width Separator Issue Resolution
Full-Width Separator Issue Resolution
What We Were Trying to Do and Why
We needed to create separator elements that would span the full viewport width (100vw) while keeping the main content constrained to 92% of the viewport width. This is a common design pattern where content is contained within a max-width, but certain elements (like separators, hero backgrounds, etc.) need to "break out" of that container and span the full width of the viewport.
The challenge was that our separators were being constrained by their parent containers, which had a width of 94% or 92%, preventing them from reaching the full viewport width.
Incorrect Attempts
Attempt 1: Basic full-width class
Initially, we had a separator component with a simple full-width class:
astro
<!-- ThinGradientBleedSeparator.astro -->
<div class="full-bleed separator--primary-bg-grd"></div>
<style>
.separator--primary-bg-grd {
width: 100vw !important;
margin-left: 0 !important;
margin-right: 0 !important;
left: 50%;
right: 50%;
transform: translateX(-50%);
height: 2px;
background: var(--grd__primary-bg);
position: relative;
}
</style>
This worked for separators that were placed outside of constrained containers, but failed for those inside the
main-content-col
div which had a width of 94%.Attempt 2: Restructuring the content layout
We tried restructuring the
MainContent.astro
file to move all separators outside of content containers: astro
<ThinGradientBleedSeparator />
<div id="main-content-col">
<section>
<!-- Content here -->
</section>
</div>
<ThinGradientBleedSeparator />
<div id="main-content-col">
<section>
<!-- More content here -->
</section>
</div>
This approach worked for some separators but was not a clean solution as it required duplicating the main content container for each section.
Attempt 3: Using a content wrapper approach
We tried a content-wrapper approach where we kept a consistent 92% width for content and let separators naturally span full width:
astro
<!-- Full-bleed separator -->
<ThinGradientBleedSeparator />
<!-- Content section with constrained width -->
<div class="content-wrapper">
<section>
<!-- Content here -->
</section>
</div>
But this still didn't work reliably because the separators weren't properly breaking out of the layout flow.
The "Aha!" Moment
Looking at the
ThreeColumnFrame.astro
layout, we discovered it already had a special CSS rule for full-bleed elements: css
/* Allow full-bleed elements to break out */
.main-content > :global(.full-bleed) {
width: 100vw !important;
margin-left: calc(30% - 50vw) !important;
margin-right: calc(30% - 50vw) !important;
left: 50%;
right: 50%;
transform: translateX(-50%);
position: relative;
}
But this wasn't working consistently. The key insight was that we needed a more reliable approach using absolute positioning to truly break out of the layout flow.
Final Solution
The solution that worked was to create a wrapper for the separator that maintains its place in the document flow, while the separator itself uses absolute positioning to break out of the container:
astro
<!-- ThinGradientBleedSeparator.astro -->
---
import "@styles/global.css";
---
<div class="separator-wrapper">
<div class="separator--primary-bg-grd"></div>
</div>
<style>
.separator-wrapper {
position: relative;
width: 100%;
height: 2px;
margin: 1rem 0;
overflow: visible;
}
.separator--primary-bg-grd {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 100vw;
height: 2px;
background: var(--grd__primary-bg);
}
</style>
This approach works because:
- The wrapper maintains its place in the document flow and provides the height needed
- The separator itself is absolutely positioned relative to its wrapper
- Using
left: 50%
andtransform: translateX(-50%)
centers the separator - Setting
width: 100vw
makes it span the full viewport width - The
overflow: visible
on the wrapper allows the separator to extend beyond its boundaries
This solution works consistently regardless of where the separator is placed in the document structure, making it much more robust and maintainable.
Related Components
The
MainContent.astro
component can now use the separator anywhere in its structure without worrying about layout constraints: astro
<section class="main-content-element">
<h2>Tools</h2>
<!-- Content here -->
<ThinGradientBleedSeparator />
<!-- More content here -->
</section>
This approach also aligns with our design system's goal of creating reusable, reliable components that work consistently across different contexts.