2

Problem:

I came across some curious Google Chrome default behaviour while building a simple SPA layout with HTML and CSS-Grid.

When it came to animating the individual rows of the grid that I was either dynamically generating content (& items) for or changing existing elements height on :hover over another element within the same grid, the height of the containing row would grow:

  • upwards - if element:hover was on the lower half of the screen (the dynamic content sticks out of the viewport with its top);
  • downwards - if element:hover was on the higher half of the screen (the dynamic content being either entirely visible or sticking out of the viewport downwards);.

!important The above works only if an element which is hovered over is taken out of its original place in document and put below dynamic element by grid-area property. In any other case grid-row always expands downwards.

Update, edited 02.05.2017

As Michael_B pointed out in comments section the curious browser behavior is due to Google Chrome feature called scroll anchoring.

Michael_B: In Chrome, the upward / downward direction of expanding boxes is governed by the scroll position in the viewport, not the layout itself. Basically, they bind a DOM element to the current scroll position. The movement of this particular ("anchor") element on the screen will determine an adjustment, if any, to the scroll position.

You can read all about it here!

Redefined problem:

Since there is no way to modify the scroll anchoring other than shutting it down using overflow-anchor: none, it does not help to enforce desired behavior described in detail in "Expected result" section.

Expected result:

I'd like to force any elements contained within a grid-row to animate vertically upwards no matter the screen position of an element hovered over. In other words, I want grid-row being animated in height to grow from bottom of itself to the top of the page, instead of top to bottom, in all cases, but subject to structure and document flow retaintment.

Research done:

I've done some digging, and it seems, that there are plenty of solutions for rather similar problems but concerning block displayed elements, and none for the CSS-Grid.

Solutions e. g.,

Here are some from stackoverflow:

And also from outside:

Research summary:

All of the above and many others solutions available on-line revolve mostly around setting a CSS rule of position:relative to the parent container for the block element to be animated, and than declaring a position:absolute and bottom:0 on the block element being animated.

And in that case, since the block element is now being positioned absolutely from the bottom of its container it is forced to animate in desired direction, for it has nowhere to expand other than vertically increase upwards.

Why doesn't it work for CSS Grid?

In case of standard document flow position:absolute element is positioned relative to its first positioned (not static, e. g., position:relative) ancestor, taking it out of the normal document flow. It's also the case for the Grid, what is specific though is that the normal element within the grid stretches by default both horizontally and vertically to fit the whole declared grid area. Contrarily, the positioned element shrinks to fit and adapts its size to the contents or even worse occupy no vertical space at all. Than you could set grid-auto-rows: minmax() property to try to cover for that. But again, than it goes to its default behavior. It also does not solve the problem, because having other elements within the grid, will become overflown by the positioned one.

You could off course try to put a block element within the grid-row, and position: it absolute to the position:ed relatively grid-row and set bottom:0 for the block element, which seems to work well at first. But than you'll notice, that the block element will grow over the previous document elements. It would actually demonstrate the same behavior, if whole layout structure was built on block elements, which is why I didn't like the idea in a first place. It's also the reason why I stated the obvious in the first sentence of this section.

Suggested solution

I believe, that I've realized how to solve that problem conceptually, but I don't have required technical skills to do so. What seems to me as the right approach is to try and override the initial browser behavior when the element:hover is on the upper side of the screen, and make it act, as it would be on the other half, since the desired outcome is already built-in in the browser but triggered under undesired circumstances.I'm off course open-minded to other propositions.

Update, edited 02.05.2017

Solution invalid due to technical limits.

#container {
  display: grid;
  grid-auto-rows: minmax(300px, auto) 100vh;
  align-content: center;
  color: white;
  font-size: 24px;
}

#fisrtelement {
  display: grid;
  background-color: orange;
}

#secondelement {
  background-color: greenyellow;
}

.expandable {
  height: 100px;
  background-color: forestgreen;
}

.content:hover~.expandable {
  height: 150px;
}

.content {
  min-height: 120px;
}

#item1 {
  grid-area: 1/1;
  background-color: forestgreen;
}

#item2 {
  grid-area: 2/2;
}

#item3 {
  grid-area: 3/3;
  background-color: forestgreen;
}
<div id="container">

  <div id="fisrtelement">
    <div id="item1" class="content">Content</div>
    <div id="item3" class="content">Content</div>
    <div id="item2" class="expandable">Expandable area (on content:hover)</div>

  </div>
  <div id="secondelement">

  </div>
</div>
  • Are you talking about this? https://stackoverflow.com/q/44826446/3597276 – Michael Benjamin May 01 '18 at 13:10
  • The scroll anchoring does seem to explain curios Google Chrome behavior when expanding row height. It also demonstrates that it is not ( at least yet) a cross browser solution. But since there is no way to modify the scroll anchoring other than shutting it down using `overflow-anchor: none`, it does not help to enforce desired behavior. – Dominik Kowalczyk May 01 '18 at 14:07
  • Have you considered altering the natural flow of the document? https://stackoverflow.com/q/40112027/3597276 (See especially the answer by @DaniP.) – Michael Benjamin May 01 '18 at 14:19
  • I did consider altering the normal flow of the web page with floats. The thing is, that it helps only in directing expansion horizontally. – Dominik Kowalczyk May 02 '18 at 11:43

0 Answers0