CSS:如何拥有一个 2x2 网格,其中图像在每个单元格内居中,并且在每个图像的右下角有一个 div

标签 css flexbox css-grid

基本上,我的模板有两个相互冲突的要求,但我找不到解决方案:

  • 它是一个 2x2 网格,包含 4 个图像,每个图像都以其自己的单元格为中心,
  • 当屏幕高度太小时,图像尺寸必须缩小,并且
  • 字母“O”div 必须位于图像的右下角
  • 我花费了大量时间创建下面的最小可重现示例,该示例有很好的文档记录。我认为阅读代码和查看图片时最好理解这个问题。我认为最简单的方法是在桌面上的文件夹中创建两个文件,然后在浏览器中打开 index.html 文件,同时使用我在下图中显示的检查器工具设置。但您也可以查看 Codepen here .

    .outermost-container {
      padding: 40px;
      height: calc(100vh - 80px);
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .container {
      display: grid;
      grid-template-columns: 1fr 1fr;
      grid-gap: 40px;
      width: 100%;
      height: 100%;
    }
    
    .image-centering-div {
      display: flex;
      justify-content: center;
      align-items: center;
      /* without this the images would not shrink in size when the screen height decreases */
      overflow: hidden;
      /* but the height: 100% & width: 100% are also crucial for this to be the case */
      width: 100%;
      height: 100%;
    }
    
    .relative-div {
      display: flex;
      justify-content: center;
      align-items: center;
      /* TODO: I have two requirements:
            1. the images should shrink in size when the screen height decreases
            2. the images should have the 'O'-div at the bottom right of their corner
        */
      /* THIS FULFILLS REQUIREMENT 1 */
      /*height: 100%;*/
      /*width: 100%;*/
      /* THIS FULFILLS REQUIREMENT 2 */
      position: relative;
      /* TODO FIXME:
            When having both snippets above commented in at same time,
            then ofc the 'O'-div is not at the bottom right of the image anymore,
            since the relative-wrapper is now full available width/height
            It is two conflicting requirements!
         */
    }
    
    .relative-div img {
      max-width: 100%;
      max-height: 100%;
      width: auto;
      height: auto;
    }
    
    .relative-div div {
      position: absolute;
      right: 0;
      bottom: 0;
    }
    <body style="margin: 0">
      <div class="outermost-container">
        <div class="container">
          <div class="image-centering-div">
            <div class="relative-div">
              <img src="https://wallpapercave.com/dwp2x/wp4471355.jpg" alt="">
              <div class="O-div">O</div>
            </div>
          </div>
          <div class="image-centering-div">
            <div class="relative-div">
              <img src="https://plus.unsplash.com/premium_photo-1699534956827-a02df22f4e3a?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="">
              <div class="O-div">O</div>
            </div>
          </div>
          <div class="image-centering-div">
            <div class="relative-div">
              <img src="https://images.unsplash.com/photo-1510505678115-f2a7ae4cfea9?q=80&w=1681&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="">
              <div class="O-div">O</div>
            </div>
          </div>
          <div class="image-centering-div">
            <div class="relative-div">
              <img src="https://plus.unsplash.com/premium_photo-1661852207925-4f1d03556a2e?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="">
              <div class="O-div">O</div>
            </div>
          </div>
        </div>
      </div>
    </body>

    我在浏览器中查看了具有这些设置的代码:

    good result when screen is high enough

    -> 正如你所看到的,这是我想要的结果。当屏幕足够高时它就可以工作。

    现在,当您降低高度时,会发生以下情况:

    bad result 1

    -> 正如你所看到的,保持图像完全可见的要求 1 并没有得到满足(实际上也没有满足要求 2,即使 o-div 位于图像的右下角,对于某些人来说它也是不可见的)因为对于某些图像,机器人右上角不再可见)

    这就是我在“REQUIREMENT 1 100% width/height styles”中评论时发生的情况:

    enter image description here

    -> 满足要求 1 保持图像不被裁剪。但不满足要求2将o-div保持在右下角

    最佳答案

    一种可能的方法如下,尽管我冒昧地调整了 HTML,试图使其更加语义化。解释性注释位于代码中,如下:

    /* removing generic browser defaults for cross-browser
       similarity: */
    *,::before,::after {
      /* causes the browser to use the same sizing algorithm for
         all elements, which includes the border-width and padding
         in the assigned sizes: */
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    body {
      min-height: 100vh;
      padding-block: 1rem;
    }
    
    .gallery {
      background: linear-gradient(to bottom right, silver, black);
      display: grid;
      gap: 2rem;
      grid-template-areas:
        "one two"
        "three four";
      /* if the element is smaller than the inline-size of its
         parent, then we center on that inline axis: */
      margin-inline: auto;
      max-inline-size: 80vmin;
      padding: 1rem;
    }
    
    li {
      display: grid;
      
      /* the ampersand is required for Chromium-based browsers, who require that
         the first character of a nested selector (as I'm using here) is a symbol,
         in order to easily distinguish between a CSS property and a nested
         selector (Firefox allows use of the "relaxed" selector syntax): */
      
      & figure {
        display: grid;
        max-inline-size: 100%;
        /* centering the content both horizontally and vertically
           within the <figure> element, and causes the child(ren)
           to occupy the smallest possible size within the constraints
           of the applied CSS: */
        place-content: center;
      }
      
      & figure > * {
        /* all items are in the same grid-area within the parent,
           I suspect there's a shorter way to achieve this but I
           couldn't (quickly) find a way: */
        grid-area: 1 / 1 / 1 / 1;
      }
      
      & img {
        max-inline-size: 100%;
      }
      
      & figcaption {
        /* purely aesthetic and for visibility, adjust to taste */
        background-color: #fffa;
        mix-blend-mode: hard-light;
        /* places the figcaption at the end of both the
           inline and block axes: */
        place-self: end;
      }
    }
    <!-- the content seems to be a list of images, hence the use of <ol>; I'm assuming it's meant to
         be in a particular order, so I used the <ol> element; if it's not required to be in
         that order then a <ul> is also an option: -->
    <ol class="gallery">
      <!-- for reasons of HTML validity the content is wrapped in <li> elements: -->
      <li>
        <!-- using a figure element to contain the images, with related text wrapped in a
             <figcaption> element: -->
        <figure>
          <img src="//wallpapercave.com/dwp2x/wp4471355.jpg" alt="">
          <figcaption>text</figcaption>
        </figure>
      </li>
      <li>
        <figure>
          <img src="//plus.unsplash.com/premium_photo-1699534956827-a02df22f4e3a?q=80&amp;w=3540&amp;auto=format&amp;fit=crop&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="">
          <figcaption>text</figcaption>
        </figure>
      </li>
      <li>
        <figure>
          <img src="//images.unsplash.com/photo-1510505678115-f2a7ae4cfea9?q=80&amp;w=1681&amp;auto=format&amp;fit=crop&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="">
          <figcaption>text</figcaption>
        </figure>
      </li>
      <li>
        <figure>
          <img src="//plus.unsplash.com/premium_photo-1661852207925-4f1d03556a2e?q=80&amp;w=3540&amp;auto=format&amp;fit=crop&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="">
          <figcaption>text</figcaption>
        </figure>
      </li>
    </ol>

    JS Fiddle demo .

    引用文献:

    关于CSS:如何拥有一个 2x2 网格,其中图像在每个单元格内居中,并且在每个图像的右下角有一个 div,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77541685/

    相关文章:

    javascript - 未捕获的类型错误 : Cannot read property 'top' of undefined in an attempt to autoscroll to gallery

    javascript - 有什么方法可以使用css在子类的基础上设置父背景颜色?

    html - 使视频在文本 block 旁边的英雄中保持纵横比

    html - 使用CSS网格将div定位在div内

    html - 具有列和增长行的动态高度的 CSS Grid 不能完全工作

    css - 克服设计 UI 元素的跨浏览器问题

    javascript - SVG 选择颜色贴图

    css - 使用网格进行布局,第一张图片左侧有不需要的填充

    jquery - 仅在 .active 类不是第一个子类时显示按钮

    html - CSS 问题页眉和页脚不保持高度