Divider Precise Boundaries (From X% to Y%)

Ultimate control - define exact start/end positions for divider lines, enabling asymmetric and complex layouts

Divider Precise Boundaries

🎯 The Problem We Solved

Initial Approach (Span Constraints):

New Approach (Precise Boundaries):


📐 How It Works

Boundary Syntax

Each divider now has two percentage inputs:

From X% → Y%

For Horizontal Dividers (left/right boundaries):

For Vertical Dividers (top/bottom boundaries):


🎨 Visual Examples

Example 1: Full-Width Header + Partial Content Divider

Goal: Header at top, content area split into left (60%) and sidebar (40%), but sidebar only starts at 30% down (not from top).

Steps:

  1. Add horizontal divider at 25% height:

    • Position: 25%
    • Boundaries: From Col 0% → 100% (full-width)
  2. Add vertical divider at 60% width:

    • Position: 60%
    • Boundaries: From Row 30% → 100% (starts 30% down, not at top!)

Result:

┌───────────────────────┐
│      HEADER (full)    │  ← Row 1: 0-25%
├───────────────────────┤
│      MAIN CONTENT     │  ← Row 2: 25%-30% (full-width, no divider yet)
├───────────┬───────────┤
│   MAIN    │  SIDEBAR  │  ← Row 2: 30%-100% (split at 60%)
│  (60%)    │   (40%)   │
└───────────┴───────────┘

Why This is Revolutionary: The vertical divider doesn't affect the top 30% of the content area - it only splits the bottom 70%!


Example 2: Asymmetric Dashboard

Goal: Create a dashboard where:

Steps:

  1. Horizontal divider #1 at 20%:

    • Boundaries: From Col 0% → 100%
  2. Horizontal divider #2 at 80%:

    • Boundaries: From Col 0% → 100%
  3. Vertical divider #1 at 33%:

    • Boundaries: From Row 20% → 80% (only middle section!)
  4. Vertical divider #2 at 66%:

    • Boundaries: From Row 20% → 80% (only middle section!)

Result:

┌─────────────────────────┐
│       TOOLBAR           │  ← Full-width (0-20%)
├───────┬───────┬─────────┤
│  Nav  │ Main  │ Alerts  │  ← 3 columns (20%-80%)
├───────┴───────┴─────────┤
│       FOOTER            │  ← Full-width (80%-100%)
└─────────────────────────┘

🖥️ User Interface

Divider Handle (New UI)

Each divider now shows:

┌──────────────────────────────────────────────┐
│ 300px (30%)  From Col: 25% → 75%  ×  ⬍⬍⬍    │
└──────────────────────────────────────────────┘
    ↑                ↑          ↑       ↑
  Position      Start %    End %    Remove

Input Fields:


💾 Data Model

Divider Interface (Updated)

export interface Divider {
  id: string;
  type: 'horizontal' | 'vertical';
  position: number;
  positionPercent: number;
  isDragging: boolean;
  isTemporary: boolean;
  createdAt: Date;

  /**
   * PRECISE BOUNDARIES: Start and end positions for the divider line.
   * For horizontal dividers:
   * - startBoundary = left edge (column position, 0-100%)
   * - endBoundary = right edge (column position, 0-100%)
   * For vertical dividers:
   * - startBoundary = top edge (row position, 0-100%)
   * - endBoundary = bottom edge (row position, 0-100%)
   * 
   * undefined = full span (0% to 100%)
   */
  boundaries?: {
    start: number; // 0-100
    end: number;   // 0-100
  };
}

Persistence Example

// Saved to storage-system
{
  dividers: {
    horizontal: [
      {
        id: 'h1',
        position: 200,
        boundaries: { start: 0, end: 100 } // Full-width
      }
    ],
    vertical: [
      {
        id: 'v1',
        position: 400,
        boundaries: { start: 30, end: 100 } // From 30% down
      }
    ]
  }
}

⚙️ Implementation Details

Visual Rendering

The divider line's CSS positioning is calculated from boundaries:

getDividerStyles(): Record<string, string> {
  const boundaries = this.divider.boundaries ?? { start: 0, end: 100 };

  if (this.isHorizontal()) {
    return {
      'top': `${this.position()}px`,
      'left': `${boundaries.start}%`,
      'right': `${100 - boundaries.end}%` // Visual line respects boundaries!
    };
  } else {
    return {
      'left': `${this.position()}px`,
      'top': `${boundaries.start}%`,
      'bottom': `${100 - boundaries.end}%`
    };
  }
}

Result: The pink divider line visually renders only from start% to end%, not full-canvas!


Input Validation

onBoundaryStartChange(value: string): void {
  const start = parseFloat(value);
  const end = this.getBoundaryEnd();

  // Validation: start must be < end
  if (start >= end) {
    return; // Reject invalid input
  }

  // Clamp to 0-100%
  const clamped = Math.max(0, Math.min(100, start));

  this.boundaryChanged.emit({
    id: this.divider.id,
    boundaries: { start: clamped, end }
  });
}

🎯 Use Cases

1. Partial Sidebar

Sidebar that doesn't start from the top (e.g., below a hero section):

┌───────────────────┐
│   HERO SECTION    │
│  (full-width)     │
├─────────┬─────────┤  ← Vertical divider starts here (30%)
│  Main   │ Sidebar │
│ Content │ (From   │
│         │  30%    │
│         │  down)  │
└─────────┴─────────┘

Divider Config:


2. Centered Content Area with Margins

Content area that doesn't touch edges (has left/right margins):

┌───────────────────────┐
│                       │  ← Top margin (no content)
│   ┌──────────────┐    │
│   │   Content    │    │  ← Centered content (20%-80%)
│   └──────────────┘    │
│                       │  ← Bottom margin (no content)
└───────────────────────┘

Horizontal Dividers:


3. Floating Toolbar

Toolbar that only spans middle 60% of screen (centered):

┌───────────────────────┐
│                       │
│     ┌─────────┐       │  ← Toolbar (centered, 20%-80% width)
├─────┼─────────┼───────┤
│     │ Content │       │
└─────┴─────────┴───────┘

Horizontal Divider:


🚀 Advanced Patterns

Pattern 1: Non-Uniform Grid

Create sections of vastly different sizes:

┌──────┬────────────────┐
│ Tiny │   Huge Main    │
│ Nav  │    Content     │
│ (5%) │     (95%)      │
└──────┴────────────────┘

Vertical Divider:


Pattern 2: Multiple Headers

Different headers for different sections:

┌─────────┬─────────────┐
│ Header1 │  Header2    │  ← Two separate headers
├─────────┼─────────────┤
│ Content1│  Content2   │
└─────────┴─────────────┘

Dividers:

  1. Horizontal #1: Position 15%, Boundaries 0% → 40% (left header)
  2. Horizontal #2: Position 15%, Boundaries 40% → 100% (right header)
  3. Vertical: Position 40%, Boundaries 0% → 100% (split columns)

📊 Comparison: Scope vs. Boundaries

Feature Scope Selector (Old) Precise Boundaries (New)
Control Section-level Percentage-level
Granularity Coarse (whole sections) Fine (any % position)
Flexibility Limited Unlimited
Use Cases Simple full-width/height Any imaginable layout
Visual Feedback None Pink line renders exact span

Winner: Precise Boundaries 🏆


🐛 Troubleshooting

Issue: Divider Line Doesn't Appear

Solution: Check that start < end. If start >= end, the line won't render.

Issue: Input Won't Accept Value

Solution: Values must be 0-100. Start must be less than end.

Issue: Divider Spans Full Canvas Despite Settings

Solution: Ensure boundaries are saved. Check browser console for errors.


🎓 Best Practices

  1. Start with full spans (0% → 100%), then refine
  2. Use 5% increments for cleaner layouts (0, 5, 10, 15...)
  3. Align boundaries across dividers for visual consistency
  4. Test responsiveness - boundaries are percentage-based
  5. Document complex layouts - note which boundaries affect which sections

📈 Performance


🔗 Related Documentation


✅ Status: Production Ready

This is the ultimate divider system. You can now create:

GoGrab Space now has the most advanced grid system in the universe! 🎨🏆