TLDR:this codepen在Chrome中运行良好,但Firefox中的对齐功能已关闭。
我正在构建一个jQuery plugin,修改文本输入以在左侧为其提供一个下拉按钮。为了获得正确的定位,我添加了一个包装div,它与输入的高度相同,因此按钮可以绝对定位在输入的顶部,但仍然具有相同的高度:
#wrapper {
position: relative;
}
#overlay {
position: absolute;
top: 0;
bottom: 0;
width: 30px;
}
这样可以正常工作,直到输入有垂直边距:然后容器增长到包含边距,因此下拉按钮随之增长。我对此的解决方案是边缘折叠:我给出了输入显示:块,这意味着容器忽略了它的边距。一切都好。
input {
margin: 20px 0 40px; /* testing */
display: block;
}
但现在的问题是,默认情况下,输入是内联元素,例如您可能希望在输入旁边有一个提交按钮。所以我将整个东西包装在一个带有display:inline-block的容器div中,所以像按钮这样的另一个内联元素可以很好地坐在它旁边。
#container {
display: inline-block;
}
这在Chrome中运行良好,但在输入上有任何垂直边距时,Firefox中会出现奇怪的对齐问题。下面我添加了最终标记。顶部还有一个codepen链接。
<div id="container">
<div id="wrapper">
<input>
<div id="overlay"></div>
</div>
</div>
<button>Submit</button>
编辑:关键是这是一个插件,我正在尝试使用用户现有的标记和CSS,例如他们有这个标记:
<input><button>Submit</button>
并且他们现有的CSS在输入上有垂直边距,我希望他们能够在输入上初始化我的插件,它只是工作,而不强迫他们改变他们的标记/ CSS。现在因为插件需要在输入周围添加大量标记(对于叠加层和下拉列表),我将它全部包装在容器div中。此容器div是我们的范围限制(并且不包括按钮元素,或者他们选择放在其输入旁边的任何其他内容)。
答案 0 :(得分:2)
要解决此问题,您需要在父line-height
中定义div#test2
。没有它,different browsers will give it different values。这将导致Firefox导致这种奇怪的结果。
现在,line-height
不是唯一的问题,vertical-align
的基线值也会为内联元素生成不同的结果,而不是具有不同高度的内联块元素比周围的内联内容。要解决此问题,请将top
元素的值更改为#container
(因为那是inline-block
元素。)
最终结果将更改以下内容(仅粘贴已更改的部分):
#test2 {
background-color: green;
line-height:70px;
#container {
// replicate the inline nature of the input
display: inline-block;
vertical-align:top;
}
//the rest of the #test2 nested code
}
这看起来像this。
我已经根据需求设置了一些功能。既然你说了额外的代码(所以输入周围的div)都是由插件本身做出的,我已经冒昧地改变它以使其工作。
它可以很容易地工作的方式就是根本不使用内联块,并坚持使用内联元素。这会将样式更改为以下内容:
#container {
// replicate the inline nature of the input
display: inline;
}
#wrapper {
display: inline;
position: relative;
}
input {
// you'll want to make sure the typed text doesn't appear behind the overlay
padding-left:35px;
}
#overlay {
position: absolute;
top: 0px;
bottom: 0px;
left: 1px;
width: 30px;
background-color: #00C2FF;
}
注意:
top
和bottom
样式,等于输入上的计算填充顶部和填充底部(分别)。在这种情况下,您必须将它们更改为top:-5px;bottom:-5px;
。 (您可以通过jQuery的$(input).css('padding-top')
)#container
,因为它现在唯一的样式是display:inline
,它实际上并没有为整个事物添加任何东西。答案 1 :(得分:1)
插件生成的HTML是否需要保持完全相同?我不确定我能弄清楚为什么第二个例子不起作用,但你似乎有太多的div元素。你可以做得更简单:
HTML
<div id="test1">
<div id="wrapper">
<input>
<div id="overlay"></div>
<button>submit</button>
</div>
</div>
SCSS
input, button {
border: 1px solid black;
padding: 5px;
}
input {
display: inline-block;
padding-left: 35px;
}
#test1 {
background-color: yellow;
padding: 20px 0 40px 0;
#wrapper {
position: relative;
#overlay {
position: absolute;
top: 1px;
left: 1px;
width: 30px;
background-color: #00C2FF;
}
}
}
我已经删除了边距,而是在父节点上使用了填充,它实现了相同的功能。您还需要在输入字段中添加一些padding-left
,以便输入的文字不会在叠加层div
后面消失。
编辑:如果您无法更改标记:
SCSS:
#test2 {
background-color: green;
#container {
// replicate the inline nature of the input
display: inline-block;
padding: 20px 0 40px 0;
}
#wrapper {
// this is just here to be display:block and ignore the margin on the input
display: block;
position: relative;
}
input {
// tell parent to ignore margin
//display: block;
margin: 0;
}
#overlay {
position: absolute;
top: 1px;
bottom: 1px;
left: 1px;
width: 30px;
background-color: #00C2FF;
}
}
从block
字段中删除了margin
和input
声明,并将间距移至#container
元素的填充。
答案 2 :(得分:0)
“免责声明”:首先我要说的是我没有找到导致Firefox出现问题的确切原因,但我确实想到了另一种可以做到的方法。
这在Firefox和Chrome中的工作方式只是使用与您#test1
完全相同的HTML,但除此之外,还使用了CSS :before
伪元素(而不是使用#container
和#wrapper
)。我使用的代码是:
#test2 {
background-color: green;
position:relative;
&:before {
content:"";
display:block;
position:absolute;
left:1px;
top:1px;
bottom:1px;
margin:20px 0 40px 0;
width:30px;
background:#00C2FF;
}
}
这样做的方法是简单地将:before
叠加层放置在与div之前完全相同的位置。正如您所看到的,我使用了大多数相同的样式,但我将它们放在:before
伪类上。
答案 3 :(得分:0)
其他答案不知道为什么它不适用于Firefox。好吧,我认为Firefox有正确的行为,这是Chrome问题。
简而言之,您希望将输入与按钮对齐。但输入是在包装器内。然后,您可以使用vertical-align
来控制包装器和按钮之间的垂直对齐,但不能控制输入和按钮之间的垂直对齐。
在这里,您可以看到包含不同vertical-align
的屏幕截图:
请参阅the code。
如果要对齐输入和按钮(图像中的最后一个案例),则会出现问题,因为您可以使用vertical-align
的任何关键字执行此操作。仅在输入的上边距和下边距相等的情况下,vertical-align: middle
才有效。
但总的来说,您还有另一种解决方案:vertical-align
也接受<length>
值。
而且,为了获得完美的对齐方式,您应该使用公式
vertical-align: -(input bottom margin)
或者,如果你想要对齐它们,即使按钮有一个底部边距,那么
vertical-align: -(input bottom margin) + (button button margin)
上面的代码公式适用于inline-block
<div>
,但不适用于<buttons>
。
公式必须固定为
vertical-align: -(input bottom margin) -(input offsetHeight)/2 + 6
在你的例子中
然后,你需要
vertical-align: -(input bottom margin) -(input offsetHeight)/2 + 6
答案 4 :(得分:0)
我可以通过以下方式实现它。Codepen 您必须知道应用于输入的CSS并将其应用于按钮
button{
position:absolute;
margin-left:5px;
}
input, button {
display: inline-block;
margin: 20px 0 40px 0;
}
答案 5 :(得分:-1)
请在您的代码中进行更新。
input, button {
border: 1px solid #000000;
margin: 20px 0 40px;
padding: 5px;
vertical-align: top;
}
希望它能运作