首页 > 解决方案 > 使用纯 CSS 切换动画元素(复选框 hack)

问题描述

document.querySelector( "style" ).innerHTML += `
  html { overflow: hidden; font-size: 5.5vmin; user-select: none; }
  html, table, caption, th, td, p {
    margin: 0; padding: 1rem;
    border-bottom-style: solid; border-color: #f5f5f5;
    background-color: #fbfbfb; color: #444;
    text-align: left; text-transform: capitalize;
    border-spacing: 0;
  }
  html, table, caption, caption p, thead, thead p, td p {
    border-style: none; background-color: transparent;
  }
  html { font-family: Arial; }
  [ type="checkbox" ] { display: none; }
  table {
    position: relative; top: -2rem;
    width: 100%; max-width: 40rem;
    margin: 1rem auto;
  }
  caption p, thead th, thead p {
    border-style: none; background-color: #f7f7f7;
    text-transform: uppercase;
  }
  caption, caption p {
    padding: 0 1rem; background-color: transparent;
    font-weight: bold; text-transform: uppercase;
    letter-spacing: 0.125rem;
  }
  #clear thead p { color: #444; }
  th:first-child { border-top-left-radius: 0.5rem; }
  th:last-child { border-top-right-radius: 0.5rem; }
`;
td, p {
  color: #555; cursor: default;
  transition-property: border-color, color, font-size, letter-spacing;
  transition-duration: 1s;
}
tr:hover td { border-color: #eee; }
tfoot td:first-child { border-bottom-left-radius: 0.5rem; }
tfoot td:last-child { border-bottom-right-radius: 0.5rem; }
tr p:hover { color: #000; }
[ for="tog" ], [ for="tog" ]::after {
  position: absolute; top: 1rem; left: 1rem;
  z-index: 1;
  display: block;
  width: 7rem; height: 4rem;
  margin: 1rem; background-color: #ddd;
  border-radius: 4rem; content: ""; cursor: pointer;
  transition-property: left, background-color; transition-duration: 0.5s;
}
[ for="tog" ]::after {
  position: absolute; top: 0; left: 0;
  transform: scale( 0.7 ); margin: 0;
  width: 4rem; background-color: #eee;
}
#tog:checked ~ main [ for="tog" ]::after {
  left: 3rem; background-color: #ddd;
}
#tog:checked ~ main [ for="tog" ] { background-color: #444; }
#dark { display: none; }
#tog:checked ~ main #clear { display: none; }
#tog:checked ~ main #dark { display: table; }
#dark th, #dark th p { background-color: #222; color: #f5f5f5; }
#dark tfoot td { background-color: #f5f5f5; }
<input type="checkbox" id="tog">
<main>
  <div class="tog_wrap"> <label for="tog"></label> </div>
  <table id="clear">
    <caption> <p> table </p> </caption>
    <thead>
      <tr>
        <th> <p>one</p> </th> <th> <p>two</p> </th> <th> <p>three</p> </th>
      </tr>
    </thead>
    <tbody>
      <td> <p>four</p> </td> <td> <p>five</p> </td> <td> <p>six</p> </td>
    </tbody>
    <tfoot>
      <td> <p>seven</p> </td> <td> <p>eight</p> </td> <td> <p>nine</p> </td>
    </tfoot>
  </table>

  <table id="dark">
    <caption> <p> table </p> </caption>
    <thead>
      <tr>
        <th> <p>one</p> </th> <th> <p>two</p> </th> <th> <p>three</p> </th>
      </tr>
    </thead>
    <tbody>
      <td> <p>four</p> </td> <td> <p>five</p> </td> <td> <p>six</p> </td>
    </tbody>
    <tfoot>
      <td> <p>seven</p> </td> <td> <p>eight</p> </td> <td> <p>nine</p> </td>
    </tfoot>
  </table>      
</main>

在上面的示例中,我使用 CSS 复选框来交换 2 个表格的显示以模拟更改一个表格的样式。

我的问题是如何在没有 JavaScript 的交换期间为这些样式设置动画?有没有办法用 CSS 中的复选框触发不透明度或(任何)动画?我可以为复选框本身设置动画,但是如何使用这种技术从一张桌子淡入另一张桌子。还是没有 JS 也有可能?

编辑:一开始的查询选择器只是为了添加更多的 CSS 样式而不在 CSS 窗格中使用更多空间以提高可读性。我在问这是否可以在没有 JavaScript 的情况下完成。

标签: htmlcsscss-animationscss-transitions

解决方案


document.querySelector( 'style' ).innerHTML +=`
  #clear thead p {
    color: #444;
  }
  th:first-child {
    border-top-left-radius: 0.5rem;
  }
  th:last-child {
    border-top-right-radius: 0.5rem;
  }
  td, p {
    color: #555; cursor: default;
  }
  tr:hover td {
    border-color: #eee;
  }
  tfoot td:first-child {
    border-bottom-left-radius: 0.5rem;
  }
  tfoot td:last-child {
    border-bottom-right-radius: 0.5rem;
  }
  tr p:hover {
    color: #000;
  }
  [ for="tog" ], [ for="tog" ]::after {
    position: relative; display: block;
    width: 7rem; height: 4rem;
    margin: 1rem; background-color: #ddd; border-radius: 4rem; content: "";
    cursor: pointer; transition-property: left, background-color;
    transition-duration: 0.5s;
  }
`
html { overflow: hidden; font-size: 5.5vmin; }
.tog_wrap { position: absolute; z-index: 1; top: 1rem; left: 1rem; }
html, table, caption, th, td, p {
  margin: 0; padding: 1rem;
  border-bottom-style: solid; border-color: #f5f5f5;
  background-color: #fbfbfb; color: #444;
  text-align: left; text-transform: capitalize;
  border-spacing: 0; transition-property: all;
  transition-duration: 1s;  
}
html, table, caption, caption p, thead, thead p, td p {
  border-style: none; background-color: transparent;
}
html {
  font-family: Arial;
}
[ type="checkbox" ] {
  display: none;
}
table {
  width: 100%; max-width: 40rem; position: relative; top: -2rem;
  margin: 1rem auto; user-select: none;
}
caption p, thead th, thead p {
  border-style: none; background-color: #f7f7f7;
  text-transform: uppercase;
}
caption, caption p {
  padding: 0 1rem; 
  background-color: transparent;
  font-weight: bold; text-transform: uppercase;
  letter-spacing: 0.125rem;
}
<style>
  [ for="tog" ]:hover { background-color: #ccc; }
  [ for="tog" ]::after {
    position: absolute; left: 0;
    transform: scale( 0.7 ); margin: 0;
    width: 4rem; background-color: #eee;
  }
  #tog:checked ~ main [ for="tog" ]::after { left: 3rem; background-color: #ddd; }
  #tog:checked ~ main [ for="tog" ] { background-color: #444; }
  #tog:checked ~ main [ for="tog" ]:hover { background-color: #333; }
  #tog:checked ~ main #clear th, #tog:checked ~ main #clear th p { 
  background-color: #222; color: #f5f5f5; 
  }
  #tog:checked ~ main #clear tfoot td { background-color: #f5f5f5; }
</style>
<input type="checkbox" id="tog">
<main>
  <div class="tog_wrap"> <label for="tog"></label> </div>
  <table id="clear">
    <caption> <p> table </p> </caption>
    <thead>
      <tr>
        <th> <p>one</p> </th> <th> <p>two</p> </th> <th> <p>three</p> </th>
      </tr>
    </thead>
    <tbody>
      <td> <p>four</p> </td> <td> <p>five</p> </td> <td> <p>six</p> </td>
    </tbody>
    <tfoot>
      <td> <p>seven</p> </td> <td> <p>eight</p> </td> <td> <p>nine</p> </td>
    </tfoot>
  </table>     
</main>


推荐阅读