【问题标题】:HTML position variableHTML 位置变量
【发布时间】:2025-12-24 14:00:17
【问题描述】:

我知道使用 Javascript 很容易,但是……有什么办法只使用 CSS 吗?

假设我们在父元素(米色)中有两个元素(绿色和红色)。红色元素应始终位于绿色元素的右侧,除非绿色元素(由于内容)太大而无法容纳父元素,在这种情况下,红色元素将超过绿色元素(正常行为是红色元素停留在绿色元素的右侧,因此由于父元素的溢出而被隐藏)

换句话说:red.x = min(green.x + green.w, beige.x+beige.w-red.w)

更多信息,这里是具体的 HTML:

<div class="beige" style="width:250px"> <!-- parent with a given width (unknown until the page is rendered) & overflow hidden -->
  <a class="green"> <!-- link with display:inline -->
    content
    <em class="red"></em> <!-- actually a button, 15 px width -->
  </a>
</div>

编辑: @kyledws 的答案很棒,但我会用更多信息(需要的东西)更新问题,例如:

  • 只有在 green:hover 时才会显示红色(这就是它在绿色内部的原因)
  • 您不知道 CSS 中的米色宽度(在现实世界中,米色在具有定义宽度但在页面渲染之前不知道的内部)
  • 绿色内容为变长文本,红色被推送的原因
  • 如果绿色内容不适合父级,则应显示省略号(文本溢出:省略号;溢出:隐藏)
  • 必须在 IE8+ 中工作

【问题讨论】:

  • 可以将em.red 移到a.green 之外还是完全不改变结构?
  • 对于这个应用程序,语义上最好将 em 放在 a 中,因为在现实世界中,em 是在新窗口中打开链接的按钮,但我想你可以将它移出如果有帮助...

标签: html css


【解决方案1】:

如果您能够将&lt;a&gt; 中的内容包装在span 中,那么试试这个。

HTML

<div class="beige">
    <a class="green" href="#">
      <span class="content">This is some text.</span><em class="red"></em>
    </a>
</div>

CSS

.beige {
  background-color: #EBDFA0;
  height: 32px;
  overflow: hidden;
  border: 4px solid #EBDFA0;
  white-space: nowrap;
  width: 400px;
}

.green {
  background-color: #4CA73D;
  color: #222;
  display: inline-block;
  height: 100%;
  text-decoration: underline;
  vertical-align: middle;
}

.content {
  display: inline-block;
  height: 100%;
  margin-left: 4px;
  position: relative;
  width: 100%;
  max-width: 364px;
  top: -50%;
}

.red {
  border: 2px solid red;
  display: inline-block;
  height: 28px;
  position: absolute;
  width: 28px;
}

基本上&lt;a class="green"&gt;&lt;span class="content"&gt;&lt;em class="red"&gt; 必须是display: inline-block&lt;span class="content"&gt; 必须是width: 100%max-width &lt;div class="beige"&gt; 和@987654335 之间的差异@ 减去任何额外的填充/边距/边框等(因此在本例中,max-width: 364px)通过在span 上设置宽度,您可以强制将em 置于其容器之外,但通过设置max-width,您可以停止em 来自主包装之外。

这是一个示例的codepen.io 链接。

(注意:上面的大部分 CSS 只是为了让示例看起来像您的图像。)

更新:

  1. 要显示或隐藏&lt;em class="red"&gt;,请将:hover 伪类添加到.beige,并将可见性或不透明度添加到.red。 (如果要使用过渡,请使用不透明度。)

    .red {
      opacity: 0;
    }
    
    .beige:hover .red {
      opacity: 1;
    }
    
  2. 因为&lt;div class="beige"&gt;的宽度未知,所以不能使用CSS在&lt;span class="content"&gt;上设置max-width

    max-width: calc(100% - 28px) 中的 100% 是 &lt;a class="green"&gt; 而不是 &lt;div class="beige"&gt; 的宽度。我也无法使用伪元素、定位、浮动或不同的显示类型(如 flex)来破解它。)

    解决方法是在CSS中修复&lt;span class="content"&gt;max-width(如上图)或者使用Javascript检测&lt;div class="beige"&gt;的宽度,然后设置max-width

    content.style.maxWidth = beige.clientWidth - red.clientWidth + "px";
    

我用可见性和 Javascript 版本更新了 example

另外,我在.red 中添加了position: absolute,所以&lt;span class="content"&gt; 右侧没有空白空间。

【讨论】:

  • 很棒的答案! codepen.io 也像一个魅力。只是一件事:如果您在 CSS 时不知道米色宽度怎么办?您可以通过 javascript 获取它并更新最大宽度,但同样,有没有 CSS-only 方法?
  • IE8 不支持 CSS calc,但无论如何我会接受你的回答,因为它对其他人有用,因为它非常完整! Anyawys,随时改进它;)
【解决方案2】:

所以我找到了一种只用 CSS 就可以处理这个问题的方法。我已经用一个例子设置了一个 jsbin。我没有花哨的滑块,所以您需要使用检查器工具来调整宽度或手动调整。

基本上,我将潜水设置为一张桌子。因为你不能放到不同的行,所以最右边的列被强制折叠,但因为它是绝对位置,所以块可见。容器的大小基于已更改为内联块以保持着色并推动其父级变大的块。请原谅我没有使样式与您在图形中的样式完全匹配。

http://jsfiddle.net/93u5E/3/

HTML

    <div class="beige">
     <div class="table">
      <!-- parent with a given width & overflow hidden -->
    <ul>
        <li><a class="green"> <!-- link with display:inline -->
    content
  </a>
        </li>
        <li><em class="red"></em> 
            <!-- actually a button, 15 px width -->
        </li>
    </ul>
    </div>
</div>

CSS

.beige {
    background-color:grey;
    overflow:hidden;
    white-space:no-wrap;
}

.table{
    display:table;
}

ul {
    display:table-row;
    list-style-type:none;
}
li {
    display:table-cell;
    position:relative;
}

li:last-child{
    width:30px;
}
.green {
    display:inline-block;
    background-color:green;
}
.red {
    border:3px solid red;
    display:inline-block;
    width:20px;
    position:absolute;
    right:0px
}
li:hover + li .red{
height:20px;
}

*更新以包括悬停

【讨论】:

  • 如果内容继续扩展,最后红色元素被“推”并变得不可见:S 此外,“nowrap”实际上是“nowrap”。我更新了你的小提琴来展示它:jsfiddle.net/93u5E/4 BTW 你不需要滑块来改变绿色层的长度,只需修改内容文本。