Table toggle not working in Safari... works fine in Chrome

Viewed 55

I have a simple table that also has a td that is offset and acts as a toggle. It switches between 3 states and is working fine in Chrome. Can anyone help me and explain why it does not currently work in Safari, I have not tested this in other browsers yet, but would like solution to work in other browsers too.

Pic and code attached.

Thank you for any help and solutions.

M.

Comparison of Chrome and Safari

highlight {
    background-color: #86C440;
    color: white;
}

th {
  font-size: 30px;
}

tr {
  text-align: left;
}

td {
  font-size: 20px;
  background-color: #d4d6d3;
  cursor: pointer;
}

.center {
  margin-left: auto;
  margin-right: auto;
}

tr {
  position:relative;
  transform:scale(1,1);
}

td.last{
  position:fixed;
  border: 5px solid #d4d6d3;
  background-color: #4eafef;
  left: -46px;
  top: -46px;
  height: 7px;
  width: 7px;
  line-height: 7px;
  cursor: pointer;
}
    <html>
        
    <body>
<div id="switch">1</div>
<br><br><br><br><br><br><br><br>

<style>

  table          {border-collapse: collapse; border: 5px solid white; padding: 5px;}
  table td       {text-align: center; color: black; border: 5px solid white; padding: 10px; height: 66px; width: 66px;}
  
</style>


<table class="center">
 <tr>
   <td>1</td>
   <td>2</td>
   <td id="toggle" class="last" onclick="toggle1()"></td>
 </tr>
    <tr>
   <td>3</td>
   <td>4</td>
 </tr>
    <tr>
   <td>5</td>
   <td>6</td>
 </tr>
</table>

</body>

    <script>

    function toggle1() {

                var key = document.getElementById("switch").innerHTML;

              if (key == 1) {

                      document.getElementById("toggle").style.backgroundColor = "white";
                      document.getElementById("toggle").style.backgroundImage = "url('')";
                      document.getElementById("toggle").style.borderStyle = "solid";
                      document.getElementById("toggle").style.borderColor = "#d4d6d3";
                      document.getElementById("toggle").style.borderWidth = "5px";
                      document.getElementById("switch").innerHTML = 2;

                            //console.log("toggle clicked 1st time!");

              } else if (key == 2) {

                      document.getElementById("toggle").style.backgroundColor = "#a370f0";
                      document.getElementById("toggle").style.backgroundImage = "url('')";
                      document.getElementById("toggle").style.borderStyle = "solid";
                      document.getElementById("toggle").style.borderColor = "#d4d6d3";
                      document.getElementById("toggle").style.borderWidth = "5px";
                      document.getElementById("switch").innerHTML = 3;

                            //console.log("toggle clicked 2nd time!");

              } else if (key == 3) {

                      document.getElementById("toggle").style.backgroundColor = "#4eafef";
                      document.getElementById("toggle").style.backgroundImage = "url('')";
                      document.getElementById("toggle").style.borderStyle = "solid";
                      document.getElementById("toggle").style.borderColor = "#d4d6d3";
                      document.getElementById("toggle").style.borderWidth = "5px";
                      document.getElementById("switch").innerHTML = 1;

                            //console.log("toggle clicked 3rd time!");

              }

    }

    </script>

    </html>

1 Answers

There are a few problems which seem to result in Chrome/Edge behaving differently from Safari.

There is a style declaration within the body rather than the head element. This is picked up by an HTML validator as illegal HTML. The snippet below moves it to the head.

There is a setting for tr elements which implements a transform. This seems to encourage Chrome to position the fixed element relative to the table start rather than relative to the viewport. I don't have a full explanation for this other than to note that any sort of transform seems to result in this behaviour and that any transform will create a new stacking context.

There is a 3rd cell in the first row but not in the subsequent rows. This is picked up as a warning by the validator. I do not know how the table's layout is supposed to look in this circumstance, but of course the result is complicated by the fixed setting which takes the 3rd cell out of the flow visually.

This snippet takes the 3rd cell out and puts a button before the table instead. Together with the other changes Safari and Chrome/Edge now behave the same, with Safari doing the expected behavior on border-collapse.

The button's position needs working on - perhaps the button plus table should be in a container which gets positioned? It depends on exactly what is required in terms of fixing its position.

<!doctype html>
<html>

<head>
  <style>
    highlight {
      background-color: #86C440;
      color: white;
    }
    
    th {
      font-size: 30px;
    }
    
    tr {
      text-align: left;
    }
    
    td {
      font-size: 20px;
      background-color: #d4d6d3;
      cursor: pointer;
    }
    
    .center {
      margin-left: auto;
      margin-right: auto;
    }
    /* REMOVED
tr {
  position:relative;
  transform:scale(1, 1);
}
*/
    
    #toggle {
      position: fixed;
      border: 5px solid #d4d6d3;
      background-color: #4eafef;
      /* REMOVED
  left: -46px;
  top: -46px;
  */
      /* values changed */
      height: 30px;
      width: 30px;
      rline-height: 7px;
      cursor: pointer;
    }
  </style>
  <!-- MOVED FROM body -->
  <style>
    table {
      border-collapse: collapse;
      border: 5px solid white;
      padding: 5px;
    }
    
    table td {
      text-align: center;
      color: black;
      border: 5px solid white;
      padding: 10px;
      height: 66px;
      width: 66px;
    }
  </style>


</head>

<body>



  <div id="switch">1</div>
  <br><br><br><br><br><br><br><br>

  <div class="container">
    <button id="toggle" class="last" onclick="toggle1()"></button>

    <table class="center">
      <tbody>
        <tr>
          <td>1</td>
          <td>2</td>
          <!-- td last removed -->
        </tr>
        <tr>
          <td>3</td>
          <td>4</td>
        </tr>
        <tr>
          <td>5</td>
          <td>6</td>
        </tr>
      </tbody>
    </table>
  </div>


  <script>
    function toggle1() {

      var key = document.getElementById("switch").innerHTML;

      if (key == 1) {

        document.getElementById("toggle").style.backgroundColor = "white";
        document.getElementById("toggle").style.backgroundImage = "url('')";
        document.getElementById("toggle").style.borderStyle = "solid";
        document.getElementById("toggle").style.borderColor = "#d4d6d3";
        document.getElementById("toggle").style.borderWidth = "5px";
        document.getElementById("switch").innerHTML = 2;

        //console.log("toggle clicked 1st time!");

      } else if (key == 2) {

        document.getElementById("toggle").style.backgroundColor = "#a370f0";
        document.getElementById("toggle").style.backgroundImage = "url('')";
        document.getElementById("toggle").style.borderStyle = "solid";
        document.getElementById("toggle").style.borderColor = "#d4d6d3";
        document.getElementById("toggle").style.borderWidth = "5px";
        document.getElementById("switch").innerHTML = 3;

        //console.log("toggle clicked 2nd time!");

      } else if (key == 3) {

        document.getElementById("toggle").style.backgroundColor = "#4eafef";
        document.getElementById("toggle").style.backgroundImage = "url('')";
        document.getElementById("toggle").style.borderStyle = "solid";
        document.getElementById("toggle").style.borderColor = "#d4d6d3";
        document.getElementById("toggle").style.borderWidth = "5px";
        document.getElementById("switch").innerHTML = 1;

        //console.log("toggle clicked 3rd time!");

      }

    }
  </script>


  <script type="text/javascript">
  </script>
</body>

</html>

Related