You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CSS实现:仅Y轴重叠的Div自适应平分容器宽度

Solution for Overlapping Schedule Events with Dynamic Width Adjustment

Hey there! I get exactly what you're going for with this schedule app—you want events that overlap vertically to split the available width evenly, while non-overlapping ones take the full container width. The issue with your current flex setup is that CSS can't natively detect when elements are overlapping and adjust their widths automatically. We'll need a bit of JavaScript to calculate those overlaps first, then apply the right styles.

Here's a step-by-step solution:

1. Tweak the Base CSS

First, let's adjust your existing CSS to lay the right foundation:

  • Set the .events container to position: relative so absolute-positioned events are anchored to it
  • Remove the display: flex from .events (we're using absolute positioning for events now)
  • Add box-sizing: border-box to events so padding doesn't mess up width calculations
.schedule-body {
  position: relative; /* Ensures the events container sits correctly alongside hours */
}

.hours {
  /* Keep your existing hours styling here */
}

.events {
  position: absolute;
  top: 0;
  right: 5%;
  width: 75%;
  height: calc(20% * 24);
  z-index: 2;
  position: relative; /* Critical for absolute event positioning */
}

.events div {
  position: absolute;
  background-color: rgba(0, 188, 140, .5);
  border-radius: 0.5rem;
  z-index: 2;
  box-shadow: 0 0 2rem .4rem rgba(0, 0, 0, 0.5);
  display: flex;
  flex-wrap: wrap;
  padding-top: 5%;
  font-size: 1rem;
  justify-content: center;
  box-sizing: border-box; /* Includes padding/border in width calculations */
}

2. Add JavaScript to Calculate Overlaps

This script will handle the heavy lifting: it detects overlapping events, counts how many are in each overlapping group, then sets their width and left position accordingly.

function adjustEventLayout() {
  const events = document.querySelectorAll('.events div');
  // Collect position data for each event relative to the container
  const eventDetails = Array.from(events).map(event => {
    const containerRect = document.querySelector('.events').getBoundingClientRect();
    const eventRect = event.getBoundingClientRect();
    return {
      element: event,
      top: eventRect.top - containerRect.top,
      bottom: eventRect.bottom - containerRect.top,
      height: eventRect.height
    };
  });

  // Loop through each event to find overlapping peers
  eventDetails.forEach(currentEvent => {
    // Find all events that overlap vertically with the current one
    const overlappingGroup = eventDetails.filter(otherEvent => {
      return currentEvent.top < otherEvent.bottom && currentEvent.bottom > otherEvent.top;
    });

    // Sort the group by top position to arrange left-to-right correctly
    overlappingGroup.sort((a, b) => a.top - b.top);
    const eventPositionInGroup = overlappingGroup.findIndex(e => e.element === currentEvent.element);
    const groupSize = overlappingGroup.length;
    const widthPercent = 100 / groupSize;

    // Apply calculated width and left offset
    currentEvent.element.style.width = `${widthPercent}%`;
    currentEvent.element.style.left = `${eventPositionInGroup * widthPercent}%`;
  });
}

// Run on page load
window.addEventListener('load', adjustEventLayout);
// Call this function every time you add/update events dynamically

3. How to Use It

When adding events to the .events container, just set their top and height styles to position them (values are percentages of the .events container's height). Then call adjustEventLayout() to update the layout.

Example Event Markup

<div class="events">
  <!-- Single event (takes full width) -->
  <div style="top: 0%; height: 10%;">Morning Standup</div>
  <!-- Two overlapping events (each takes 50% width) -->
  <div style="top: 12%; height: 8%;">Project Sync</div>
  <div style="top: 15%; height: 10%;">Client Check-In</div>
  <!-- Three overlapping events (each takes ~33.3% width) -->
  <div style="top: 25%; height: 12%;">Team Lunch</div>
  <div style="top: 28%; height: 10%;">Design Review</div>
  <div style="top: 30%; height: 8%;">Code Walkthrough</div>
</div>

Key Details

  • The script uses getBoundingClientRect() to get accurate, relative positions for each event
  • Overlapping events are sorted by their top position to ensure clean left-to-right layout
  • box-sizing: border-box prevents padding from making events overflow their assigned width

This setup will dynamically adjust your event widths whenever the page loads or you add new events, ensuring overlapping events don't block each other and non-overlapping ones use the full available space.

内容的提问来源于stack exchange,提问作者Niko Nikolopoulos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 12:52:55