如果这是一个骗局,那么抱歉,但我找不到它。
我有一个绝对定位的元素,其大小目前基于其内容:当前案例中的要求。但是,它也直接设置在其父级的右侧,而它需要直接位于其下方。 要将绝对元素设置在其父元素下方,我将其左侧和顶部设置为相对定位的父元素。但是,当我这样做时,绝对元素采用其父元素的宽度(这是非常小的)。我真的需要绝对元素来根据其(通常是动态的)内容来定义自己的宽度。
是否有一种有效的方法可以将绝对元素设置在其父元素的正下方,同时保持其内容的大小?
修改
Here's一个jsfiddle链接来演示这个问题。
这是html:
<div id='menu'>
<span class='menuItem'>
<span class='menuItemTitle'>
Item 1
</span>
<div class='menuItemContent'>
test1 test1 test1 test1<br/>
testing testing, one two three<br/>
Anyone there?
</div>
</span>
<span class='menuItem'>
<span class='menuItemTitle'>
Item 2: extra wide
</span>
<div class='menuItemContent'>
test2 test2 test2 test2
</div>
</span>
</div>
这是CSS:
#menu
{
background-color: blue;
width: 100%;
}
.menuItem
{
padding: 0 1em;
//position: relative;
}
.menuItemTitle
{
background-color: yellow;
}
.menuItemContent
{
background-color: green;
display: none;
position: absolute;
z-index: 100;
}
.menuItem:hover .menuItemContent
{
display: inherit;
}
默认情况下,它显示没有相对父级的绝对元素。这允许元素的内容定义其宽度。 如果你转到“.menuItem”样式并取消注释它的位置,那么绝对元素会被压扁。
答案 0 :(得分:1)
绝对定位元素默认为内容大小,除非您设置其两侧(例如“左”和“右”),或明确设置其宽度。
因此,如果绝对定位的元素相对于父元素的大小,则必须执行上述操作之一。测试的一个好方法是使用检查员,例如, Firefox或Chrome,查看计算出的CSS,看看它是否包含上述内容之一。您还可以通过在元素上设置right: auto;
和width: auto;
来强行阻止这些情况。
一个小问题是它仍然会从其父级继承断行规则。要防止这种情况,只需将其宽度设置为一个非常大的数字,如1000000px。这样可以防止断线,但也可以使其内部的任何相对大小的元素过大。但是,后者不是技术问题:相对大小的元素必须相对于某事进行调整,因此您要么将其保留为相对于父对象,要么避免在直接子对象中使用相对大小绝对定位的元素。
如果你需要一个内容大小的边框,只需在绝对定位的元素中放入另一个div,使其绝对定位或浮动,并给它一个边框。
如果要将相对大小的元素与不相同的元素混合,请允许绝对定位元素相对于父元素的大小,但同时包装不应包装的单个元素/段落非常广泛的div。
如果您希望绝对定位的元素相对于父元素的父元素进行调整,请不要使它完全定位。相反,使用浮点数,并使其成为父项父项的直接子项。例如,这是我用来制作内容大小的侧边栏一次的技巧:
<div id="parent" style="float: left; width: 100%; clear:both"><!-- Float parent -->
<div id="sidebar" style="float: left">
Dynamic content
</div>
<div id="main_content_position" style="float: left"><!-- Extra div to set the position right of the sidebar -->
<div id="main_content" style="width: 100%"><!-- Inner div with 100% width forces the position div to grow as large as it can, minus the size of the sidebar -->
My content
</div>
</div>
</div>
<div id="clear_after" style="clear:both"></div><!-- Clear after the floating parent. We don't want it to actually float -->
请注意,这种方法远非完美。它需要使用严格模式(<!DOCTYPE html>
),如果你使用RTL,你需要在Firefox上至少增加一个div,并混淆overflow:visible
和overflow:hidden
,否则自动换行将会破碎。
一般来说,让侧边栏具有静态宽度是个好主意,然后使用旧的浮动和边距技巧:
<div id="parent" style="width: 100%">
<div id="sidebar" style="float: left; width: 150px">
Static content
</div>
<div id="main_content" style="margin-left: 150px">
Dynamic content
</div>
</div>
更新:它在JSFiddle中“压扁”的原因是因为此实例中的“内容大小”基于最大的单词。你显然想要的是它根本不引入换行符。
(另外,你把一个div放在一个不完全有效的范围内,但我会让它通过)
部分工作的一个解决方案是增加div的宽度并使用内部div,如前所述:
<div class='menuItemContent'>
<div class='menuItemContentInner'>
test1 test1 test1 test1<br/>
testing testing, one two three<br/>
Anyone there?
</div>
</div>
添加CSS:
.menuItemContent
{
display: none;
position: absolute;
left: 0;
top: 1em;
z-index: 100;
width: 10000px;
}
.menuItemContentInner
{
background-color: green;
float: left;
}
此解决方案的缺陷是,当您将鼠标悬停在项目上时会创建滚动条。使用overflow:hidden
并不能解决问题,因为它还会将事情降低到菜单的高度。不幸的是,不可能只在一个方向上进行overflow:hidden
。
然而,在与小提琴手玩耍之后,我终于找到了这个解决方案:
.menuItem
{
padding: 0 1em;
float: left;
}
.menuItemContent
{
background-color: green;
display: none;
position: absolute;
z-index: 100;
clear: left;
}
将<div style="clear:both"></div>
添加到菜单的末尾。
这会导致内容断开并显示在文本下方,而无需明确设置其left
或top
,因此不需要对项目position:relative
。我在Firefox,Internet Explorer 11和Chrome中测试过它。这实际上是一个更清洁的解决方案。
答案 1 :(得分:0)
我最近通过网站上的下拉悬停子菜单来完成此操作。我发现的解决方案是将子“绝对”元素的空白设置为“ nowrap”。 在我的具体情况下:
&.menu-item-has-children {
position: relative;
.sub-menu {
position: absolute;
li a {
white-space: nowrap;
}
}
}
这允许绝对元素根据其父元素定位,但仍允许其宽度基于其内容大于其父元素。