2014-01-23 102 views
2

TLDR:this codepen在Chrome中正常工作,但Firefox中的对齐关闭。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是我们触及范围的限制(并且不包括按钮元素,或者他们选择放在其输入旁边的任何其他东西)。

回答

2

要解决此问题,您需要在父母div#test2中定义line-height。没有它,different browsers will give it different values。这将导致Firefox导致这个奇怪的结果。

现在,line-height不是唯一的问题,vertical-align的基线值将为内联元素生成不同的结果,而不是高于周围内联内容的内联块元素。要解决此问题,请将#container元素的值更改为top(因为这是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; 
} 

注:

  • 我没有理会使得上层覆盖输入的整个高度,因为你的插件只会使它成为一个标志呢。为了覆盖整个高度,只需在叠加层上设置阴性topbottom样式,等于输入上计算的填充顶部和填充底部(分数)。在这种情况下,您必须将它们更改为top:-5px;bottom:-5px;。(你可以通过jQuery的$(input).css('padding-top')得到计算的样式)
  • 你实际上也可以从中删除整个#container,因为它现在唯一的样式是display:inline,它确实没有增加任何东西。
  • 我已经在输入中添加了填充左边的内容,否则就不得不在覆盖层后面输入,这很愚蠢。
+0

非常酷的解决方案,但我很难过说这是不可能的。我已经更新了这个问题,要明确哪些内容可以更改,哪些内容无法更改。 – jackocnr

+0

@jackocnr请参阅我的更新回答。这是你在找什么? – Joeytje50

+1

哇!如此简单而有效!这是最好的答案。阻止我给予赏金的唯一方法是,您必须知道输入中的填充以定位叠加层,但填充由用户设置(以适应他们现有的样式)。我想解决方法是用jQuery破解CSS,但这是我想避免的。如果没有人提出更好的答案,我会给你赏金。谢谢! – jackocnr

0

免责声明”:让我刚开始说我没有找到究竟是什么导致了Firefox的问题,但我确实想到了一种可以做到的替代方法。

这部作品在Firefox和Chrome浏览器仅仅是使用完全相同的HTML作为您用于#test1,但最重要的是,还使用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; 
    } 
} 

demo

这种工作方式是简单地将:before叠加的位置上完全一样的地方的div以前是。正如你所看到的,我已经使用了大部分相同的风格,但是我将它们放在了:before伪类中。

+0

感谢。一个有趣的方法,但我不只是需要覆盖的彩色方块:我肯定需要使用真正的(非常复杂的)标记,我不认为这个解决方案允许? – jackocnr

+0

@jackocnr我不知道我是否不知道你需要什么标记。你能联系我一个你想要它做什么的演示吗?然后我可以试着看看它是否适合你:':before'。另外,你可以用''的'content'属性[比我做的更多](https://developer.mozilla.org/en-US/docs/Web/CSS/content#Syntax) '伪元素。 – Joeytje50

+3

问题中存在一个与插件的Github页面相关的链接,其中包含有关该插件的更多详细信息,包括链接到演示。 – jackocnr

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; 
    } 
    } 
} 

Codepen example

我已经删除了保证金,并用来代替父填充,它会达到同样的事情。您还需要在输入字段输入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; 
    } 
} 

codepen demo

移除了inputblockmargin声明,并且移动的间距填充#container元素。

+0

如果问题是关于解决保证金问题,删除它就像作弊...但也许你是正确的,不需要保证金,所以这是[XY问题](http://meta.stackexchange。 COM /问题/ 66377 /什么,是最XY-问题)。 – Oriol

+0

感谢您的建议,但重点是我正在尝试使用用户现有的标记和CSS,例如他们有提交和他们现有的CSS在输入上有垂直边距,我希望他们能够只是初始化我的插件,它只是工作,没有更改他们的标记/ CSS的麻烦 – jackocnr

+1

所以有覆盖你的默认的CSS来满足他们的需求。没有人抱怨jQuery和其他插件无法正常工作。解决这个问题可能会导致另一个问题。也就是说,也许你应该编辑你的问题,确切地说明什么可以和不可以改变。 – jammykam

0

其他答案不知道为什么它不适用于Firefox。那么,我认为Firefox有正确的行为,这是一个Chrome的问题。

简而言之,您想要将输入与按钮对齐。但输入是在一个包装内。然后,您可以使用vertical-align来控制包装器和按钮之间的垂直对齐,但不能在输入和按钮之间进行垂直对齐。

在这里你可以看到不同的vertical-align的截图:

Screenshot with different <code>vertical-align</code>

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 

在您的例子

  • (输入底部边缘)= 40像素
  • (输入的offsetHeight)= 31px

然后,你需要

vertical-align: -(input bottom margin) -(input offsetHeight)/2 + 6 

Demo

+0

“其他答案不知道为什么它不适用于Firefox” - 不正确,请参阅我的第二个答案。 – Joeytje50

+0

谢谢你这个启发性的答案,但不幸的是,保证金是用户设置的未知变量。如果不清楚,我很抱歉 - 我编辑了这个问题来澄清这一点。 – jackocnr

+0

@jackocnr是的,但如果它是一个jQuery插件,你可以用JS检测边距,并根据它设置'vertical-align'。 – Oriol

0

我可以通过以下方法实现它。 Codepen你必须知道应用于输入的CSS并将其应用于按钮以及

button{ 
    position:absolute; 
    margin-left:5px; 
    } 
    input, button { 
    display: inline-block; 
    margin: 20px 0 40px 0; 
    } 
-1

请在你的代码下面进行更新。

input, button { 
    border: 1px solid #000000; 
    margin: 20px 0 40px; 
    padding: 5px; 
    vertical-align: top; 
} 

希望它会工作

http://codepen.io/anon/pen/Isycu

+0

否 - 阅读问题 - 该按钮不在插件的控制之下。 – jackocnr