css 如何防止:after元素脱离其div?(不使用溢出:hidden;)

cpjpxq1n  于 2023-05-19  发布在  其他
关注(0)|答案(3)|浏览(169)

我不问问题,所以我不知道我是否正确地标记了代码。
我正在制作一个伪聊天客户端,它仅用于显示目的。我一直在尝试添加一个假的“打字区”和一个“发送按钮”,一起我已经标记为“打字栏”。在测试时,我注意到当“screen”/viewport太窄时,“send button”会从div容器中跳出。

.typebar {
    min-width: 0;
    max-width: 620px;
    max-height: 40px;
    margin-left: auto;
    margin-right: auto;
    border: 5px solid red;
    display: flex;
    position: relative; 
    }

.typebar:before {
    content: '';
    border: 5px solid #566573;
    padding: 26px 85% 0 0;
    background: #eeeeee; 
    position: relative;
    float: left;
    cursor: text;
    }

.typebar:after {
    content: 'PESTER';
    font-weight: 600;
    border: 5px solid #566573;
    padding: 5px;
    margin-left: 1%;
    color: #eeeeee;
    background: #2C3E50;
    position: relative;
    float: right;
    cursor: pointer;
    }
<div class="typebar"></div>

问题是这样的。我添加了一个红色边框,以查看div容器应该在哪里结束。
这是它在“全景”中的样子。

下面是屏幕太窄时会发生的情况。(我确信与这个项目互动的人大多会在移动的上,这就是为什么这对我很重要。
如果可能的话,我需要一种方法来使“before”元素可以更快地“最小化”(如果有意义的话),以防止“after”元素从div中引导出来。(AKA,保持在所需宽度%)
添加overflow: hidden;确实可以将其保留在div中,但代价是“send”元素中的一些字母变得......隐藏起来!不能在“打字区”使用,因为没有内容,只有填充。
尝试给予“before”元素一个max-height和max-padding,但是当屏幕变得太窄时,它根本不想停留在正确的百分比。
尝试使用“vw”单位(似乎最大宽度在这里不适用),这只会导致两个元素都从div中取出。
我还尝试将before和after元素放入它们自己的独立类中(我最初没有这样做的原因是为了在HTML部分使其更精简),希望它们作为自己的类可能会有不同的行为。不!我使用了相同的代码,除了“after”类中的一个微小变化(content: '';content: "";)。
如果一切都失败了,我可以诉诸于只是扔在毛巾,并简单地添加一个.png的“输入栏”,(或删除此区域完全,只是有聊天客户端显示的消息本身),但我真的不想这样做。

1szpjjfi

1szpjjfi1#

如前所述,在这里使用:before和:after是不必要的,而且会适得其反。但你也没有充分利用Flexbox的潜力。(或者Grid会是一个更好的选择,我认为。)无论如何,这里有一个快速的flex演示:

html {
  box-sizing: border-box;
}

*, *:before, *:after {
  box-sizing: inherit;

.typebar {
    min-width: 0;
    max-width: 620px;
    margin-left: auto;
    margin-right: auto;
    border: 5px solid red;
    display: flex;
    justify-content:space-between;
    }

.typebar .left {
    border: 5px solid #566573;
    background: #eeeeee; 
    cursor: text;
    flex-grow: 1;
    }

.typebar .right {
    font-weight: 600;
    border: 5px solid #566573;
    color: #eeeeee;
    background: #2C3E50;
    cursor: pointer;
    width: min-content;
    }

.left, .right {
  margin: 0;
}
<div class="typebar">
  <p class="left"></p>
  <p class="right">PESTER</p>
</div>
kx1ctssn

kx1ctssn2#

您可以给予位置:absolute to::before and::after伪元素withleft:0表示::beforeandright:0表示后的::,而不是float属性。下面是更新后的代码:-

.typebar {
    min-width: 0;
    max-width: 620px;
    max-height: 40px;
    margin-left: auto;
    margin-right: auto;
    border: 5px solid red;
    display: flex;
    position: relative; 
 }

.typebar:before {
    content: '';
    border: 5px solid #566573;
    padding: 26px 85% 0 0;
    background: #eeeeee; 
    position: absolute;
    left: 0;
    cursor: text;
 }

.typebar:after {
    content: 'PESTER';
    font-weight: 600;
    border: 5px solid #566573;
    padding: 5px;
    margin-left: 1%;
    color: #eeeeee;
    background: #2C3E50;
    position: absolute;
    right: 0;
    cursor: pointer;
 }
frebpwbc

frebpwbc3#

使用相对单位表示长度,如百分比、vw、vh等。而不是像px这样的绝对单位。在示例A示例B中,宽度均以vw为单位--每1vw =视口宽度的1%。
顺便说一句,在与用户的实际交互中使用伪元素(即::before::after)是一个坏主意,因为就HTML和JavaScript而言,它们并不存在--它们纯粹是样式的表现。只有以实际元素或样式为目标,才能间接影响伪元素。在Example B中,我添加了一些额外的CSS、HTML属性和JavaScript“keyup”事件处理程序,以展示::before区域如何模仿[contenteditable]元素。作为按钮进行交互的::after区域不包括在内(将涉及更多内容)。请记住示例B是额外的,不是问题解决方案的一部分。
简而言之,最好使用<input>[contenteditable]<button><input type="button">,然后将它们 Package 成一个block元素,如<div><section>

示例A

/**
 * vmin for font-size makes fonts responsive and is not required.
 * If the viewport height is less than it's width, then vh
 * is used and vice versa.
 */
:root {
  font: 5vmin/1.15 "Segoe UI";
}

.text {
  display: flex;
  width: 96vw;
  border: 5px solid red;
  overflow: hidden/* For demo purposes */;
  resize: both/* For demo purposes */;
}

.text::before {
  content: "";
  display: flex;
  align-items: center;
  width: 85vw;
  padding: 5px;
  border: 5px solid #566573;
  background: #eeeeee;
  cursor: text;
}

.text::after {
  content: 'PESTER';
  display: flex;
  justify-content: center;
  align-items: center;
  width: 10vw;
  margin-left: 1vw;
  padding: 2px;
  border: 5px solid #566573;
  font-weight: 600;
  color: #eeeeee;
  background: #2C3E50;
  cursor: pointer;
<div class="text"></div>

示例B

document.querySelectorAll(".text").forEach(txt => txt.onkeyup = type);

function type(e) {
  let txt = this.textContent;
  this.dataset.text = txt;
}
/**
 * vmin for font-size makes fonts responsive and is not required.
 * If the viewport height is less than it's width, then vh
 * is used and vice versa.
 */
 :root {
  font: 5vmin/1.15 "Segoe UI";
}

.text {
  display: flex;
  width: 96vw;
  border: 5px solid red;
  font-size: 0;
  overflow: hidden/* For demo purposes */;
  resize: both/* For demo purposes */;
}

.text::before {
  content: attr(data-text);
  display: flex;
  align-items: center;
  width: 85vw;
  padding: 5px;
  border: 5px solid #566573;
  font-size: 5vmin;
  background: #eeeeee;
  cursor: text;
}

.text::after {
  content: 'PESTER';
  display: flex;
  justify-content: center;
  align-items: center;
  width: 10vw;
  margin-left: 1vw;
  padding: 2px;
  border: 5px solid #566573;
  font-size: 5vmin;
  font-weight: 600;
  color: #eeeeee;
  background: #2C3E50;
  cursor: pointer;
}
<div class="text" data-text contenteditable></div>
<div class="text" data-text contenteditable></div>
<div class="text" data-text contenteditable></div>

相关问题