【问题标题】:Safari v14 glitching when changing from display: contents to display: none inside a grid从显示更改时 Safari v14 出现故障:内容到显示:网格内没有
【发布时间】:2020-11-14 21:01:40
【问题描述】:

我已经看到这里和其他地方解决了类似的问题,但是虽然 Safari v14 似乎修复了许多类似的问题,但这里解决的问题仍然是一个问题:

使用基本的 CSS 和 HTML,我使用带有“display: contents;”的 div样式对属于 CSS 网格中一行的元素进行分组。我想向某些设置“显示:无!重要;”的“过滤”行添加一个类到行元素,从而隐藏网格上该行中的所有项目。删除该类应重新显示以前过滤的行。

这种技术在 Chrome 和 Firefox 中完美运行,但 Safari 显示了一些非常奇怪的行为——当“display: none”类被添加到过滤的行中时,它不会正确调整剩余行的大小并且它不会重新- 删除该类时显示行。

下面的例子试图完全展示这个问题。请以“整页”模式运行示例。 (事实上​​,在这里查看,它似乎只能在全页模式下工作,我无法解释)。您可以使用 Chrome 或 Firefox 并将其与 Safari 进行比较。我希望有一个解决方法:

function addRows() {
  var grid = document.getElementById("grid-div");
  if (grid.childNodes.length < 10) {
    for (var iRow = 0; iRow < 50; iRow++) {
      var row = document.createElement("div");
      row.classList.add("grid-row");
      row.id = `row-${iRow}`;
      grid.appendChild(row);
      for (var iCol = 0; iCol < 3; iCol++) {
        var label = document.createElement("label");
        label.innerHTML = `Cell ${iRow}:${iCol}`;
        row.appendChild(label);
      }
    }
  } else {
    alert("Looks like the grid was already filled");
  }
}

function hideSomeRows() {
  var grid = document.getElementById("grid-div");
  if (grid.childNodes.length > 10) {
    for (var iRow = 10; iRow < 40; iRow++) {
      var rowToHide = document.getElementById(`row-${iRow}`);
      rowToHide.classList.add("collapsed");
    }
  } else {
    alert("First you need to fill the grid")
  }
}

function showSomeRows() {
  var grid = document.getElementById("grid-div");
  if (grid.childNodes.length > 10) {
    for (var iRow = 10; iRow < 40; iRow++) {
      var rowToHide = document.getElementById(`row-${iRow}`);
      rowToHide.classList.remove("collapsed");
    }
  } else {
    alert("First you need to fill the grid")
  }
}

function hideGrid() {
  var grid = document.getElementById("grid-div");
  grid.classList.add("collapsed");
}

function showGrid() {
  var grid = document.getElementById("grid-div");
  grid.classList.remove("collapsed");
}
.body {
  overflow: auto;
  border: 2px blue dashed;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: stretch;
  padding: 0;
  margin: 0;
  height: 100vh;
  width: 100vw;
  box-sizing: border-box;
}

.main-div {
  display: flex;
  flex-direction: row;
  overflow: auto;
}

.column-div {
  display: flex;
  flex-direction: column;
  justify-items: flex-start;
  align-items: flex-start;
  overflow: auto;
}


/* Add some quick spacing */

.main-div div {
  margin-bottom: 0.4rem;
}

.main-div button {
  margin-right: 0.2rem;
}

.test-grid {
  display: grid;
  grid-template-columns: 5rem 5rem 5rem;
  row-gap: 0.3rem;
  column-gap: 0.2rem;
  justify-items: stretch;
  align-items: stretch;
  border: 1px solid black;
  /* just to see it */
  overflow: auto;
}

.test-grid .grid-row {
  display: contents;
}

.test-grid .grid-row label {
  border: 1px purple solid;
}

.collapsed {
  display: none !important;
}
<body>
  <div class="body">
    <div class="main-div">
      <div class="column-div" style="flex: none;">
        <div style="display: flex; flex: none;">
          <button onclick="addRows()">Fill Grid</button>
          <button onclick="hideGrid()">Hide Grid</button>
          <button onclick="showGrid()">Show Grid</button>
        </div>
        <div style="display: flex; flex: none;">
          <button onclick="hideSomeRows()">Hide Some Rows</button>
          <button onclick="showSomeRows()">Show Some Rows</button>
        </div>
        <div id="grid-div" class="test-grid">
          <div class="grid-row">
            <label>Column 1</label>
            <label>Column 2</label>
            <label>Column 3</label>
          </div>
        </div>
      </div>

      <div class="column-div" style="margin-left: 1rem;">
        <label>
          <b>Please use full page mode!</b><br>
             I believe this is a Safari glitch where changing an element inside a grid from 
             "display: content" to "display: none" and back is not handled properly.  Here's how to
             show this using the example to the left:
        </label>
        <ul>
          <li>
            First, click "Fill Grid" to add 50 rows (with display: content) to the grid.
            <ul>
              <li>
                If your display is short enough, the grid will go off the bottom of the display and overflow will allow you to scroll through the rows without scrolling the rest of the content.
              </li>
            </ul>
          </li>
          <li>
            Next, click "Hide Some Rows" to add a class that sets "display: none" on rows 10 to 39.
          </li>
          <ul>
            <li>
              In Chrome and Firefox, the grid resizes and the remaining rows fill the region. If your browser window is tall enough, the grid will now fit in the space available and will not need to scroll.
            </li>
            <li>
              In Safari (using v14.0.1), the grid appears to resize, but the remaining rows do not properly size (in height) and though the grid may now fit vertically on the display (you'll see all of its outline box fits on the display), you still have to scroll
              in the grid to see all the rows -- very odd.
            </li>
          </ul>
          <li>
            Next, click "Show Some Rows" to remove the "display: none" class from rows 10 to 39.
          </li>
          <ul>
            <li>
              In Chrome and Firefox, the grid rows reappear and the grid resizes back to the way it appeared before.
            </li>
            <li>
              In Safari (using v14.0.1), the rows do not reappear and the grid does not resize.
            </li>
            <ul>
              <li>
                UNLESS you resize the Safari window! Resizing the window after clicking "Show Some Rows" appears to force Safari to properly show the rows and resize the grid... Ugh!
              </li>
            </ul>
          </ul>
        </ul>

        <ul>
          <li>
            SIDE NOTE 1: In Safari, after you hide the rows, if you click "Hide Grid" (to add a class that sets display: none on the grid element) and then click "show Grid" to remove that class, I find that Safari now does <b>not</b> re-display the grid
            -- UNLESS you then resize the Safari window... THEN Safari will re-show the grid AND it will have the content properly sized... Ugh again!
          </li>
        </ul>
        <ul>
          <li>
            SIDE NOTE 2: In my project, I use this method to qucikly filter complex rows of information in a grid. I encompass each row with an element that has display set to "content" and add a class that sets display to "none" on each row that needs to be hidden
            by the filter. This keeps me from having to remove and recreate the content of the row and by wrapping each row in a "display:content" element, I can add the "display:none" class to just that element and don't have to add it to each item in
            that row of the grid. BUT, Safari isn't playing nice! I'm hoping this glitch can be fixed before long...
          </li>
        </ul>
      </div>
    </div>

  </div>
</body>

【问题讨论】:

  • 只是为了确认您的观察结果-它在 Edge Windows 10 上也适用于我。在 iPadIOS 14 上使用 Safari 时,它的行为与您描述的方式不同。它甚至可以在 iPad 上捏缩放窗口时恢复。
  • 感谢@A Haworth 提供更多信息
  • 旁注:我试图找到一种方法来强制 Safari 在应用过滤后“重新计算”网格和子大小(无论您调整窗口大小时它在做什么),但我没有运气不错。

标签: html css safari display


【解决方案1】:

如果我们给 main-div 一个明确的高度——比如 500px——那么 Safari(至少在 iPadIOS 14.2 上)会按预期运行——行可以从网格中删除并像 Chrome/Firefox/Edge 一样放回(在至少在 Windows 10 上)。

包含 div 的 .body 类已经有一个高度(100vh),但这似乎还不够。事实上,将 main-div 的高度设置为 100% 并不能解决问题,更奇怪的是,将其设置为 100vh 的高度也不能解决问题。

我无法解释这种行为,尽管它可能与 % height 之类的定义方式有关(或没有 - 例如,请参阅CSS Grid Row Height Safari Bug 上的讨论

我意识到,设置 px 高度不太可能是一种可接受的解决方法,但似乎值得将信息放在这里,以防它有助于找到解决问题的另一种方法。也可能与问题中的 sn-p 在非全屏模式下工作的事实有关 - 尽管在受限区域中的 iframe 中不应该有影响,但似乎确实有.

这是高度为 500px 的 sn-p:

function addRows() {
  var grid = document.getElementById("grid-div");
  if (grid.childNodes.length < 10) {
    for (var iRow = 0; iRow < 50; iRow++) {
      var row = document.createElement("div");
      row.classList.add("grid-row");
      row.id = `row-${iRow}`;
      grid.appendChild(row);
      for (var iCol = 0; iCol < 3; iCol++) {
        var label = document.createElement("label");
        label.innerHTML = `Cell ${iRow}:${iCol}`;
        row.appendChild(label);
      }
    }
  } else {
    alert("Looks like the grid was already filled");
  }
}

function hideSomeRows() {
  var grid = document.getElementById("grid-div");
  if (grid.childNodes.length > 10) {
    for (var iRow = 10; iRow < 40; iRow++) {
      var rowToHide = document.getElementById(`row-${iRow}`);
      rowToHide.classList.add("collapsed");
    }
  } else {
    alert("First you need to fill the grid")
  }
}

function showSomeRows() {
  var grid = document.getElementById("grid-div");
  if (grid.childNodes.length > 10) {
    for (var iRow = 10; iRow < 40; iRow++) {
      var rowToHide = document.getElementById(`row-${iRow}`);
      rowToHide.classList.remove("collapsed");
    }
  } else {
    alert("First you need to fill the grid")
  }
}

function hideGrid() {
  var grid = document.getElementById("grid-div");
  grid.classList.add("collapsed");
}

function showGrid() {
  var grid = document.getElementById("grid-div");
  grid.classList.remove("collapsed");
}
.body {
  overflow: auto;
  border: 2px blue dashed;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: stretch;
  padding: 0;
  margin: 0;
  height: 100vh;
  width: 100vw;
  box-sizing: border-box;
}

.main-div {
  display: flex;
  flex-direction: row;
  overflow: auto;
  height: 500px;
}

.column-div {
  display: flex;
  flex-direction: column;
  justify-items: flex-start;
  align-items: flex-start;
  overflow: auto;
}


/* Add some quick spacing */

.main-div div {
  margin-bottom: 0.4rem;
}

.main-div button {
  margin-right: 0.2rem;
}

.test-grid {
  display: grid;
  grid-template-columns: 5rem 5rem 5rem;
  row-gap: 0.3rem;
  column-gap: 0.2rem;
  justify-items: stretch;
  align-items: stretch;
  border: 1px solid black;
  /* just to see it */
  overflow: auto;
}

.test-grid .grid-row {
  display: contents;
}

.test-grid .grid-row label {
  border: 1px purple solid;
}

.collapsed {
  display: none !important;
}
<body>
  <div class="body">
    <div class="main-div">
      <div class="column-div" style="flex: none;">
        <div style="display: flex; flex: none;">
          <button onclick="addRows()">Fill Grid</button>
          <button onclick="hideGrid()">Hide Grid</button>
          <button onclick="showGrid()">Show Grid</button>
        </div>
        <div style="display: flex; flex: none;">
          <button onclick="hideSomeRows()">Hide Some Rows</button>
          <button onclick="showSomeRows()">Show Some Rows</button>
        </div>
        <div id="grid-div" class="test-grid">
          <div class="grid-row">
            <label>Column 1</label>
            <label>Column 2</label>
            <label>Column 3</label>
          </div>
        </div>
      </div>

      <div class="column-div" style="margin-left: 1rem;">
        <label>
          <b>Please use full page mode!</b><br>
             I believe this is a Safari glitch where changing an element inside a grid from 
             "display: content" to "display: none" and back is not handled properly.  Here's how to
             show this using the example to the left:
        </label>
        <ul>
          <li>
            First, click "Fill Grid" to add 50 rows (with display: content) to the grid.
            <ul>
              <li>
                If your display is short enough, the grid will go off the bottom of the display and overflow will allow you to scroll through the rows without scrolling the rest of the content.
              </li>
            </ul>
          </li>
          <li>
            Next, click "Hide Some Rows" to add a class that sets "display: none" on rows 10 to 39.
          </li>
          <ul>
            <li>
              In Chrome and Firefox, the grid resizes and the remaining rows fill the region. If your browser window is tall enough, the grid will now fit in the space available and will not need to scroll.
            </li>
            <li>
              In Safari (using v14.0.1), the grid appears to resize, but the remaining rows do not properly size (in height) and though the grid may now fit vertically on the display (you'll see all of its outline box fits on the display), you still have to scroll
              in the grid to see all the rows -- very odd.
            </li>
          </ul>
          <li>
            Next, click "Show Some Rows" to remove the "display: none" class from rows 10 to 39.
          </li>
          <ul>
            <li>
              In Chrome and Firefox, the grid rows reappear and the grid resizes back to the way it appeared before.
            </li>
            <li>
              In Safari (using v14.0.1), the rows do not reappear and the grid does not resize.
            </li>
            <ul>
              <li>
                UNLESS you resize the Safari window! Resizing the window after clicking "Show Some Rows" appears to force Safari to properly show the rows and resize the grid... Ugh!
              </li>
            </ul>
          </ul>
        </ul>

        <ul>
          <li>
            SIDE NOTE 1: In Safari, after you hide the rows, if you click "Hide Grid" (to add a class that sets display: none on the grid element) and then click "show Grid" to remove that class, I find that Safari now does <b>not</b> re-display the grid
            -- UNLESS you then resize the Safari window... THEN Safari will re-show the grid AND it will have the content properly sized... Ugh again!
          </li>
        </ul>
        <ul>
          <li>
            SIDE NOTE 2: In my project, I use this method to qucikly filter complex rows of information in a grid. I encompass each row with an element that has display set to "content" and add a class that sets display to "none" on each row that needs to be hidden
            by the filter. This keeps me from having to remove and recreate the content of the row and by wrapping each row in a "display:content" element, I can add the "display:none" class to just that element and don't have to add it to each item in
            that row of the grid. BUT, Safari isn't playing nice! I'm hoping this glitch can be fixed before long...
          </li>
        </ul>
      </div>
    </div>

  </div>
</body>

【讨论】:

  • 感谢您查看。如果需要的话,我也许可以通过强制大小来提出一种通用的解决方法。
猜你喜欢
  • 1970-01-01
  • 2015-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多