首页 > 解决方案 > 以相对方式绝对定位 n 个孩子?

问题描述

我目前正在处理一个自定义下拉列表,我希望父级在页面内相对定位。然后我希望下拉列表的所有子项(列表项)被页面的其余部分忽略以模拟一个select元素。我的第一个想法是通过类似于以下伪代码的方式使用 JavaScript 定位孩子:

function positionChildren() {
    var ddl = document.getElementById("myDDL");
    var items = ddl.getElementsByTagName("LI");
    var bottom = 0;
    for (var i = 0; i < items.length; i++) {
        items[i].style.top = bottom + 5 + "px";
        bottom += items[i].height;
    }
}

父母将拥有的地方position: relative,每个孩子都会拥有position: absolute,因此将被那里的其余内容忽略。

不过,我不仅觉得没那么简单,而且我也相信用纯CSS大概有办法做到,所以特地来高手所在的地方求助。

到目前为止,为了清楚起见,这是我所拥有的:

function openDropDown(dropDownList) {
	dropDownList.classList.toggle("selecting");
}
* {
	transition: 0.3s all linear;
}
html,
body {
	margin: 0;
	height: 100%;
	background-color: #319;
	background-image: linear-gradient(45deg, #b0a, #319);
	background-image: -webkit-linear-gradient(45deg, #b0a, #319);
  overflow: hidden;
}
.primary-content {
	height: 100%;
	text-align: center;
	padding: 15px;
	color: #fff;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	align-items: center;
}

/* DDL Specific Styles Start Here */
.drop-down-list {
	position: relative;
	list-style-type: none;
	padding: 0;
	padding-right: 5px;
	min-width: 300px;
	text-align: left;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
  overflow-y: auto;
	overflow-x: hidden;
}
.drop-down-list:after {
	content: "\21AC";
	position: absolute;
	top: -5px;
	right: 5px;
	font-size: 30px;
	color: #555;
	-webkit-transform: rotate(-90deg);
	transform: rotate(-90deg);
}
.drop-down-list.selecting:after {
	-webkit-transform: scaleX(-1) rotate(90deg);
	transform: scaleX(-1) rotate(90deg);
}
.drop-down-list.selecting {
	max-height: 60%;
	overflow-y: auto;
}
.drop-down-list > li {
	background-color: rgba(255, 255, 255, 0.95);
	color: #555;
	padding: 2px;
	padding-left: 10px;
	margin-bottom: 5px;
	border-radius: 5px;
	box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.25);
	cursor: pointer;
}
.drop-down-list > li.selected {
	background-color: rgba(20, 200, 255, 0.95);
	color: #fff;
}
.drop-down-list:not(.selecting) > li.selected {
	background-color: rgba(255, 255, 255, 0.95);
	color: #555;
}
.drop-down-list:not(.selecting) > li.selected:hover {
	background-color: #fff;
}
.drop-down-list:not(.selecting) > li:not(.selected) {
	height: 0;
	line-height: 0;
	font-size: 0;
	padding: 0;
	margin: 0;
	opacity: 0;
}
.drop-down-list > li:hover {
	background-color: #fff;
}
.drop-down-list > li.selected:hover {
	background-color: #3cf;
}
<div id="primary-content" class="primary-content">
  <p class="lead">Click the option to expand the children out.</p>
	<ul class="drop-down-list" onclick="openDropDown(this);">
		<li>Option 1</li>
		<li>Option 2</li>
		<li>Option 3</li>
		<li class="selected">Option 4</li>
		<li>Option 5</li>
		<li>Option 6</li>
		<li>Option 7</li>
		<li>Option 8</li>
		<li>Option 9</li>
		<li>Option 10</li>
		<li>Option 11</li>
		<li>Option 12</li>
		<li>Option 13</li>
	</ul>
	<p class="lead">This paragraph is to simulate content below the drop down to ensure that page content isn't pushed around when the control expands.</p>
</div>

如何相对于父级定位下拉列表的所有子级,但页面的其余部分会忽略它们?

标签: javascripthtmlcss

解决方案


你几乎就在那里 - 你基本上只需要一个包装在你的ul.

一些注意事项:

  • 进行选择将始终关闭下拉菜单。e.stopPropagation()如果你想解决这个问题,你需要使用

  • 下拉菜单可以离开页面底部。玩ul' 的高度并让它在打开时滚动应该会有所帮助

  • 下拉菜单根本无法访问

function openDropDown(dropDownList) {
	dropDownList.classList.toggle("selecting");
}
* {
	transition: 0.3s all linear;
}
html,
body {
	margin: 0;
	height: 100%;
	background-color: #319;
	background-image: linear-gradient(45deg, #b0a, #319);
	background-image: -webkit-linear-gradient(45deg, #b0a, #319);
  overflow: hidden;
}
.primary-content {
	height: 100%;
	text-align: center;
	padding: 15px;
	color: #fff;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	align-items: center;
}

/* DDL Specific Styles Start Here */
.drop-down {
  width: 300px;
  height: 3em;
}

.drop-down-list {
	position: relative;
	list-style-type: none;
	padding: 0;
	padding-right: 5px;
	min-width: 300px;
	text-align: left;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}
.drop-down-list:after {
	content: "\21AC";
	position: absolute;
	top: -5px;
	right: 5px;
	font-size: 30px;
	color: #555;
	-webkit-transform: rotate(-90deg);
	transform: rotate(-90deg);
}
.drop-down-list.selecting:after {
	-webkit-transform: scaleX(-1) rotate(90deg);
	transform: scaleX(-1) rotate(90deg);
}
.drop-down-list.selecting {
	max-height: 60%;
	position: absolute;
}
.drop-down-list > li {
	background-color: rgba(255, 255, 255, 0.95);
	color: #555;
	padding: 2px;
	padding-left: 10px;
	margin-bottom: 5px;
	border-radius: 5px;
	box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.25);
	cursor: pointer;
}
.drop-down-list > li.selected {
	background-color: rgba(20, 200, 255, 0.95);
	color: #fff;
}
.drop-down-list:not(.selecting) > li.selected {
	background-color: rgba(255, 255, 255, 0.95);
	color: #555;
}
.drop-down-list:not(.selecting) > li.selected:hover {
	background-color: #fff;
}
.drop-down-list:not(.selecting) > li:not(.selected) {
	height: 0;
	line-height: 0;
	font-size: 0;
	padding: 0;
	margin: 0;
	opacity: 0;
}
.drop-down-list > li:hover {
	background-color: #fff;
}
.drop-down-list > li.selected:hover {
	background-color: #3cf;
}
<div id="primary-content" class="primary-content">
  <p class="lead">Click the option to expand the children out.</p>
  <div class="drop-down">
    <ul class="drop-down-list" onclick="openDropDown(this);">
      <li>Option 1</li>
      <li>Option 2</li>
      <li>Option 3</li>
      <li class="selected">Option 4</li>
      <li>Option 5</li>
      <li>Option 6</li>
      <li>Option 7</li>
      <li>Option 8</li>
      <li>Option 9</li>
      <li>Option 10</li>
      <li>Option 11</li>
      <li>Option 12</li>
      <li>Option 13</li>
    </ul>
   </div>
	<p class="lead">This paragraph is to simulate content below the drop down to ensure that page content isn't pushed around when the control expands.</p>
</div>


推荐阅读