最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - CSS ExpandContract Animation to ShowHide Content - Stack Overflow

programmeradmin2浏览0评论

I am trying to create a box that can expand and collapse with a simple slide out animation. If you run the example below, the idea is that it starts with one red line and when you click the button it separates into two read lines and gently expands to reveal the content like pulling a draw out of a table.

I've tried both transform, animation, relative: positioning with top, and i'm unable to get the desired effect.

The containing box should expand in size

function expandContract() {
   const el = document.getElementById("expand-contract")
   el.classList.toggle('expanded')
   el.classList.toggle('collapsed')
}
#container {
   border: 1px solid black;
   padding: 15px;
}

#top-section {
  border-bottom: 1px solid red;
}

#expand-contract {
  border-bottom: 1px solid red;
}

.expand-contract {
   transform: translateY(-100%)
   overflow: hidden;
}

@keyframes slide-in {
    100% {
        transform: translateY(0%)
    }
}

.expanded {
   background-color: green;
   animation-name: slide-in;
   animation-duration: 1s;
}

.collapsed {
   background-color: red;
   transform: translateY(-100%)
}
<div id="container">
  <div id="top-section">
    This is always displayed
  </div>
  
  <div id="expand-contract" class="expanded">
    This section expands and contracts
  
    <table>
      <tr><td>test1</td></tr>
      <tr><td>test2</td></tr>
      <tr><td>test3</td></tr>
      <tr><td>test4</td></tr>
    </table>
  </div>
  
  <div id="bottom-section">
    This section is always displayed
  </div>
</div>

<button onclick="expandContract()">Expand/Contract</button>

I am trying to create a box that can expand and collapse with a simple slide out animation. If you run the example below, the idea is that it starts with one red line and when you click the button it separates into two read lines and gently expands to reveal the content like pulling a draw out of a table.

I've tried both transform, animation, relative: positioning with top, and i'm unable to get the desired effect.

The containing box should expand in size

function expandContract() {
   const el = document.getElementById("expand-contract")
   el.classList.toggle('expanded')
   el.classList.toggle('collapsed')
}
#container {
   border: 1px solid black;
   padding: 15px;
}

#top-section {
  border-bottom: 1px solid red;
}

#expand-contract {
  border-bottom: 1px solid red;
}

.expand-contract {
   transform: translateY(-100%)
   overflow: hidden;
}

@keyframes slide-in {
    100% {
        transform: translateY(0%)
    }
}

.expanded {
   background-color: green;
   animation-name: slide-in;
   animation-duration: 1s;
}

.collapsed {
   background-color: red;
   transform: translateY(-100%)
}
<div id="container">
  <div id="top-section">
    This is always displayed
  </div>
  
  <div id="expand-contract" class="expanded">
    This section expands and contracts
  
    <table>
      <tr><td>test1</td></tr>
      <tr><td>test2</td></tr>
      <tr><td>test3</td></tr>
      <tr><td>test4</td></tr>
    </table>
  </div>
  
  <div id="bottom-section">
    This section is always displayed
  </div>
</div>

<button onclick="expandContract()">Expand/Contract</button>

Share Improve this question asked Jan 8, 2018 at 2:02 Tony J WatsonTony J Watson 7093 gold badges10 silver badges22 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 31

You can achieve this using the CSS transition along with toggled styles. Initially you may think to transition the height (from 0 to initial so that it expands dynamically based on height) but unfortunately CSS transition doesn't properly handle this.

Instead, you can wrap it in a container of its own with overflow: hidden and then use a margin-top: -100% to hide it, and 0 to show it.

Here is your code with this modification:

function expandContract() {
   const el = document.getElementById("expand-contract")
   el.classList.toggle('expanded')
   el.classList.toggle('collapsed')
}
#container {
   border: 1px solid black;
   padding: 15px;
}

#top-section {
  border-bottom: 1px solid red;
}

#expand-container {
  overflow: hidden;
}

#expand-contract {
  border-bottom: 1px solid red;
  margin-top: -100%;
  transition: all 1s;
}

#expand-contract.expanded {
   background-color: green;
   margin-top: 0;
}
<div id="container">
  <div id="top-section">
    This is always displayed
  </div>
  
  <div id="expand-container">
    <div id="expand-contract" class="expanded">
      This section expands and contracts
  
      <table>
        <tr><td>test1</td></tr>
        <tr><td>test2</td></tr>
        <tr><td>test3</td></tr>
        <tr><td>test4</td></tr>
      </table>
    </div>
  </div>
  
  <div id="bottom-section">
    This section is always displayed
  </div>
</div>

<button onclick="expandContract()">Expand/Contract</button>

here is an example that uses jquery

hope to help you

function expandContract() {
    $header = $(".header");
    $content = $("#expand-contract")
    $content.slideToggle(500, function () {
        $header.text(function () {
            return $content.is(":visible") ? "Collapse" : "Expand";
        });
    });
};
.container {
    width:100%;
    border:1px solid #d3d3d3;
}
.container div {
    width:100%;
}
.header {
    background-color:#d3d3d3;
    padding: 2px;
    cursor: pointer;
    font-weight: bold;
}
.container .expanded {
    display: none;
    padding : 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
    <div id="top-section">
      This is always displayed
    </div>
   <div id="expand-container">
    <div class="expanded" id="expand-contract">
         <table>
            <tr><td>test1</td></tr>
            <tr><td>test2</td></tr>
            <tr><td>test3</td></tr>
            <tr><td>test4</td></tr>
        </table>
    </div>
  </div>
</div>
<button class="header" onclick="expandContract()">Expand/Contract</button>

also see codepen here.

Here is a workaround without JS just CSS & HTML tricks, making use of <input type="checkbox" /> in order to collapse/expand your content.

Below the snipped illustrates a dismissible alert. The important thing here is that the .wrapper needs to have overflow: hidden and we play with .alert's height.

If the .alert has padding we need to add a negative margin to the .alert when it's checked so that it behaves like it has been removed from context.

The collapse can either be triggered from the X button inside the .alert or from the Toggle button below.

.wrapper {
  overflow: hidden;
}

.alert {
  font-family: sans-serif;
  font-size: 16px;
  border-radius: 4px;
  padding: 20px;
  display: flex;
  align-items: center;
  gap: 16px;
  transition: visibility .3s linear, opacity .3s ease, margin-top .3s ease, height .3s ease;
  border: 1px solid #ccc;
  background: #FEECCA;
}

.body {
    flex: 1;
}

.check {
  visibility: hidden;
  position: absolute;
  top: -9999px;
  left: -9999px;
}
    
.check:checked + .alert {
  height: 0;
  margin-top: -40px; /* if your collapsible element has padding, use the top & bottom padding value */
  visibility: hidden;
  opacity: 0;
}

.close {
  cursor: pointer;
}
    
.button {
  padding:15px 20px;
  font-family: sans-serif;
  font-size: 16px;
  display: inline-block;
  border: 1px solid #ccc;
  cursor: pointer;
}
<div class="wrapper">
  <input type="checkbox" class="check" id="check1">
  <div class="alert">
    <div class="body">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nulla elit, iaculis vitae facilisis quis, sollicitudin elementum lacus. Nunc vitae tellus vel mi ullamcorper luctus. Nunc laoreet ligula diam.</div>
    <label class="close" for="check1" tabindex="0" aria-label="Close">
      <svg class="icon-close" width="12" height="12" aria-hidden="true" viewBox="0 0 32 32">
        <path d="M2.897 0.434l28.303 28.303c0.579 0.579 0.579 1.518 0 2.096s-1.518 0.579-2.096 0l-28.303-28.303c-0.579-0.579-0.579-1.518 0-2.096s1.518-0.579 2.096 0z"></path>
        <path d="M0.8 29.469l28.303-28.303c0.579-0.579 1.518-0.579 2.096 0s0.579 1.518 0 2.096l-28.303 28.303c-0.579 0.579-1.518 0.579-2.096 0s-0.579-1.518 0-2.096z"></path>
      </svg>
    </label>
  </div>
</div>

<br/>
<br/>

<label class="button" for="check1" tabindex="0" aria-label="Toggle" role="button">Toggle Collapse/Expand</label>

发布评论

评论列表(0)

  1. 暂无评论