如何固定绝对溢出元素相对于相对父元素的位置?
How to fix the position of an absolute overflowing element with respect to a relative parent?
我制作了一个自定义的 select 框,它包裹在一个可滚动的 div 内。
我的问题是:下拉列表占用了包装器的 space。也就是说,它看起来像这样:
但是,我希望它像这样针对父包装器进行修复:
我可以通过从 .select_box
中删除 position:relative;
来实现这个结果。但是,它打破了输入框和列表(我不想要的)之间的间距,如下所示:
这是我的代码--
HTML:
<div id="wrapper">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
<br/><br/>
<div class="select_box">
<input type="text" onMouseDown="show_list(this)" onblur="hide_list(this)" readonly/>
<ul style="width:200px;">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
</ul>
</div><br/><br/>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
jQuery:
function show_list(element) {
$(element).next().toggle();
if ($(element).next().css('display') == 'none') $(element).css('background', 'url(select_box_arrow.png) no-repeat 95%');
else $(element).css('background', 'url(select_box_arrow_inverted.png) no-repeat 95%');
}
function hide_list(element) {
$(element).next().hide();
$(element).css('background', 'url(select_box_arrow.png) no-repeat 95%');
}
$(document).ready(function () {
$("div[class='select_box'] input:text").css("padding", "0 10px");
$("div[class='select_box'] li").mousedown(function () {
$(this).parent().prev().attr('value', $(this).text());
});
});
CSS:
#wrapper {
height:200px;
width:400px;
border:Solid 1px;
overflow:auto;
}
/* CSS for customized select box */
.select_box {
display:inline-block;
//position:relative;
}
.select_box input[type="text"] {
width:200px;
height:25px;
border: 1px solid #cccccc;
border-radius:2px;
background:url(select_box_arrow.png) no-repeat 95%;
font-size:15px;
outline:none;
cursor:pointer;
vertical-align:middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.select_box input[type="text"]:focus {
border-color:#FFC59D;
box-shadow:0 0 10px #FFC59D;
}
.select_box ul {
list-style:none;
padding:0;
margin:0;
margin-top:2px;
font-family:Tahoma, Geneva, sans-serif;
line-height:25px;
font-size:15px;
font-weight:normal;
border:solid 1px #FFC59D;
width:220px;
max-height:250px;
overflow:auto;
display:none;
position:absolute;
background:#fff;
color:#000000;
scrollbar-arrow-color: #ff6600;
scrollbar-track-color: #FFC59D;
scrollbar-face-color: #ff6600;
scrollbar-shadow-color: #ff6600;
}
.select_box li {
padding-left:10px;
}
.select_box li:hover {
background:#FF9D5B;
color:#fff;
cursor:default;
}
.select_box ::-webkit-scrollbar {
width: 12px;
border:solid 1px #FFC59D;
border-left-width:2px;
}
.select_box ::-webkit-scrollbar-thumb {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background:#FFC59D;
}
.select_box ::-webkit-scrollbar-thumb:window-inactive {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background:#FFC59D;
}
有没有简单的CSS解决方案?我也愿意通过 jQuery 寻求解决方案。
实现此目的的最简单方法是尽可能使用原生 select 框。但是,如果您必须为输入框使用自定义列表,您可以尝试类似下面的示例。
Fiddle(您会看到我在文本输入框旁边添加了本机 select 框,以显示其默认情况下的工作方式)
HTML
<ul class="list-box" style="width:200px;">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
</ul>
<div id="wrapper">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
<br/><br/>
<select><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option></select>
<div class="select_box">
<input class="list_input" type="text" onMouseDown="show_list(this)" onblur="hide_list(this)" readonly/>
</div><br/><br/>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
Javascript
function show_list(element) {
var pos = $(element).offset();
var input_height = $(element).height();
$('.list-box').css('top', pos.top + input_height);
$('.list-box').css('left', pos.left);
$('.list-box').toggle();
if ($('.list-box').css('display') == 'none') $(element).css('background', 'url(select_box_arrow.png) no-repeat 95%');
else $(element).css('background', 'url(select_box_arrow_inverted.png) no-repeat 95%');
}
function hide_list(element) {
$(element).next().hide();
$(element).css('background', 'url(select_box_arrow.png) no-repeat 95%');
}
$(document).ready(function () {
$("div[class='select_box'] input:text").css("padding", "0 10px");
$("ul.list-box li").mousedown(function () {
$('.list_input').attr('value', $(this).text());
$('.list-box').toggle();
});
$('#wrapper').on('scroll', function(){
var pos = $('.list_input').offset();
var input_height = $('.list_input').height();
$('.list-box').css('top', pos.top + input_height);
$('.list-box').css('left', pos.left);
});
});
CSS
#wrapper {
height:200px;
width:400px;
border:Solid 1px;
overflow:auto;
}
/* CSS for customized select box */
.select_box {
display:inline-block;
position:relative;
}
.select_box input[type="text"] {
width:200px;
height:25px;
border: 1px solid #cccccc;
border-radius:2px;
background:url(select_box_arrow.png) no-repeat 95%;
font-size:15px;
outline:none;
cursor:pointer;
vertical-align:middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.select_box input[type="text"]:focus {
border-color:#FFC59D;
box-shadow:0 0 10px #FFC59D;
}
.select_box ul {
list-style:none;
padding:0;
margin:0;
margin-top:2px;
font-family:Tahoma, Geneva, sans-serif;
line-height:25px;
font-size:15px;
font-weight:normal;
border:solid 1px #FFC59D;
width:220px;
max-height:250px;
overflow:auto;
display:none;
position:absolute;
background:#fff;
color:#000000;
scrollbar-arrow-color: #ff6600;
scrollbar-track-color: #FFC59D;
scrollbar-face-color: #ff6600;
scrollbar-shadow-color: #ff6600;
}
.select_box li {
padding-left:10px;
}
.select_box li:hover {
background:#FF9D5B;
color:#fff;
cursor:default;
}
.select_box ::-webkit-scrollbar {
width: 12px;
border:solid 1px #FFC59D;
border-left-width:2px;
}
.select_box ::-webkit-scrollbar-thumb {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background:#FFC59D;
}
.select_box ::-webkit-scrollbar-thumb:window-inactive {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background:#FFC59D;
}
所做更改的快速说明:
如@charlietfl 所述,列表需要附加到主体而不是滚动元素内。从那里,我将 类 添加到输入类型文本和列表中,因为父级 jquery selector 将不再工作,因为它们彼此不相邻或不在同一父级中容器。单击输入或滚动 #wrapper div 时,我将列表放在单击的文本框正下方。
像这样?
您需要将下拉菜单移到 #wrapper
之外,然后用 javaScript 和 position: absolute
计算它相对于 input[type=text]
的位置
工作演示:
http://jsfiddle.net/4rv4s3ce/10/
希望对您有所帮助。
我制作了一个自定义的 select 框,它包裹在一个可滚动的 div 内。
我的问题是:下拉列表占用了包装器的 space。也就是说,它看起来像这样:
但是,我希望它像这样针对父包装器进行修复:
我可以通过从 .select_box
中删除 position:relative;
来实现这个结果。但是,它打破了输入框和列表(我不想要的)之间的间距,如下所示:
这是我的代码--
HTML:
<div id="wrapper">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
<br/><br/>
<div class="select_box">
<input type="text" onMouseDown="show_list(this)" onblur="hide_list(this)" readonly/>
<ul style="width:200px;">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
</ul>
</div><br/><br/>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
jQuery:
function show_list(element) {
$(element).next().toggle();
if ($(element).next().css('display') == 'none') $(element).css('background', 'url(select_box_arrow.png) no-repeat 95%');
else $(element).css('background', 'url(select_box_arrow_inverted.png) no-repeat 95%');
}
function hide_list(element) {
$(element).next().hide();
$(element).css('background', 'url(select_box_arrow.png) no-repeat 95%');
}
$(document).ready(function () {
$("div[class='select_box'] input:text").css("padding", "0 10px");
$("div[class='select_box'] li").mousedown(function () {
$(this).parent().prev().attr('value', $(this).text());
});
});
CSS:
#wrapper {
height:200px;
width:400px;
border:Solid 1px;
overflow:auto;
}
/* CSS for customized select box */
.select_box {
display:inline-block;
//position:relative;
}
.select_box input[type="text"] {
width:200px;
height:25px;
border: 1px solid #cccccc;
border-radius:2px;
background:url(select_box_arrow.png) no-repeat 95%;
font-size:15px;
outline:none;
cursor:pointer;
vertical-align:middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.select_box input[type="text"]:focus {
border-color:#FFC59D;
box-shadow:0 0 10px #FFC59D;
}
.select_box ul {
list-style:none;
padding:0;
margin:0;
margin-top:2px;
font-family:Tahoma, Geneva, sans-serif;
line-height:25px;
font-size:15px;
font-weight:normal;
border:solid 1px #FFC59D;
width:220px;
max-height:250px;
overflow:auto;
display:none;
position:absolute;
background:#fff;
color:#000000;
scrollbar-arrow-color: #ff6600;
scrollbar-track-color: #FFC59D;
scrollbar-face-color: #ff6600;
scrollbar-shadow-color: #ff6600;
}
.select_box li {
padding-left:10px;
}
.select_box li:hover {
background:#FF9D5B;
color:#fff;
cursor:default;
}
.select_box ::-webkit-scrollbar {
width: 12px;
border:solid 1px #FFC59D;
border-left-width:2px;
}
.select_box ::-webkit-scrollbar-thumb {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background:#FFC59D;
}
.select_box ::-webkit-scrollbar-thumb:window-inactive {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background:#FFC59D;
}
有没有简单的CSS解决方案?我也愿意通过 jQuery 寻求解决方案。
实现此目的的最简单方法是尽可能使用原生 select 框。但是,如果您必须为输入框使用自定义列表,您可以尝试类似下面的示例。
Fiddle(您会看到我在文本输入框旁边添加了本机 select 框,以显示其默认情况下的工作方式)
HTML
<ul class="list-box" style="width:200px;">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
</ul>
<div id="wrapper">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
<br/><br/>
<select><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option><option>test</option></select>
<div class="select_box">
<input class="list_input" type="text" onMouseDown="show_list(this)" onblur="hide_list(this)" readonly/>
</div><br/><br/>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
Javascript
function show_list(element) {
var pos = $(element).offset();
var input_height = $(element).height();
$('.list-box').css('top', pos.top + input_height);
$('.list-box').css('left', pos.left);
$('.list-box').toggle();
if ($('.list-box').css('display') == 'none') $(element).css('background', 'url(select_box_arrow.png) no-repeat 95%');
else $(element).css('background', 'url(select_box_arrow_inverted.png) no-repeat 95%');
}
function hide_list(element) {
$(element).next().hide();
$(element).css('background', 'url(select_box_arrow.png) no-repeat 95%');
}
$(document).ready(function () {
$("div[class='select_box'] input:text").css("padding", "0 10px");
$("ul.list-box li").mousedown(function () {
$('.list_input').attr('value', $(this).text());
$('.list-box').toggle();
});
$('#wrapper').on('scroll', function(){
var pos = $('.list_input').offset();
var input_height = $('.list_input').height();
$('.list-box').css('top', pos.top + input_height);
$('.list-box').css('left', pos.left);
});
});
CSS
#wrapper {
height:200px;
width:400px;
border:Solid 1px;
overflow:auto;
}
/* CSS for customized select box */
.select_box {
display:inline-block;
position:relative;
}
.select_box input[type="text"] {
width:200px;
height:25px;
border: 1px solid #cccccc;
border-radius:2px;
background:url(select_box_arrow.png) no-repeat 95%;
font-size:15px;
outline:none;
cursor:pointer;
vertical-align:middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.select_box input[type="text"]:focus {
border-color:#FFC59D;
box-shadow:0 0 10px #FFC59D;
}
.select_box ul {
list-style:none;
padding:0;
margin:0;
margin-top:2px;
font-family:Tahoma, Geneva, sans-serif;
line-height:25px;
font-size:15px;
font-weight:normal;
border:solid 1px #FFC59D;
width:220px;
max-height:250px;
overflow:auto;
display:none;
position:absolute;
background:#fff;
color:#000000;
scrollbar-arrow-color: #ff6600;
scrollbar-track-color: #FFC59D;
scrollbar-face-color: #ff6600;
scrollbar-shadow-color: #ff6600;
}
.select_box li {
padding-left:10px;
}
.select_box li:hover {
background:#FF9D5B;
color:#fff;
cursor:default;
}
.select_box ::-webkit-scrollbar {
width: 12px;
border:solid 1px #FFC59D;
border-left-width:2px;
}
.select_box ::-webkit-scrollbar-thumb {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background:#FFC59D;
}
.select_box ::-webkit-scrollbar-thumb:window-inactive {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background:#FFC59D;
}
所做更改的快速说明:
如@charlietfl 所述,列表需要附加到主体而不是滚动元素内。从那里,我将 类 添加到输入类型文本和列表中,因为父级 jquery selector 将不再工作,因为它们彼此不相邻或不在同一父级中容器。单击输入或滚动 #wrapper div 时,我将列表放在单击的文本框正下方。
像这样?
您需要将下拉菜单移到 #wrapper
之外,然后用 javaScript 和 position: absolute
input[type=text]
的位置
工作演示: http://jsfiddle.net/4rv4s3ce/10/
希望对您有所帮助。