固定放置元素,但在元素之前考虑伪

Fixed placement of element, but considering pseudo before element

我对表单的 html 布局有一个烦人的问题。我不能真正改变一般设置,因为它是一个巨大框架的一部分。但是我要"move"一个按钮到一个更合适的位置。我很接近,但到目前为止对解决方案不满意。也许你可以给我一些想法。这是一个非常简化的版本来展示我的方法:

我有两个容器 div,顶部和底部。 顶部容器在左侧显示一个按钮。该按钮是固定的,但由于其标签的翻译可能具有不同的宽度。 底部容器装有很多东西。其中顶部的第二个按钮工作正常,但看起来不对。我想将它以光学方式移动到顶部容器中,因为那里有一个到按钮的逻辑连接。当然,真的把它放在那儿才是正确的解决方案,但我目前做不到。相反,我使用固定位置,效果很好,但水平放置除外。我必须决定从左边推多远来放置按钮,这样它肯定不会与容器中的第一个按钮重叠。我显然必须考虑所有翻译,结果有效,但根据第一个按钮标签,我在两个按钮之间有一个恼人的水平间隙。

我尝试在第二个按钮上使用伪元素 (::before) 来帮助布局。因为在渲染视图时我显然有第一个按钮的翻译标签我可以将它复制到第二个按钮的一些 属性 并在我的 css 中使用那个 属性 来填充之前的伪第二个按钮的元素与第一个按钮的长度完全相同。这就是下面发布的代码示例中显示的内容。

我完全没能做到的是将伪元素放置在顶部容器中(正好在第一个按钮下方)。这个想法是间接地以这种方式放置第二个按钮。显然,这似乎是不可能的。但由于我是标记和样式方面的初学者,我认为在这里可能值得一问...


下面是一些彻底精简的代码来演示我的方法。

我创建了一个 jsfiddle 供您使用。这是代码:

HTML:

<div id="top-container">
    <button>multilingual button text</button>
</div>

<div id="bottom-container">
    <h2>
        Some title opening the bottom container
        <span class="into-top-container">
            <button id="place-me" reference-text="multilingual button text">button to be placed</button>
        </span>
    </h2>
    <p>Some content</p>
    <p>Some content</p>
    <p>Some content</p>
</div>

CSS:

body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}
div {
    margin: 0;
    padding: 5px;
}
button {
    margin: 0;
    padding: 5px;
    white-space: nowrap;
}


div#top-container {
    width: 100%;
    border: 1px solid green;
}

div#bottom-container {
    width: 100%;
    border: 1px solid blue;
}

#place-me {
    position: fixed;
    top: 0;
    left: 400px;
    margin: 5px;
    background: yellow;
}

#place-me::before {
    z-index: 0;
  /*visibility: hidden;*/
    position: absolute;
    content: attr(reference-text);
    margin: 0 5px;
    padding: 0;
    background: gold;
    right: 100%;
}

备注:


应要求提供截图:

取自我上面发的fiddle。我添加了红色椭圆,它显示了我要移动的元素对,左箭头指示我也想将其移动到哪里。我想把它移动到那么远,两个测试 "multilingual button text" 正好放在彼此之上,但是 没有 显然指定一个显式的左侧放置。这就是伪元素存在的原因:作为虚拟占位符。然后我会隐藏那个伪元素并将第二个按钮放在第一个按钮的右边,不管那里的翻译文本有多长。

所以最终结果应该是这样的:

好的,我投入了更多时间,因为这个问题在我们的代码回归后再次出现,我发现,在允许一段时间后,一个合乎逻辑且相对干净的解决方案:

我使用相同的精简代码来进行演示。

jsfiddle 基于问题本身提供的那个。

HTML:除了 reference-text 从按钮移动到容器外,没有真正的变化,原因见下文:

CSS:

* {
    font-size: 12px;
    font-weight: normal;
    font-family: Arial;
}

body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    font-size: 12px;
    font-weight: normal;
}
span,
div {
    margin: 0;
    padding: 5px;
}
button {
    margin: 0;
    padding: 5px;
    white-space: nowrap;
}


div#top-container {
    width: 100%;
    border: 1px solid green;
}

div#bottom-container {
    width: 100%;
    border: 1px solid blue;
}

span.into-top-container {
    position: fixed;
    top: 0;
    left: 0;
    pointer-events: none;
    border: 1px solid transparent;
}

span.into-top-container::before {
    visibility: hidden;
    content: attr(reference-text);
    position: relative;
    margin-right: 5px;
    padding: 5px;
    border: 2px solid;
    background: gold;
}

#place-me {
    background: yellow;
    pointer-events: all;
}

策略上的基本变化:必须以固定方式放置包含要放置的按钮的容器,而不是按钮本身(所以 <span class="into-top-container">)!这允许使用伪 before 元素,现在也锚定到该容器,而不是按钮,根据需要获取 space 而无需实际获取按钮本身的一部分。

由于该容器现在位于无法再点击的原始多语言按钮之上。该问题已通过将容器的 css pointer-events 设置为 none 并再次将放置的按钮设置为 all 来解决。这使得容器本身简单地忽略所有事件(点击)并将它们传递给下面的原始按钮。

我必须确保伪元素内使用的字体与原始多语言按钮的样式完全相同。这实际上是有道理的,因为字体样式定义了该按钮使用的实际宽度,所以伪元素使用的实际宽度应该以完全相同的方式定义。在上面的示例中,我通过简单地将所有元素字体样式规则设置为一些固定值(CSS 代码中的初始 * {...})来强制执行此操作。这显然也可以在伪元素本身的 css 规则内完成。我在这里选择了更简单和粗暴的变体来保持代码干净。