如何垂直对齐展开手风琴的CSS箭头?

时间:2020-04-09 19:46:40

标签: html css

我使用CSS而不是Fontawesome来生成箭头。我认为这比加载单独的图标库更有意义。但是我很难将那些CSS箭头定位在中心,当它指向上方时看起来很棒,我认为它位于中心或至少靠近中心,但是当它指向下方时,看起来就像箭头朝着底部移动。 任何建议,我将不胜感激

"use strict";

const panelHeader = document.querySelectorAll(".panel-header");

panelHeader.forEach(item => {
  item.addEventListener("click", event => {
    event.preventDefault();
    item.parentElement.classList.toggle("open");
    const panel = item.nextElementSibling;
    panel.style.height = panel.style.height ? null : panel.scrollHeight + "px";
  });
});
:root {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

body {
  margin: 0;
  padding: 0;
}

.accordion {
  max-width: 1200px;
  margin: 0 auto;
}

.accordion-container {
  padding: 15px;
}

h2 {
  color: #444;
  font-size: 1.75rem;
  position: relative;
  padding: 0 0 25px 0;
  margin: 15px 0 20px 0;
}

h2::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 50px;
  height: 5px;
  background: #f79c31;
}

.panel-container > .panel + .panel {
  margin-top: 15px;
}

.panel {
  background: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 0.1875em;
}

.panel-header {
  background: #564990;
  border-color: #564990;
  border-top-left-radius: 0.1875em;
  border-top-right-radius: 0.1875em;
  position: relative;
  transition: background .25s linear;
}

.panel-header > h4 {
  margin: 0;
}

.panel-header > h4 > a {
  position: relative;
  display: block;
  color: #fff;
  font-size: 1.125rem;
  text-decoration: none;
  padding: 15px 50px 15px 15px;
}

.panel-header:hover {
  background: #443776;
}

.panel-body {
  height: 0;
  overflow: hidden;
  transition: 0.3s height 0.2s;
}

.panel-body-container {
  padding: 15px;
}

.arrow {
  position: absolute;
  top: 22px;
  right: 10px;
  font-size: 1.7rem;
  border: solid #fff;
  border-width: 0 4px 4px 0;
  display: inline-block;
  padding: 5px;
  opacity: .5;
  transform: rotate(-135deg);
  transition: transform 0.15s linear;
}

.arrow-up {

}

.panel.open .arrow {
  transform: rotate(-315deg);
  transform-origin: center center;
}
<!DOCTYPE html>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="accordion-faq.css">
  <title>Accordion FAQ</title>
</head>
<body>
  <section class="accordion">
    <div class="accordion-container">
      <header>
        <h2>FAQs</h2>
      </header>

      <div class="panel-container">
        <div class="panel">
          <div class="panel-header">
            <h4>
              <a href="#">First question?</a>
            </h4>
            <div class="arrow"><div class="arrow-up"></div></div>
          </div>
          <div class="panel-body">
            <div class="panel-body-container">
              <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit.
                Accusantium animi blanditiis corporis dicta, dolor dolores
                enim facilis fuga itaque iure iusto molestiae mollitia
                natus nisi pariatur praesentium quo rerum vel.
              </p>
            </div>
          </div>
        </div> <!-- .panel -->

        <div class="panel">
          <div class="panel-header">
            <h4>
              <a href="#">Second question?</a>
            </h4>
            <div class="arrow arrow-up"></div>
          </div>
          <div class="panel-body">
            <div class="panel-body-container">
              <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit.
                Accusantium animi blanditiis corporis dicta, dolor dolores
                enim facilis fuga itaque iure iusto molestiae mollitia
                natus nisi pariatur praesentium quo rerum vel.
              </p>
            </div>
          </div>
        </div> <!-- .panel -->
      </div> <!-- .panel-container -->
    </div> <!-- .accordion-container -->
  </section>

  <script src="accordion-faq.js"></script>
</body>
</html>

5 个答案:

答案 0 :(得分:1)

首先,对于position: absolute可以解决问题的这类问题,您可以避免使用display: flex

const panelHeader = document.querySelectorAll(".panel-header");

panelHeader.forEach(item => {
  item.addEventListener("click", event => {
    event.preventDefault();
    item.parentElement.classList.toggle("open");
    const panel = item.nextElementSibling;
    panel.style.height = panel.style.height ? null : panel.scrollHeight + "px";
  });
});
:root {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

body {
  margin: 0;
  padding: 0;
}

.accordion {
  max-width: 1200px;
  margin: 0 auto;
}

.accordion-container {
  padding: 15px;
}

h2 {
  color: #444;
  font-size: 1.75rem;
  position: relative;
  padding: 0 0 25px 0;
  margin: 15px 0 20px 0;
}

h2::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 50px;
  height: 5px;
  background: #f79c31;
}

.panel-container>.panel+.panel {
  margin-top: 15px;
}

.panel {
  background: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 0.1875em;
}

.panel-header {
  display: flex;  /* <- Use flexbox */
  justify-content: space-between;
  align-items: center;
  background: #564990;
  border-color: #564990;
  border-top-left-radius: 0.1875em;
  border-top-right-radius: 0.1875em;
  position: relative;
  transition: background .25s linear;
}

.panel-header>h4 {
  margin: 0;
}

.panel-header>h4>a {
  position: relative;
  display: block;
  color: #fff;
  font-size: 1.125rem;
  text-decoration: none;
  padding: 15px 50px 15px 15px;
}

.panel-header:hover {
  background: #443776;
}

.panel-body {
  height: 0;
  overflow: hidden;
  transition: 0.3s height 0.2s;
}

.panel-body-container {
  padding: 15px;
}

.arrow {
  /* Don't need position absolute anymore */
  margin: 10px;
  font-size: 1.7rem;
  border: solid #fff;
  border-width: 0 4px 4px 0;
  display: inline-block;
  padding: 5px;
  opacity: .5;
  transform: rotate(-135deg);
  transition: transform 0.15s linear;
}

.arrow-up {}

.panel.open .arrow {
  margin-top: -5px;  /* <- Remove arrow heigth (5px) to stay at the same level */
  transform: rotate(-315deg);
  transform-origin: center center;
}
<!DOCTYPE html>
<html lang="en-US">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="accordion-faq.css">
  <title>Accordion FAQ</title>
</head>

<body>
  <section class="accordion">
    <div class="accordion-container">
      <header>
        <h2>FAQs</h2>
      </header>

      <div class="panel-container">
        <div class="panel">
          <div class="panel-header">
            <h4>
              <a href="#">First question?</a>
            </h4>
            <div class="arrow">
              <div class="arrow-up"></div>
            </div>
          </div>
          <div class="panel-body">
            <div class="panel-body-container">
              <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium animi blanditiis corporis dicta, dolor dolores enim facilis fuga itaque iure iusto molestiae mollitia natus nisi pariatur praesentium quo rerum vel.
              </p>
            </div>
          </div>
        </div>
        <!-- .panel -->

        <div class="panel">
          <div class="panel-header">
            <h4>
              <a href="#">Second question?</a>
            </h4>
            <div class="arrow arrow-up"></div>
          </div>
          <div class="panel-body">
            <div class="panel-body-container">
              <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium animi blanditiis corporis dicta, dolor dolores enim facilis fuga itaque iure iusto molestiae mollitia natus nisi pariatur praesentium quo rerum vel.
              </p>
            </div>
          </div>
        </div>
        <!-- .panel -->
      </div>
      <!-- .panel-container -->
    </div>
    <!-- .accordion-container -->
  </section>

  <script src="accordion-faq.js"></script>
</body>

</html>

答案 1 :(得分:1)

使用您当前的设置,最好的解决方案是-

  1. 更改动画类中的top值。您还需要将animate的值更改为all,以便它还可以动画显示最高值的变化而不会跳转。
.arrow {
  ...
  transition: all 0.15s linear;
}

.panel.open .arrow {
  transform: rotate(-315deg);
  transform-origin: center center;
  top: 18px;
}
  1. 您还可以将transform-origin更改为100% center,但这会导致动画以一种奇怪的方式旋转。

如果您不想加载字体库或SVG图标,也可以使用内置HTML箭头并旋转它们。它可能会表现出您的期望-https://www.toptal.com/designers/htmlarrows/

答案 2 :(得分:0)

请尝试将top类的.arrow属性更改为top: 50%,以免对其进行硬编码。

然后,将其添加到transform属性translate(0, -50%)中。

答案 3 :(得分:0)

在CSS中使用top专有性。
这将在旋转箭头时设置箭头的顶部位置。

这是您的代码:

"use strict";

const panelHeader = document.querySelectorAll(".panel-header");

panelHeader.forEach(item => {
  item.addEventListener("click", event => {
    event.preventDefault();
    item.parentElement.classList.toggle("open");
    const panel = item.nextElementSibling;
    panel.style.height = panel.style.height ? null : panel.scrollHeight + "px";
  });
});
:root {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

body {
  margin: 0;
  padding: 0;
}

.accordion {
  max-width: 1200px;
  margin: 0 auto;
}

.accordion-container {
  padding: 15px;
}

h2 {
  color: #444;
  font-size: 1.75rem;
  position: relative;
  padding: 0 0 25px 0;
  margin: 15px 0 20px 0;
}

h2::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 50px;
  height: 5px;
  background: #f79c31;
}

.panel-container > .panel + .panel {
  margin-top: 15px;
}

.panel {
  background: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 0.1875em;
}

.panel-header {
  background: #564990;
  border-color: #564990;
  border-top-left-radius: 0.1875em;
  border-top-right-radius: 0.1875em;
  position: relative;
  transition: background .25s linear;
}

.panel-header > h4 {
  margin: 0;
}

.panel-header > h4 > a {
  position: relative;
  display: block;
  color: #fff;
  font-size: 1.125rem;
  text-decoration: none;
  padding: 15px 50px 15px 15px;
}

.panel-header:hover {
  background: #443776;
}

.panel-body {
  height: 0;
  overflow: hidden;
  transition: 0.3s height 0.2s;
}

.panel-body-container {
  padding: 15px;
}

.arrow {
  position: absolute;
  top: 22px;
  right: 10px;
  font-size: 1.7rem;
  border: solid #fff;
  border-width: 0 4px 4px 0;
  display: inline-block;
  padding: 5px;
  opacity: .5;
  transform: rotate(-135deg);
  transition: transform 0.15s linear;
}

.arrow-up {

}

.panel.open .arrow {
  transform: rotate(-315deg);
  transform-origin: center center;
  top: 15px; //Do it!
}
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="accordion-faq.css">
  <title>Accordion FAQ</title>
</head>
<body>
  <section class="accordion">
    <div class="accordion-container">
      <header>
        <h2>FAQs</h2>
      </header>

      <div class="panel-container">
        <div class="panel">
          <div class="panel-header">
            <h4>
              <a href="#">First question?</a>
            </h4>
            <div class="arrow"><div class="arrow-up"></div></div>
          </div>
          <div class="panel-body">
            <div class="panel-body-container">
              <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit.
                Accusantium animi blanditiis corporis dicta, dolor dolores
                enim facilis fuga itaque iure iusto molestiae mollitia
                natus nisi pariatur praesentium quo rerum vel.
              </p>
            </div>
          </div>
        </div> <!-- .panel -->

        <div class="panel">
          <div class="panel-header">
            <h4>
              <a href="#">Second question?</a>
            </h4>
            <div class="arrow arrow-up"></div>
          </div>
          <div class="panel-body">
            <div class="panel-body-container">
              <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit.
                Accusantium animi blanditiis corporis dicta, dolor dolores
                enim facilis fuga itaque iure iusto molestiae mollitia
                natus nisi pariatur praesentium quo rerum vel.
              </p>
            </div>
          </div>
        </div> <!-- .panel -->
      </div> <!-- .panel-container -->
    </div> <!-- .accordion-container -->
  </section>

  <script src="accordion-faq.js"></script>
</body>

现场演示:https://codepen.io/marchmello/pen/mdedGra

答案 4 :(得分:0)

您需要在position: absolute CSS上使用top.panel.open .arrow位置,如下所示:

"use strict";

const panelHeader = document.querySelectorAll(".panel-header");

panelHeader.forEach(item => {
  item.addEventListener("click", event => {
    event.preventDefault();
    item.parentElement.classList.toggle("open");
    const panel = item.nextElementSibling;
    panel.style.height = panel.style.height ? null : panel.scrollHeight + "px";
  });
});
:root {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

body {
  margin: 0;
  padding: 0;
}

.accordion {
  max-width: 1200px;
  margin: 0 auto;
}

.accordion-container {
  padding: 15px;
}

h2 {
  color: #444;
  font-size: 1.75rem;
  position: relative;
  padding: 0 0 25px 0;
  margin: 15px 0 20px 0;
}

h2::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 50px;
  height: 5px;
  background: #f79c31;
}

.panel-container > .panel + .panel {
  margin-top: 15px;
}

.panel {
  background: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 0.1875em;
}

.panel-header {
  background: #564990;
  border-color: #564990;
  border-top-left-radius: 0.1875em;
  border-top-right-radius: 0.1875em;
  position: relative;
  transition: background .25s linear;
}

.panel-header > h4 {
  margin: 0;
}

.panel-header > h4 > a {
  position: relative;
  display: block;
  color: #fff;
  font-size: 1.125rem;
  text-decoration: none;
  padding: 15px 50px 15px 15px;
}

.panel-header:hover {
  background: #443776;
}

.panel-body {
  height: 0;
  overflow: hidden;
  transition: 0.3s height 0.2s;
}

.panel-body-container {
  padding: 15px;
}

.arrow {
  position: absolute;
  top: 22px;
  right: 10px;
  font-size: 1.7rem;
  border: solid #fff;
  border-width: 0 4px 4px 0;
  display: inline-block;
  padding: 5px;
  opacity: .5;
  transform: rotate(-135deg);
  transition: transform 0.15s linear;
}

.arrow-up {

}

.panel.open .arrow {
  transform: rotate(-315deg);
  transform-origin: center center;
  position: absolute;
  top: 30%;
}
<!DOCTYPE html>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="accordion-faq.css">
  <title>Accordion FAQ</title>
</head>
<body>
  <section class="accordion">
    <div class="accordion-container">
      <header>
        <h2>FAQs</h2>
      </header>

      <div class="panel-container">
        <div class="panel">
          <div class="panel-header">
            <h4>
              <a href="#">First question?</a>
            </h4>
            <div class="arrow"><div class="arrow-up"></div></div>
          </div>
          <div class="panel-body">
            <div class="panel-body-container">
              <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit.
                Accusantium animi blanditiis corporis dicta, dolor dolores
                enim facilis fuga itaque iure iusto molestiae mollitia
                natus nisi pariatur praesentium quo rerum vel.
              </p>
            </div>
          </div>
        </div> <!-- .panel -->

        <div class="panel">
          <div class="panel-header">
            <h4>
              <a href="#">Second question?</a>
            </h4>
            <div class="arrow arrow-up"></div>
          </div>
          <div class="panel-body">
            <div class="panel-body-container">
              <p>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit.
                Accusantium animi blanditiis corporis dicta, dolor dolores
                enim facilis fuga itaque iure iusto molestiae mollitia
                natus nisi pariatur praesentium quo rerum vel.
              </p>
            </div>
          </div>
        </div> <!-- .panel -->
      </div> <!-- .panel-container -->
    </div> <!-- .accordion-container -->
  </section>

  <script src="accordion-faq.js"></script>
</body>
</html>