面试题:如何在浏览器可视区域画一个最大的正方形?

这是一个考察对 CSS 布局、视口单位和响应式设计理解的面试题。

目标是创建一个在任何屏幕尺寸下都尽可能大,且保持为正方形,并完全位于可视区域内的元素。

核心思路

要画一个“最大”的正方形,意味着它的尺寸应该由视口的较短边决定。因为正方形的宽高相等,所以最大边长只能是 min(视口宽度, 视口高度)

最佳解决方案:使用视口单位 (Viewport Units)

最优雅、最直接的方法是使用 vmin 单位。

  • vmin:等于视口宽度和高度中较小值的 1%
    • 例如,如果视口是 800px × 600px,那么 1vmin = 6px(因为 600 是较小值,600 / 100 = 6)。

实现代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>最大正方形</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box; /* 确保边框和内边距不增加总尺寸 */
        }

        .square {
            /* 关键:使用 vmin 单位 */
            width: 100vmin;
            height: 100vmin;

            /* 居中显示 */
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);

            /* 视觉效果:添加背景色和边框以便观察 */
            background-color: #3498db;
            border: 2px solid #2980b9;

            /* 可选:添加一些内容或阴影 */
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        }
    </style>
</head>
<body>
    <div class="square"></div>
</body>
</html>

为什么 100vmin 是完美的?

  • 在一个 800x600 的屏幕上,100vmin = 600px,正方形就是 600x600,高度刚好占满,宽度有剩余。
  • 在一个 600x800 的屏幕上,100vmin = 600px,正方形就是 600x600,宽度刚好占满,高度有剩余。
  • 在一个 1000x1000 的正方形屏幕上,100vmin = 1000px,正方形就是 1000x1000,完美填满。

vmin 会自动取视口的较短边,因此 100vmin 就是视口的较短边长度,正好是最大正方形的边长。


其他可行方案(作为备选或对比)

方案一:使用 vhvw 并取最小值(需 JavaScript)

如果浏览器不支持 vmin(非常老的浏览器),可以用 JavaScript 动态计算。

.square {
    width: 100px; /* 初始值,会被 JS 覆盖 */
    height: 100px;
    /* ... 其他样式(居中等)同上 */
}
function setMaxSquare() {
    const shorterSide = Math.min(window.innerWidth, window.innerHeight);
    const square = document.querySelector('.square');
    square.style.width = `${shorterSide}px`;
    square.style.height = `${shorterSide}px`;
}

// 初始化
setMaxSquare();

// 窗口大小改变时重新计算
window.addEventListener('resize', setMaxSquare);

缺点:需要 JavaScript,不如 CSS vmin 方案简洁高效。

方案二:使用 Flexbox + 百分比(不够精确)

body, html {
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 0;
}

.container {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}

.square {
    width: 100%;
    height: 100%;
    max-width: 100vh;
    max-height: 100vh;
    /* 问题:无法保证是正方形,除非父容器是正方形 */
}

缺点:这种方法很难保证最终是一个“最大”的正方形,逻辑复杂且不直观。


关键考察点(面试加分项)

  1. 理解 vmin 单位:这是本题的“题眼”。能准确说出 vmin 的定义并应用,是最佳答案。
  2. box-sizing: border-box:如果正方形有 borderpadding,必须使用 border-box,否则边框会增加元素总尺寸,可能导致溢出。
  3. 居中技巧:使用 position: absolute + transform: translate(-50%, -50%) 是居中的经典方法。也可以说 margin: auto 配合 position: absolutetop/left/right/bottom: 0
  4. 响应式vmin 是响应式的,窗口大小改变时,正方形会自动调整。
  5. 浏览器兼容性:可以提及 vmin 在现代浏览器中支持良好,对于极老的浏览器(如 IE9-)可以用 JS 方案降级。

总结回答示例

要在可视区域画一个最大的正方形,关键是让正方形的边长等于视口的较短边。

最优雅的方法是使用 CSS 的 vmin 单位。1vmin 等于视口宽高中较小值的 1%,所以将正方形的 widthheight 都设置为 100vmin,它就会自动适应为最大可能的正方形。

然后配合 position: absolutetransform: translate(-50%, -50%) 将其居中。

如果需要兼容不支持 vmin 的老浏览器,可以用 JavaScript 动态计算 Math.min(window.innerWidth, window.innerHeight) 并设置尺寸。

THE END
喜欢就支持一下吧
点赞5 分享