Как вертикально выровнять стрелку CSS, которая разворачивает гармошку? - PullRequest
2 голосов
/ 09 апреля 2020

Я использовал 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 ]

1 голос
/ 09 апреля 2020

При текущей настройке лучшим решением будет либо -

  1. Изменить значение top в классе анимации. Вам также нужно изменить значение animate на all, чтобы оно также анимировало изменение верхнего значения без скачков.
.arrow {
  ...
  transition: all 0.15s linear;
}

.panel.open .arrow {
  transform: rotate(-315deg);
  transform-origin: center center;
  top: 18px;
}
Вы также можете изменить transform-origin на 100% center, однако это заставит анимацию вращаться странным образом.

Вы также можете использовать встроенные стрелки HTML и вращая их, если вы не хотите загружать библиотеку шрифтов или значок SVG. Он может вести себя больше, чем вы ожидаете - https://www.toptal.com/designers/htmlarrows/

1 голос
/ 09 апреля 2020

Прежде всего, вы можете избежать использования 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>
0 голосов
/ 09 апреля 2020

Используйте свойство top в 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;
  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

0 голосов
/ 09 апреля 2020

Вам необходимо использовать позиции position: absolute и top на вашем .panel.open .arrow 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;
  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>
0 голосов
/ 09 апреля 2020

Попробуйте изменить свойство top класса .arrow на top: 50%, чтобы оно не было жестко закодировано.

Затем добавьте к свойству transform translate(0, -50%).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...