【问题标题】:Drawing a grid using CSS使用 CSS 绘制网格
【发布时间】:2011-05-10 15:03:54
【问题描述】:

我正在寻找一种在 div 内绘制网格(即http://www.artlex.com/ArtLex/g/images/grid.gif)的方法,使用 CSS(必要时使用 JS)。感觉它应该相对简单,但我一直无法弄清楚。任何建议将不胜感激。

提前谢谢你, 莱尼

【问题讨论】:

标签: javascript css layout grid drawing


【解决方案1】:

这是一个简单的纯 CSS 解决方案,使用线性渐变:

html, 
body,
.grid {
    height: 100%;
    width: 100%;
    margin: 0;
}
.grid {
    background-image:
      repeating-linear-gradient(#ccc 0 1px, transparent 1px 100%),
      repeating-linear-gradient(90deg, #ccc 0 1px, transparent 1px 100%);
    background-size: 71px 71px;
}
<div class="grid"></div>

【讨论】:

  • 很棒的纯 CSS 答案,可以避免任何 .js 或 dom 噪音。
  • 我采用了这个绝妙的 hack 并用它制作了一个 Sass 包:Artboard。打包的主要原因是暴露一个 Sass 变量来方便地改变网格的大小。
  • 这很有帮助!!谢谢你
  • 如果我想在网格中放数字怎么办,这个例子怎么做?
【解决方案2】:

这是一个使用 jQuery 的简单解决方案。该脚本将尝试在不溢出的情况下填充尽可能多的网格元素。该函数接受一个参数,该参数定义了网格的大小。

function createGrid(size) {
    var ratioW = Math.floor($(window).width()/size),
        ratioH = Math.floor($(window).height()/size);

    var parent = $('<div />', {
        class: 'grid',
        width: ratioW  * size,
        height: ratioH  * size
    }).addClass('grid').appendTo('body');

    for (var i = 0; i < ratioH; i++) {
        for(var p = 0; p < ratioW; p++){
            $('<div />', {
                width: size - 1,
                height: size - 1
            }).appendTo(parent);
        }
    }
}

它还需要一个简单的 CSS 样式:

.grid {
    border: 1px solid #ccc;
    border-width: 1px 0 0 1px;
}

.grid div {
    border: 1px solid #ccc;
    border-width: 0 1px 1px 0;
    float: left;
}

在这里查看一个简单的演示:http://jsfiddle.net/yijiang/nsYyc/1/


这是一个使用原生 DOM 函数的例子。我还应该更改初始比率计算以使用 DOM 函数,但我无法终生让 window.innerWidth 返回准确的数字 修复:

function createGrid(size) {
    var ratioW = Math.floor((window.innerWidth || document.documentElement.offsetWidth) / size),
        ratioH = Math.floor((window.innerHeight || document.documentElement.offsetHeight) / size);

    var parent = document.createElement('div');
    parent.className = 'grid';
    parent.style.width = (ratioW * size) + 'px';
    parent.style.height = (ratioH * size) + 'px';

    for (var i = 0; i < ratioH; i++) {
        for (var p = 0; p < ratioW; p++) {
            var cell = document.createElement('div');
            cell.style.height = (size - 1) + 'px';
            cell.style.width = (size - 1) + 'px';
            parent.appendChild(cell);
        }
    }

    document.body.appendChild(parent);
}

createGrid(10);

它基本上是 jQuery 代码的直接翻译。如果您需要更高的性能,您可以切换到使用推送到数组的字符串来生成框:

arr.push('<div style="width:', (size - 1), 'px;height:', (size - 1), 'px;"></div>');

然后在最后

parent.innerHTML = arr.join('');

【讨论】:

  • 顺便说一句,有什么建议可以提高效率吗?这段代码中的任何内容我都可以缓存或用本机 JS 替换 jquery 以使其运行得更快?
  • @lennysan 绝对!事实上,整个事情都可以用原生 JS 重写。此外,您可能不想在循环中附加元素,而是将其附加到其他内容,然后在循环之外将整个内容附加到正文。如果你愿意,我可以把它改写成更高效的东西。
  • 如果您有任何空闲周期,我很想获得高性能版本。我的 JS 技能还不成熟,可能需要几个小时才能搞定。
  • @YiJang:你是真正的英雄。
  • 非常好!玩弄添加排水沟。有什么建议吗?也在考虑在排水沟里贴标签,但一步一步。示例:jsfiddle.net/Twisty/18erqbqv
【解决方案3】:

我知道这个问题已经得到解答,但我已经为我正在从事的项目就这个确切的问题做了大量工作,所以我想我会分享我的发现。渲染速度对我来说是一个大问题,和@YiJiang 一样,我从循环内部添加节点开始,但我发现这不是一个非常高效的解决方案,所以我研究了优化算法的方法。

从算法上讲,嵌套循环会导致 O(n^2) 复杂度,在这种情况下,可以通过生成一次行 html 来避免这种情况(因为每一行都是相同的),然后将此字符串连接到每一行中。这会导致 O(n) 复杂度,并且是迄今为止我找到的最有效的解决方案。

function drawGrid(width, height) {
    var grid = '<div id="grid">',
        cell_html = '',
        i = 0, j = 0;

    for( ; i < width; i++) {
        cell_html += '<div class="cell"></div>';
    }

    for( ; j < height; j++) {
        grid += '<div class="row">' + cell_html + '</div>';
    }

    grid += '</div>';

    return grid;
}

这将为网格创建基本的 HTML 结构,然后可以使用 CSS 对其进行适当的样式设置。

【讨论】:

    【解决方案4】:

    这是一个解决方案,它是@YiJiang 答案的编辑版本,可将其降低到 O(n) 复杂度。我添加解决方案的唯一原因是它包含 css 和 jsfiddle 示例 (http://jsfiddle.net/madstop/bM5Kr/)

    css:

    .gridlines { display: none; position:absolute; background-color:#ccc; }
    

    javascript/jquery:

    function createGrid(size) {
    var i, 
        height = $(window).height(),
        width = $(window).width(),
        ratioW = Math.floor(width/size),    
        ratioH = Math.floor(height/size); 
    
    for (i=0; i<= ratioW; i++)  // vertical grid lines
        $('<div />').css({
                'top': 1, 
                'left': i * size, 
                'width': 1, 
                'height': height })
            .addClass('gridlines')
            .appendTo('body');
    
        for (i=0; i<= ratioH; i++) // horizontal grid lines
            $('<div />').css({
                'top': 1 + i * size, 
                'left': 0, 
                'width': width, 
                'height': 1 })
            .addClass('gridlines')
            .appendTo('body');
    
        $('.gridlines').show();
    }
    
    createGrid(50);
    

    【讨论】:

      【解决方案5】:

      “纯 CSS”和 100px2 网格。

      (投票最多的answer, above的变体。)

      body { box-sizing:border-box; margin:0; height:100%; width:100%; background-size:100px 100px;
             background-image: repeating-linear-gradient(0deg, transparent, transparent 99px, #ccc 99px, #ccc 100px), 
             repeating-linear-gradient(-90deg, transparent, transparent 99px, #ccc 99px, #ccc 100px); 
           }

      【讨论】:

        【解决方案6】:

        body { 
          box-sizing:border-box; 
          margin:0; 
          height:100%; 
          width:100%; 
          background-size:100px 100px;       
          background-image: repeating-linear-gradient(0deg, 
          transparent, transparent 99px, #ccc 99px, #ccc 100px), 
          repeating-linear-gradient(-90deg, transparent, 
          transparent 99px, #ccc 99px, #ccc 100px); 
        }

        这就是你想要的

        【讨论】:

          【解决方案7】:

          这就是我的做法:

          1) 制作 L 的图像,其中 L 的每一边都等于网格中的一个正方形。

          2) 将此设置为 div 的背景图像,在 x 和 y 轴上重复

          3) 给你的 div 在顶部和右侧设置一个 1px 的黑色边框

          4) 你达到了想要的效果!

          希望对你有帮助

          看到您的无图片评论后编辑:

          为什么不直接使用表格来制作网格(因为如果没有图像,您将无法做您想做的事情)并用绝对定位的内容 div 覆盖表格?

          【讨论】:

          • 这听起来像是合理的解决方案,但是使用图像会很难轻松缩放此网格(在这种情况下,我忘记提及的事情很重要)。希望还有其他方法出现,否则你赢了:)
          • 这个网站太快了。
          • 查看编辑 :) 你也可以使用 JS 来确保你的 div 覆盖与你的表格保持相同的大小
          【解决方案8】:

          三年后...@user3061127,我爱你!

          其他答案很好,但仅使用一些非常简单的 HTML 和 CSS 就可以产生我想要的结果。一个美妙的,美丽的网格。我会发布一条带有小提琴链接的简单评论,但我还不够酷,因此我的答案是。

          这是我根据你的原作得出的,它呈现了你在专业方格纸上看到的两层网格(是的,这一切都是因为我太固执了,不能出去买一些!)

          如果您有不同尺寸的纸张,您只需更改#main 的高度和宽度即可。如果你想要一个不同大小的网格,你所要做的就是改变背景尺寸属性和背景图像中的尺寸。请注意,重复的背景图像很挑剔。尺寸必须与背景尺寸相匹配,否则您将根本看不到重复的线条。

          <!DOCTYPE html>
          <html>
              <head>
                  <style>
                      html, body {
                          margin: 0;
                      }
                      #main {
                          height: 11in; /* Double this and print at 50% */
                          position: relative;
                          width: 8.5in; /* Double this and print at 50% */
                      }
                      .grid {
                          background-image: repeating-linear-gradient(0deg,transparent,transparent 69px,#88F 69px,#88F 70px),
                                          repeating-linear-gradient(-90deg,transparent,transparent 69px,#88F 69px,#88F 70px);
                          background-size: 70px 70px;
                          height: 100%;
                          position: absolute;
                          width: 100%;
                      }
                      .smallgrid {
                          background-image: repeating-linear-gradient(0deg,transparent,transparent 13px,#CCF 13px,#CCF 14px),
                                          repeating-linear-gradient(-90deg,transparent,transparent 13px,#CCF 13px,#CCF 14px);
                          background-size: 14px 14px;
                          height: 100%;
                          position: absolute;
                          width: 100%;
                      }
                  </style>
              </head>
              <body>
                  <div id="main">
                      <div class="smallgrid"></div>
                      <div class="grid"></div>
                  </div>
              </body>
          </html>
          

          小提琴: http://jsfiddle.net/ykotfuaw/5/

          【讨论】:

          • 请注意,只有当您启用打印背景颜色和图像的选项时,才能正确打印。目前,Edge 没有这样的选项。奇怪的是,Chrome 打印了大部分,但不是所有的行,所以它也不值得。幸运的是,Firefox 做得对。想要更细的线条?您不能创建小于 1 像素的线条,但您可以“作弊”并将 #main 尺寸加倍,然后在打印时使用缩小以适应或 50% 选项。
          猜你喜欢
          • 2016-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-12-31
          • 2021-07-11
          • 2016-02-06
          • 2011-08-05
          相关资源
          最近更新 更多