代码之家  ›  专栏  ›  技术社区  ›  vrintle Jake

固定高度父级应包括绝对/固定位置子级

  •  2
  • vrintle Jake  · 技术社区  · 6 年前

    div.settings 作为“家长”和 #mainMenu 作为“孩子”。

    现在,我想创建一个类似于Windows中的下拉列表。所以,父母的身高需要 固定的 fixed

    enter image description here


    * {
      box-sizing: border-box;
      cursor: default;
      user-select: none;
      font-family: Roboto;
      font-weight: 400;
    }
    
    .settings {
      padding: 7px 16px;
      border: 0.5px solid #7777;
      border-radius: 4px;
    }
    
    #mainMenu {
      position: fixed;
      /* or absolute */
      display: inline-flex;
      flex-flow: column wrap;
      justify-content: flex-start;
      align-items: stretch;
    }
    
    span.opt {
      padding: 5px 20px;
      flex-grow: 1;
      margin: 0;
      background: #777;
      color: #FFF;
      text-align: center;
      display: none;
    }
    
    span.selected {
      display: inline-block !important;
      background: #28F;
    }
    
    #mainMenu:hover>span.opt {
      display: inline-block;
    }
    <div class='settings'>
      <p>Select default browser</p>
      <span id='mainMenu'>
        <span class='opt'>Google Chrome</span>
        <span class='opt'>Mozilla Firefox</span>
        <span class='opt'>Safari</span>
        <span class='opt selected'>Microsoft Edge</span>
        <span class='opt'>Opera</span>
        <span class='opt'>Internet Explorer</span>
      </span>
    </div>

    问题

    我想让父母 包括 菜单包含在其内容中。如下图所示:

    enter image description here

    注意 :只有CSS(因为没有任何东西是动态的而没有效果),并且我在代码中只显示了一个菜单(以最小化复杂性和代码长度)。实际上,可能有 许多的

    简言之,我只想让孩子保持固定的位置,在父母身体内部,保持固定的高度。

    4 回复  |  直到 4 年前
        1
  •  1
  •   Arleigh Hix    6 年前

    您可以将菜单包装在一个具有最小高度的div中,以便在父div中保留该空间, 使用“占位符”span.opt.selected with visibility:hidden(请参阅更新的代码段)。

    * {
      box-sizing: border-box;
      cursor: default;
      user-select: none;
      font-family: Roboto;
      font-weight: 400;
    }
    
    .settings {
      padding: 7px 16px;
      border: 0.5px solid #7777;
      border-radius: 4px;
      background-color: inherit;
    }
    
    #mainMenu {
      position: fixed;
      /* or absolute */
      display: inline-flex;
      flex-flow: column wrap;
      justify-content: flex-start;
      align-items: stretch;
    }
    
    span.opt {
      padding: 5px 12px;
      flex-grow: 1;
      margin: 0;
      background: #777;
      color: #FFF;
      text-align: center;
      display: none;
    }
    
    span.placeholder {
      visibility: hidden;
    }
    
    span.selected {
      display: inline-block !important;
      background: #28F;
    }
    
    #mainMenu:hover>span.opt {
      display: inline-block;
    }
    <div class='settings'>
      <p>Select default browser</p>
      <span id='mainMenu'>
        <span class='opt'>Google Chrome</span>
        <span class='opt'>Mozilla Firefox</span>
        <span class='opt'>Safari</span>
        <span class='opt selected'>Microsoft Edge</span>
        <span class='opt'>Opera</span>
        <span class='opt'>Internet Explorer</span>
      </span>
      <span class='opt selected placeholder'>placeholder</span>
    </div>
        2
  •  2
  •   evgeni fotia    6 年前

    我添加了一个悬停效果,所以你可以看到。设置高度是动态的

    var mainMenu = document.getElementById("mainMenu");
    var heightc = document.getElementById("heightc");
    var opt = document.getElementsByClassName("opt");
    var scrollHeight = 0;
    mainMenu.addEventListener('mouseenter', function(){
        for(var i=0; i<opt.length; i++){
           if(opt[i].className.indexOf("selected") > 0){
              var dm = i*opt[i].offsetHeight;
              mainMenu.style.bottom = dm + 'px';
              heightc.style.paddingBottom = dm + 'px';
              scrollHeight = window.scrollY;
              window.scrollTo(0, window.scrollY+dm);
           }
        }
    });
    
    
    mainMenu.addEventListener('mouseleave', function(){
        mainMenu.style.bottom = 0;
        heightc.style.paddingBottom = 0;
        window.scrollTo(0, scrollHeight); 
    });
    * {
    	box-sizing: border-box;
    	cursor: default;
    	user-select: none;
    	font-family: Roboto;
    	font-weight: 400;
    }
    #fs{
      height: 1000px;
    }
    .settings {
    	padding: 7px 16px;
    	border: 0.5px solid #7777;
    	border-radius: 4px;
    }
    #mainMenu {
    	display: inline-flex;
    	flex-flow: column wrap;
    	justify-content: flex-start;
    	align-items: stretch;
      position: relative;
    }
    /* added */
    #mainMenu span{
      display: none;
    }
    #mainMenu .selected{
      display: block;
    }
    #mainMenu:hover .opt{
      display: block;
    }
    /* end added */
    span.opt {
    	padding: 5px 12px;
    	flex-grow: 1;
    	margin: 0;
    	background: #777;
    	color: #FFF;
    	text-align: center;
    }
    span.selected {
    	display: inline-block !important;
    	background: #28F;
    }
    <div class='settings'>
      <p id="heightc">Select default browser</p>
      <span id='mainMenu'>
        <span class='opt'>Google Chrome</span>
        <span class='opt'>Mozilla Firefox</span>
        <span class='opt'>Safari</span>
        <span class='opt selected'>Microsoft Edge</span>
        <span class='opt'>Opera</span>
        <span class='opt'>Internet Explorer</span>
      </span>
    </div>
    <div id="fs"></div>
        3
  •  1
  •   sol    6 年前

    我希望父级在其内容中包含菜单

    添加位置 absolute fixed

    const MENU = document.getElementById('mainMenu');
    const SELECTION = document.getElementById('selection');
    const OPTION_CONTAINER = document.getElementById('options');
    const OPTIONS = [...document.querySelectorAll('.opt')];
    
    let height;
    
    function addEventListeners() {
      OPTIONS.forEach((option, index) => {
        option.addEventListener('click', (e) => {
          let val = option.innerText;
          SELECTION.innerText = val;
          positionMenu(index);
    
          if (MENU.classList.contains('is-open')) {
            MENU.classList.remove('is-open')
          }
        })
      })
    
      MENU.addEventListener('mouseenter', () => {
        MENU.classList.add('is-open');
      })
    
      MENU.addEventListener('mouseleave', () => {
        MENU.classList.remove('is-open');
      })
    }
    
    function getOptionHeight() {
      height = OPTIONS[0].getBoundingClientRect().height;
    }
    
    function positionMenu(index) {
      index--;
      OPTION_CONTAINER.style.transform = `translateY(-${index * height}px)`;
    }
    
    getOptionHeight();
    addEventListeners();
    * {
      box-sizing: border-box;
      cursor: default;
      user-select: none;
      font-family: Roboto;
      font-weight: 400;
    }
    
    .settings {
      /* demo */
      margin: 100px 0 100px;
      
      padding: 7px 16px;
      border: 0.5px solid #7777;
      border-radius: 4px;
    }
    
    .options-container {
      position: relative;
      width: 200px;
    }
    
    .options {
      display: inline-flex;
      flex-flow: column wrap;
      justify-content: flex-start;
      align-items: stretch;
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      opacity: 0;
      pointer-events: none;
    }
    
    .opt {
      padding: 5px 20px;
      flex-grow: 1;
      margin: 0;
      background: #777;
      color: #FFF;
      text-align: center;
      display: inline-block;
      width: 100%;
    }
    
    .selected {
      background: #28F;
    }
    
    .options-container.is-open .options {
      opacity: 1;
      pointer-events: auto;
    }
    
    .opt:hover {
      background: #28F;
    }
    <div class='settings'>
      <p>Select default browser</p>
      <div id='mainMenu' class="options-container">
        <span id="selection" class="opt selected">Select</span>
        <div class="options" id="options">
          <span class='opt'>Google Chrome</span>
          <span class='opt'>Mozilla Firefox</span>
          <span class='opt'>Safari</span>
          <span class='opt'>Microsoft Edge</span>
          <span class='opt'>Opera</span>
          <span class='opt'>Internet Explorer</span>
        </div>
      </div>
    </div>
        4
  •  1
  •   Mattia Pontonio    6 年前

    JavaScript和CSS解决方案建议

    为了 控制定位 最好将选项和选中的选项保持在两个位置 不同的背景 然后再做手术 top属性 以编程方式 . 在那之后,你必须解决问题 价值呢 得到 设置 在标记中。

    function setTop() {
      let height = document.querySelector(".opt").clientHeight;
      document.querySelector(".options").style.top = height * 3 * (-1) + "px";
    }
    setTop();
    * {
          box-sizing: border-box;
          cursor: default;
          user-select: none;
          font-family: Roboto;
          font-weight: 400;
        }
    
        .settings {
          padding: 7px 16px;
          border: 0.5px solid #7777;
          border-radius: 4px;
        }
    
        #mainMenu {
          position: relative;
          display: block;
          width:300px;
        }
        #mainMenu .options {
          position: absolute;
          display: none;
          width:100%;
        }
        #mainMenu:hover .options {
          display: block;
        }
    
        #mainMenu .opt {
          padding: 5px 20px;
          background: #777;
          color: #FFF;
          text-align: center;
        }
        #mainMenu .opt.selected {
          background: #28F;
        }
        #mainMenu .selection {
          display:block;
        }
    <div class='settings'>
          <p>Select default browser</p>
          <div id='mainMenu'>
            <span class='opt selected selection'>Microsoft Edge</span>
            <div class='options' style="top:0;">
              <div class='opt'>Google Chrome</div>
              <div class='opt'>Mozilla Firefox</div>
              <div class='opt'>Safari</div>
              <div class='opt selected'>Microsoft Edge</div>
              <div class='opt'>Opera</div>
              <div class='opt'>Internet Explorer</div>
            </div>
          </div>
        </div>