英文:
Two span in same line
问题
我有一个包含两个 "span" 的 "div"。
一个 "span" 接受用户输入的文本并将其发送到后端以生成下一个文本(类似于自动完成)。
第二个 "span" 是模型生成的文本的返回,它将提供一个补充建议。如下图所示。
问题是有时第二个 的文本被覆盖,影响可视化。我想找到一种方法将第二个 "span" 的文本放在第一个 "span" 的前面。
我已经尝试在第二个 "span" 中使用 "padding-left",但某个时候第一个 "span" 会覆盖它。
以下是代码:
HTML:
<template>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div class="pad-container">
<div tabindex="1" @focus="setCaret" class="divAutocomplete">
<span @input="sendText" @keypress="preventInput" ref="editbar" class="editable" contenteditable="true" placeholder='Digite sua busca'></span>
<span class="placeholder" data-ondeleteId="#editx" contenteditable="false">{{String_Text}}</span>
</div>
</div>
</template>
CSS:
<style scoped>
.pad-container {
padding: 0;
width: 640px;
border-radius: 12px;
border: medium solid;
border-color: #0072c6;
}
.divAutocomplete {
font-family: "Crete Round";
font-size: 16px;
border-radius: 8px;
height: 32px;
width: 100%;
text-align: left;
position: relative;
background-color: hwb(244 16% 17% / 0.1);
caret-color: #0072c6;
color: #0072c6;
}
span {
display: block;
min-width: 1px;
outline: none;
}
.editable {
position: absolute;
left: 8px;
top: 5px;
text-transform: lowercase;
}
.placeholder {
color: gray;
position: absolute;
left: 8px;
top: 5px;
z-index: -1;
}
</style>
"String Text" 是简单的文本,比如 "Hello World" 或 "Welcome to the White House"。如果可能的话,我希望它看起来像这样:
这样,当用户输入文本时,第二个 "span" 会保留在第一个 "span" 之间的空间。
英文:
I have a "div" that has two "span".
A "span" takes the text typed by the user and sends it to the backend to generate the following text (similar to autocomplete).
The second "span" is the return of the text generated by the model, which would be a complement suggestion. As you can see in the figure below.
The issue is that sometimes the text of the second <span> is overwritten and embarrassing the visualization. I would like to see a way to put the text of the second "span" in front of the first "span".
I've already tried to use "padding-left" in the second "span", but at some point the first "span" overwrites it.
Below are codes:
HTML -->
<template>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div class="pad-container">
<div tabindex="1" @focus="setCaret" class="divAutocomplete">
<span @input="sendText" @keypress="preventInput" ref="editbar" class="editable" contenteditable="true" placeholder='Digite sua busca'></span>
<span class="placeholder" data-ondeleteId="#editx" contenteditable="false">{{String_Text}}</span>
</div>
</div>
</template>
CSS -->
<style scoped>
.pad-container {
padding: 0;
width: 640px;
border-radius: 12px;
border: medium solid;
border-color: #0072c6;
},
.divAutocomplete {
font-family: "Crete Round";
font-size: 16px;
border-radius: 8px;
height: 32px;
width: 100%;
text-align: left;
position: relative;
background-color: hwb(244 16% 17% / 0.1);
caret-color: #0072c6;
color: #0072c6;
},
span {
display: block;
min-width: 1px;
outline: none;
},
.editable {
position: absolute;
left: 8px;
top: 5px;
text-transform: lowercase;
},
.placeholder {
color: gray;
position: absolute;
left: 8px;
top: 5px;
z-index: -1;
}
</style>
"String Text" is simple text such as "Hello World" or "Welcome to the White House". I would like it to look like this if possible:
So that, when the user types the text, the second "span" would keep the space between the first "span"
答案1
得分: 2
保持建议与可编辑文本保持恒定距离的方法是:
- 从子元素中删除
position: absolute
, - 给父元素添加
display: flex
, - 给第二个子元素添加
display: inline-block
和适量的左内边距。
如果你希望建议显示在可编辑文本之前,添加以下样式:
flex-direction: row-reverse;
justify-content: flex-end;
并将建议的 padding-left
移动到 padding-right
。
此外,你还可以在DOM中交换它们的位置(这意味着唯一的额外规则将是建议的内边距方向的改变)。
最后,你应该避免在创建UI时重新发明轮子。解决你试图解决的UI问题的直观模式是在可编辑元素下方打开一个可滚动的下拉选择器,并通过上/下箭头让建议可访问。当用户选择建议并按下回车键时,输入的值将更改为所选建议,而不会失去焦点。
你还应该注意,contenteditable
元素可能在某些设备上带来无障碍挑战,而在某些国家的公共网站上使用可能构成违法行为。你可能更喜欢完全可访问的 <input />
元素。
英文:
To keep the suggestion at a constant distance from the editable text you have to:
- remove
position: absolute
from children, - give parent
display: flex
, - give the second child
display: inline-block
and a minor left padding
That's about it:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.parent {
padding: 1rem;
border-radius: 12px;
border: medium solid;
border-color: #0072c6;
display: flex;
}
.editable {
min-width: .5rem;
background-color: hwb(244 16% 17% / 0.1);
caret-color: #0072c6;
color: #0072c6;
font-weight: bold;
outline: none;
}
.suggestion {
padding-left: .5rem;
display: inline-block;
}
<!-- language: lang-html -->
<div class="parent">
<div class="editable" contenteditable>This is the editable text...</div>
<div class="suggestion">This is the dynamic suggestion...</div>
</div>
<!-- end snippet -->
If you want the suggestion displayed first, add
flex-direction: row-reverse;
justify-content: flex-end;
to parent and move the padding-left
on the suggestion to padding-right
.
Alternatively, you could switch their position in DOM (which would mean the only extra rule would be the change of padding side on the suggestion).
Note this will keep the two children side by side even when any of them has to wrap:
<!-- begin snippet: js hide: true console: true babel: false -->
<!-- language: lang-css -->
.parent {
padding: 1rem;
border-radius: 12px;
border: medium solid;
border-color: #0072c6;
display: flex;
}
.editable {
min-width: .5rem;
background-color: hwb(244 16% 17% / 0.1);
caret-color: #0072c6;
outline: none;
}
.suggestion {
padding-left: .5rem;
display: inline-block;
}
<!-- language: lang-html -->
<div class="parent">
<div class="editable" contenteditable>
Kitty scratches couch bad kitty do doodoo in the litter-box, clickityclack on the piano, be frumpygrumpy why use post when this sofa is here, instead of drinking water from the cat bowl, make sure to steal water from the toilet cat gets stuck in tree firefighters try to get cat down firefighters get stuck in tree cat eats firefighters' slippers freak human out make funny noise mow mow mow mow mow mow success now attack human
</div>
<div class="suggestion">This is the dynamic suggestion...</div>
</div>
<!-- end snippet -->
Last, but not least, you should avoid re-inventing the wheel when creating UI. The intuitive pattern for the UI problem you're trying to solve is to open a scrollable drop-down selector under the editable element, and make the suggestions accessible via up/down arrows. When the user selects a suggestion and presses enter, the input's value is changed to the selected suggestion, without losing focus.
You should also note that contenteditable
elements might create accessibility challenges on certain devices which, in some countries, is an offence when used on public websites. You might prefer fully accessible <input />
elements.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论