在一个轴上将元素与父项的父项对齐?

时间:2017-04-10 16:20:43

标签: html css flexbox

我有一个以(公平)语义HTML定义的标签列表:

<ul class='tabs'>
  <li class='tab'>
    <input type='radio' checked='checked' id='apples' name='fruit' />
    <label for='apples'>
      Apples
    </label>
    <div class='panel apples'>
      <p>Apples are red. </p> 
    </div>
  </li>
  <li class='tab'>
    <input type='radio' id='bananas' name='fruit' />
    <label for='bananas'>
      Bananas
    </label>
    <div class='panel bananas'>
      <p>Bananas are yellow. </p> 
    </div>
  </li>
  <li class='tab'>
    <input type='radio' id='cherries' name='fruit' />
    <label for='cherries'>
      Cherries
    </label>
    <div class='panel cherries'>
      <p>Cherries are... cherry. </p> 
    </div>
  </li>
</ul>
<p>
  This should always be below the tabs! 
</p>

我想使用纯CSS将元素渲染为制表符。选项卡应该是连续的按钮。所选面板应显示在按钮下方,并与最左侧按钮对齐。我有其他元素应该在标签面板下面。我不想使用像素定位,以便页面可以轻松调整大小。

这是我到目前为止尝试过的CSS:

.tabs {
  display: flex;
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.tabs .tab {
  display: flex;
  flex-direction: column;
  margin: 0;
  margin-right: 32px;
  padding: 0;
}

.tabs .tab:last-child {
  margin-right: 0;
}

.panel {
  display: none;
  margin-top: 16px;
}

.tabs input[type=radio] {
  display:none;
  margin: 0;
}

.tabs .tab label {
  background: #f00;
  margin: 0;
  cursor:pointer;
}

input[type=radio]:checked ~ label {
  background: #ff0;
}

input[type=radio]:checked ~ .panel {
  display: flex;
  background: #0ff;
} 

这几乎就在那里,但所选面板显示在其按钮下方,而不是最左侧的按钮。

我想做position-x: absolute之类的事情,但我不知道这是否可行。

如何将所选面板与其父母的父母对齐?

小提琴:https://jsfiddle.net/mkf7b8cy/

1 个答案:

答案 0 :(得分:1)

使用CSS单独使用当前标记结构无法解决这个问题,需要一个脚本。

您的建议,使用position: absolute(顺便说一下,position-x)会使以下元素(在本例中为p)跳到/隐藏在panel,因为他们的父级会将其高度折叠为0,这是由绝对定位的panel引起的。

如果将标记更改如下,则可以将input放在ul之前,将panel放在{。}}之后。

:checked CSS规则也需要更新。

Updated fiddle

Stack snippet

.tabs {
  display: flex;
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.tabs .tab {
  display: flex;
  flex-direction: column;
  margin: 0;
  margin-right: 32px;
  padding: 0;
}

.tabs .tab:last-child {
  margin-right: 0;
}

.panel {
  display: none;
  margin-top: 16px;
}

input[type=radio] {
  display: none;
  margin: 0;
}

.tabs .tab label {
  background: #f00;
  margin: 0;
  cursor: pointer;
}

input[type=radio][id=apples]:checked ~ ul label[for=apples],
input[type=radio][id=bananas]:checked ~ ul label[for=bananas],
input[type=radio][id=cherries]:checked ~ ul label[for=cherries] {
  background: #ff0;
}

input[id=apples]:checked ~ .panel.apples,
input[id=bananas]:checked ~ .panel.bananas,
input[id=cherries]:checked ~ .panel.cherries {
  display: flex;
  background: #0ff;
}
<input type='radio' checked='checked' id='apples' name='fruit' />
<input type='radio' id='bananas' name='fruit' />
<input type='radio' id='cherries' name='fruit' />
<ul class='tabs'>
  <li class='tab'>
    <label for='apples'>
      Apples
    </label>
  </li>
  <li class='tab'>
    <label for='bananas'>
      Bananas
    </label>
  </li>
  <li class='tab'>
    <label for='cherries'>
      Cherries
    </label>
  </li>
</ul>
<div class='panel apples'>
  <p>Apples are red. </p>
</div>
<div class='panel bananas'>
  <p>Bananas are yellow. </p>
</div>
<div class='panel cherries'>
  <p>Cherries are... cherry. </p>
</div>


<p>
  This should always be below the tabs!
</p>