css 如何让所有的“+”按钮相互垂直对齐?

zzlelutf  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(172)

我正在为我正在编写的一个项目做一个常见问题解答部分。我将列出潜在买家可能会遇到的常见问题。我希望当用户在问题后单击+按钮时,在下面打开一个新的段落来回答问题。我现在关注的是让所有的+按钮都垂直对齐。如果你看看现在的情况,每个+都根据问题的长度排列在不同的位置。我使用justify-content: space-between来使问题和+之间有一个合理的距离,但它看起来很俗气,所有+都没有垂直对齐在一起。

section {
  background-color: #fff;
  height: 100vh;
  height: fill-available;
  min-height: -moz-available;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  overflow-x: hidden;
}

.faq {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.container {
  display: flex;
  width: 60vw;
}

.left {
  width: 100%;
}

.get-started {
  font-family: "Poppins", sans-serif;
  font-size: 28px;
}

.question {
  display: flex;
  justify-content: space-between;
}
<section class="faq">
        <div class="container">
          <div class="left">
            <div class="get-started">
              <p>Learn How To Get Started</p>
            </div>
            <div class="question">
              <p>How do I create a website?</p>
              <button>+</button>
              <div>
                <p></p>
              </div>
            </div>
            <div class="question">
              <p>Is this website right for me?</p>
              <button>+</button>
              <div>
                <p></p>
              </div>
            </div>
           <div class="question">
             <p>How much will web storage cost me?</p>
             <button>+</button>
             <div>
               <p></p>
             </div>
           </div>
          </div>
        </div>
      </section>
gc0ot86w

gc0ot86w1#

/* simple demo, I didn't want to put a lot of time into creating a "pretty" demo, though */

// retrieving all elements matching the selector:
const questions = document.querySelectorAll('.question'),
    buttons = document.querySelectorAll('.question button'),
    // defining the toggle() function, using Arrow syntax:
    toggle = (evt) => {
      // destructuring assignment to retrieve the value of
      // the currentTarget property from the Event Object
      // (passed automatically from EventTarget.addEventListener())
      // to a variable of the same name:
      let {currentTarget} = evt,
          // navigation to the closest '.question' ancestor, and
          // from there, finding the first <div> element within
          // that '.question' element; this allows for some
          // reorganisation of the HTML:
          answer = currentTarget.closest('.question').querySelector('div');

      // we set the hidden property of the found answer to be the inverse
      // of the current state of the hidden property; 'hidden' is a Boolean
      // property so it will either be true or false. If it's currently
      // true we invert that to false, and vice-versa:
      answer.hidden = !answer.hidden;
      
      // we update the text-content of the <button> to either
      // '-' if the answer is now visible (hidden: false) and
      // to '+' if the element is not visible (hidden: true):
      currentTarget.textContent = !answer.hidden ? '-' : '+';
      
    }
 
 // iterating over the '.question' elements and setting hidden: true, to
 // hide them on page load:
 questions.forEach((q) => q.querySelector('div').hidden = true);
 
 // iterating over the <button> elements and, using an Arrow function
 buttons.forEach(
  // we bind the toggle() function as the event-handler for the
  // 'click' event on each <button> in the NodeList:
  (btn) => btn.addEventListener('click', toggle)
 );
/* reorganised the CSS to follow an order that makes sense to me,
   basically following the HTML structure from the top 'section.faq'
   inwards through the hierarchy of elements in order to make it
   - for me, personally - easier to follow the cascade: */
section {
  background-color: #fff;
  height: 100vh;
  height: fill-available;
  min-height: -moz-available;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  overflow-x: hidden;
}

.faq {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.container {
  display: flex;
  width: 60vw;
}

.left {
  width: 100%;
}

.get-started {
  font-family: "Poppins", sans-serif;
  font-size: 28px;
}

.question {
  display: flex;
  /* using shorthand to explicitly set:
       flex-direction: row;
       flex-wrap: wrap; */
  flex-flow: row wrap;
  justify-content: space-between;
}

/* because of the way that flex-items are sized,
   changing the <button> text (see the JS) causes
   the <button> to have different sizing depending
   on the text, and the open/closed state of the
   answer text's visibility; this is set simply
   to have the browser maintain the size consistently: */
.question button {
  flex-basis: 2rem;
}

.question div {
  /* to have the <div> containing the answer take
     up the full available space, so forcing it
     to wrap to the next line (thanks to flex-wrap: wrap
     overriding the default value of flex: nowrap): */
  flex-basis: 100%;
}
<section class="faq">
  <div class="container">
    <div class="left">
      <div class="get-started">
        <p>Learn How To Get Started</p>
      </div>
      <div class="question">
        <p>How do I create a website?</p>
        <button>+</button>
        <div>
          <p>You can create a website following our simple <a href="#">guidelines</a>, <a href="#">wizards</a>, or <a href="#">intuitive UI</a>.</p>
        </div>
      </div>
      <div class="question">
        <p>Is this website right for me?</p>
        <button>+</button>
        <div>
          <p>Do you like it? That's your answer!</p>
        </div>
      </div>
      <div class="question">
        <p>How much will web storage cost me?</p>
        <button>+</button>
        <div>
          <p>Time, money, blood, sweat, and tears in convenient monthly installments.</p>
        </div>
      </div>
    </div>
  </div>
</section>

JS Fiddle demo
至于如何更好地处理它,利用现有的HTML元素和原生功能,我建议如下(正如在问题的评论中已经提到的):

/* reorganised the CSS to follow an order that makes sense to me,
   basically following the HTML structure from the top 'section.faq'
   inwards through the hierarchy of elements in order to make it
   - for me, personally - easier to follow the cascade: */
section {
  background-color: #fff;
  height: 100vh;
  height: fill-available;
  min-height: -moz-available;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  overflow-x: hidden;
}

.faq {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.container {
  display: flex;
  width: 60vw;
}

.left {
  width: 100%;
}

.get-started {
  font-family: "Poppins", sans-serif;
  font-size: 28px;
}

/* hiding the default marker, the triangle (this doesn't
   affect functionality, I just assumed you'd rather
   retain a <button>-like interactivity/state element: */
.faq ::marker {
  content: '';
}

summary {
  /* to indicate interactivity: */
  cursor: pointer;
  display: flex;
  justify-content: space-between;
}

/* styling the <span> element: */
details span {
  /* ensuring that the element is equally wide as it is
     tall: */
  aspect-ratio: 1;
  background-color: lightskyblue;
  /* to create a round indicator: */
  clip-path: circle(50%);
  /* setting the dimensions of the element in concert
     with aspect-ratio: */
  inline-size: 2rem;
  /* large line-height to place the text in vertical, or
     block-axis, center of the element: */
  line-height: 2rem;
  /* aligning the text centrally on the inline-axis,
     horizontal in English, European languages: */
  text-align: center;
}

/* styling the <span> when the ancestor <details> element
   has the "open" attribute (adjust to taste, please): */
details[open] span {
  background-color: palegreen;
}

/* setting the default text of the <span> element's
   ::before pseudo element: */
details span::before {
  content: '+';
}

/* setting the text of the <span> element's
   ::before element when its ancestor <details>
   element has the "open" attribute, which is
   set and handled by the browser by default 
   (although the user can also write the attribute
   in the HTML to influence the default state): */
details[open] span::before {
  content: '-';
}
<section class="faq">
  <div class="container">
    <div class="left">
      <div class="get-started">
        <p>Learn How To Get Started</p>
      </div>

      <!-- using the <details> element to contain both the question and the answer: -->
      <details>
        <!-- the <summary> element is visible on the page by default, and should the
             user click on that element, the 'answer' (any child element(s) which are
             not the <summary> will be toggled between visible/invisible based on
             the presence, or absence, of the "open" attribute on the ancestor
             <details>. The <button> element - with no text or child content - serves
             as the wrapper for the indicator '+'/'-' text which indicates the
             functionality of clicking-->
        <summary>How do I create a website? <span></span></summary>
        <p>You can create a website following our simple <a href="#">guidelines</a>, <a href="#">wizards</a>, or <a href="#">intuitive UI</a>.</p>
      </details>
      <details>
        <summary>Is this website right for me? <span></span></summary>
        <p>Do you like it? That's your answer!</p>
      </details>

      <details>
        <summary>How do I create a website? <span></span></summary>
        <p>You can create a website following our simple <a href="#">guidelines</a>, <a href="#">wizards</a>, or <a href="#">intuitive UI</a>.</p>
      </details>
      <details>
        <summary>How much will web storage cost me?</summary>
        <p>Time, money, blood, sweat, and tears in convenient monthly installments.</p>
      </details>

    </div>
  </div>
</section>

JS Fiddle demo
参考文献:

nfeuvbwi

nfeuvbwi2#

如果你想使用justify-content: space-between;右对齐按钮,你应该只有两个元素在容器中,否则,容器的所有元素之间将有相同的空间(在你的例子中,按钮之后)。在下面的代码片段中,我创建了一个div(.label)来 Package 问题段落和按钮,然后我在上面使用了flexbox。

section {
    background-color: #fff;
    height: 100vh;
    height: fill-available;
    min-height: -moz-available;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    overflow-x: hidden;
}

.faq {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.container {
    display: flex;
    width: 60vw;
}

.left {
    width: 100%;
}

.get-started {
    font-family: "Poppins", sans-serif;
    font-size: 28px;
}

/* Use flex on the label div */
    .question .label {
    display: flex;
    justify-content: space-between;
}
<section class="faq">
    <div class="container">
        <div class="left">
            <div class="get-started">
                <p>Learn How To Get Started</p>
            </div>
            <div class="question">
                <div class="label">
                    <p>How do I create a website?</p>
                    <button>+</button>
                </div>
                <div>
                    <p></p>
                </div>
            </div>
            <div class="question">
                <div class="label">
                    <p>Is this website right for me?</p>
                    <button>+</button>
                </div>
                <div>
                    <p></p>
                </div>
            </div>
            <div class="question">
                <div class="label">
                    <p>How much will web storage cost me?</p>
                    <button>+</button>
                </div>
                <div>
                    <p></p>
                </div>
            </div>
        </div>
    </div>
</section>

相关问题