3300.me

accordion

last update: 2020/12/19
<!doctype html>
<title>accordion</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1, viewport-fit=cover">

<style>
html, body, ul {
  margin: 0;
  padding: 0;
}
body {
  margin: 0 auto;
  padding: 10px;
  max-width: 500px;
}
.listSet {
  position: relative;
}
.itemList {
  margin-bottom: 80px;
  overflow: hidden;
  transition: height 0.3s;
}
.itemList li {
  list-style: none;
  float: left;
  width: calc((100% - 20px) / 3);
  height: 30vw;
  margin-left: 10px;
  margin-bottom: 10px;
  background: #f1f1f1;
  border: #ddd 1px solid;
  box-sizing: border-box;
}
.itemList li:nth-child(3n+1) {
  margin-left: 0;
}
.listSet.setB li {
  height: 40vw;
}
@media screen and (min-width: 500px) {
  .itemList li {
    height: 158px;
  }
  .listSet.setB li {
    height: 200px;
  }
}
.toggle {
  position: absolute;
  bottom: -30px;
  left: calc(50% - 4px);
  content: "";
  display: block;
  width: 10px;
  height: 10px;
  border-right: #000 2px solid;
  border-bottom: #000 2px solid;
  transform: rotate(225deg);
  cursor: pointer;
}
.close .toggle {
  transform: rotate(45deg);
}
</style>

<div class="listSet setA close">
<ul class="itemList">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
<li>14</li>
<li>15</li>
<li>16</li>
<li>17</li>
<li>18</li>
</ul>
<div class="toggle"></div>
</div>

<div class="listSet setB close">
<ul class="itemList">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
<li>14</li>
<li>15</li>
<li>16</li>
<li>17</li>
<li>18</li>
</ul>
<div class="toggle"></div>
</div>

<script>
const setAccordionEvent = () => {
  const getHeight = (area, param) => parseInt((area.currentStyle || document.defaultView.getComputedStyle(area, ''))[param], 10);
  const itemLists = document.querySelectorAll('.listSet');
  const flag = 'close';
  const minimum = 2;
  Object.values(itemLists).forEach((list) => {
    const frame = list.querySelector('.itemList');
    const topItem = list.querySelectorAll('li')[0];
    const toggle = list.querySelector('.toggle');
    const minHeight = (getHeight(topItem, 'height') + getHeight(topItem, 'margin-bottom') + getHeight(topItem, 'margin-top')) * minimum;
    const maxHeight = getHeight(list, 'height');
    const setHeight = (h) => frame.style.height = h + 'px';
    toggle.addEventListener('click', () => {
      if (list.classList.contains(flag)) {
        list.classList.remove(flag);
        setHeight(maxHeight);
      } else {
        list.classList.add(flag);
        setHeight(minHeight);
      }
    });
    setHeight(minHeight);
  });
};

window.onload = () => {
  setAccordionEvent();
};
</script>

code_popup

sample