◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。
传统的web网页表格制作方法一般都是选用table、tr、td标签制作,现在基本上正在逐渐淡出,因为table的布局难以实现现在复杂响应式网站的设计,在前面我讲过可以用ul加li标签制作表格,但是多数情况下受到网站建站系统的制约,它们会在发布文章时被清除,所以今天我再介绍一种,div加CSS实现表格的制作方法。
1.固定宽高的1横3列表格制作方法
表格的制作,需要理解,怎样制作横和列?横可以用div容器来实现,列呢?也是一样,同样用div容器实现,只是在制作列时,用的是小div,就是子级div,制作横的div我们就称之为父级div,比如下面这样的一对父级div加上三对子级div。
<div> <div></div> <div></div> <div></div> </div>
就可以实现一个简单的1横3列的表格,每个格子的宽为100像素,高为30像素。像下面这种效果:
其实这里面除了div标签,当然还有css定义。
首先对父级div容器的定义是display: table-row,意思就是把div元素显示为表格行。
子级div的定义是display: table-cell,意思是显示为表格单元格,即会表现得像表格中的一个单元格。
当前例子是一个固定宽高像素的表格,所以给予height: 30px; width: 100px这样的高为30像素,宽为100像素的css定义,同时边框定义为border: 1px solid #000,就是边框为1像素的黑色实线。
如果要实现文字居中,还可以给它一个30像素行高line-height: 30px(高为多少像素就把行高设为多少像素)和文字垂直居中text-align: center,效果如下:
完整代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>div+css表格制作</title> <style type="text/css"> <!-- .heng { display: table-row; } .shu { height: 30px; width: 100px; display: table-cell; border: 1px solid #000; line-height: 30px; text-align: center; } --> </style> </head> <body> <div class="heng"> <div class="shu">文字1</div> <div class="shu">文字2</div> <div class="shu">文字3</div> </div> </body> </html>
在以上的代码中,我给父级div定义为一个heng的类,再给子级div定义为shu的类,这样只需要给这两个类一个单独的CSS定义就可以实现表格的效果,但是在建站程序系统中,可能不允许这样的css定义出现在文章中,但多数是支持把定义写在div容器中的,只是每个div都需要css定义,代码会更冗长。代码如下:
<div style="display: table-row;"> <div style="height: 30px; width: 100px; display: table-cell; border: 1px solid #000;line-height: 30px;text-align: center;">文字1</div> <div style="height: 30px; width: 100px; display: table-cell; border: 1px solid #000;line-height: 30px;text-align: center;">文字2</div> <div style="height: 30px; width: 100px; display: table-cell; border: 1px solid #000;line-height: 30px;text-align: center;">文字3</div> </div>
2.固定宽高的3横3列表格制作方法
上面介绍了用div加css制作了一个1横3列表格的例子,那么如果需要制作多行多列又怎样实现了。因为在制作原理中就已经讲到,父级div是制作表格的横,子级div制作表格的列,也就是说需要多少横,就有多少组父级div,每个父级div中的子级div有多少组就代表有多少列,如果以制作一个3横3列的表格为例子,只需要将上面的代码复制3组即可实现,效果如下:
完整代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>div+css表格制作</title> <style type="text/css"> <!-- .heng { display: table-row; } .shu { height: 30px; width: 100px; display: table-cell; border: 1px solid #000; } --> </style> </head> <body> <div class="heng"> <div class="shu"></div> <div class="shu"></div> <div class="shu"></div> </div> <div class="heng"> <div class="shu"></div> <div class="shu"></div> <div class="shu"></div> </div> <div class="heng"> <div class="shu"></div> <div class="shu"></div> <div class="shu"></div> </div> </body> </html>
3.添加类解决每个div边框重叠的问题
细心的你也许会发现,在上面的例子中,不管是1横3列的表格还是3横3列的表格,它们的边框线条都是中间粗,四周细,这是什么原因呢?这是因为我们给予每个子级div四边的边框线条都是1像素,当它们相互靠在一起时,就会变成2像素,所以会出现这样的状况很正常。
要解决这个问题,无非就两种,一是把四周的边框线条都定义为2像素,二是把相邻的div边框只设置1个有线条,另外一个没有线条,在这里我选择了第二种做法。
首先把所有的子级div的左边的边框和下边的边框去掉,得到一个如下图形。
从上面的图形可以看得出来,现在变成了每一根线条都是一样了粗细,全部是1像素,唯一不足的就是整个表格的左边和下边没有线条。接下来我们为每一个单元格标上序号,得到如下图形:
通过以上图形,知道1、4、7单元格没有左边线,7、8、9没有下边线,那么就把1、4、7单元格再添加left的类,7、8、9单元格再添加一个down的类。
如果是个位数以内的单元格,倒是可以手动添加,若是遇上几十成百上千的单元格,岂不是弄到牛年马月,因此我提供了一个快速替换单元格类的方法,使用正则表达式和反斜杠的转义,快速替换成自己想要的类或其他文字。
首先请出我们的主角Notepad2,没有可以通过下面链接下载。如果不熟悉它,可以通过我的另外一篇文章《txt文本文件回车的替换,记事本回车替换》了解。
下载Notepad2 :点击下载
备用下载 :点击下载
把下面的代码复制到Notepad2中:
<div class="heng"> <div class="shu">1</div> <div class="shu">2</div> <div class="shu">3</div> </div> <div class="heng"> <div class="shu">4</div> <div class="shu">5</div> <div class="shu">6</div> </div> <div class="heng"> <div class="shu">7</div> <div class="shu">8</div> <div class="shu">9</div> </div>
左边一列的1、4、7单元格就是:
<div class="heng"> <div class="shu">1</div>
我们只取:
<div class="heng"> <div class="shu">
进行替换即可
方法是Ctrl+H,打开Notepad2的替换功能,勾选上下面的“对反斜杠"\"进行转义(T)”,在“查找”中输入:
<div class="heng">\r\n <div class="shu">
在“替换”中输入:
<div class="heng">\r\n <div class="shu left">
点击右边“全部替换”,如下图所示:
如果出现“未找到的文本”,请复制子级div前面的空格覆盖掉“查找”框中\r\n后面的空格。替换成功后就会得到如下代码:
<div class="heng"> <div class="shu left">1</div> <div class="shu">2</div> <div class="shu">3</div> </div> <div class="heng"> <div class="shu left">4</div> <div class="shu">5</div> <div class="shu">6</div> </div> <div class="heng"> <div class="shu left">7</div> <div class="shu">8</div> <div class="shu">9</div> </div>
接下来我们将替换最下面一栏7、8、9的全部单元格,也就是最后一组父级div的全部单元格,这里只需要选择这组div,然后Ctrl+H,打开Notepad2的替换功能,什么都不用勾选,在“查找”中输入:
<div class="shu
替换中输入:
<div class="shu down
最后单击右边的“选区替换”,如图:
就会得到如下代码:
<div class="heng"> <div class="shu left">1</div> <div class="shu">2</div> <div class="shu">3</div> </div> <div class="heng"> <div class="shu left">4</div> <div class="shu">5</div> <div class="shu">6</div> </div> <div class="heng"> <div class="shu down left">7</div> <div class="shu down">8</div> <div class="shu down">9</div> </div>
现在给予left这个类添加一个1像素的黑色实线左边线css定义:border-left-width: 1px; border-left-style: solid; border-left-color: #000;
同样也给down这个类添加一个1像素的黑色实线下边线css定义:border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #000;
得到非常完美单元格,每个单元格的边框线全部就变成了1像素,效果如下:
设置边框线全部为1像素的完整代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>div+css表格制作</title> <style type="text/css"> <!-- .heng { display: table-row; } .shu { height: 30px; width: 100px; display: table-cell; border-top-width: 1px; border-right-width: 1px; border-top-style: solid; border-right-style: solid; border-top-color: #000; border-right-color: #000; border-top-color: #000; } .left { border-left-width: 1px; border-left-style: solid; border-left-color: #000; } .down { border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #000; } --> </style> </head> <body> <div class="heng"> <div class="shu left">1</div> <div class="shu">2</div> <div class="shu">3</div> </div> <div class="heng"> <div class="shu left">4</div> <div class="shu">5</div> <div class="shu">6</div> </div> <div class="heng"> <div class="shu down left">7</div> <div class="shu down">8</div> <div class="shu down">9</div> </div> </body> </html>
4.使用CSS相邻兄弟选择器(+)解决单元格边框重叠问题
虽然上面我介绍的方法能够解决问题,但是在添加不同的类这个过程中非常麻烦,你需要知道整个表的左边一列单元格是哪些、下边一排的单元格又是哪些,稍不注意就会出错,特别是当单元格成百上千时,更容易出错,有没有好的方法解决这个问题?答案当然是有的,我们可以使用CSS相邻兄弟选择器(+)来定义特定位置的单元格样式。这样你不需要为每个单元格手动添加额外的类,从而简化了HTML结构并且提高了可维护性。
要使用CSS相邻兄弟选择器,首先你得明白CSS相邻兄弟选择器是怎么回事。以下面的代码为例子:
<p>A</p> <p>B</p> <p>C</p>
如果想把相邻的p标签之间的文字设置成红色,可以使用以下css定义:
p + p { color: #F00; }
实现了下面这样的效果:
A
B
C
从上面的例子可以看出来,A的前面没有相邻的p标签,所以它的颜色没有变化,B和C的前面都有P标签,自然就被定义成了红色。因此可以看出来,CSS相邻兄弟选择器可以实现第一组标签的选择性定义和非第一组标签的选择性定义。就比如下面这样的需要定义成表格的代码:
<div class="heng"> <div class="shu">1</div> <div class="shu">2</div> <div class="shu">3</div> </div> <div class="heng"> <div class="shu">4</div> <div class="shu">5</div> <div class="shu">6</div> </div> <div class="heng"> <div class="shu">7</div> <div class="shu">8</div> <div class="shu">9</div> </div>
我们既可以让相邻单元格的左边不显示边框和相邻每排的单元格不显示上边框来解决单元格边框重叠问题,因为单元格的div的类是shu,因此相邻单元格可以写成.shu + .shu,同时因为排的类为heng,则相邻排的单元格可以写成.heng +heng .shu,为什么不写成.heng +heng 或者.heng .shu +heng .shu?不使用.heng +heng 是因为父级div并没有定义任何边框,但如果使用.heng .shu +heng .shu,实际HTML结构中,.shu 元素不会直接紧跟在另一个 .heng 元素之后,因为它们是在不同的父级 .heng 元素内,所以是匹配不到任何元素的。只有使用.heng +heng .shu,才会定义到每排之间相邻的单元格。完整代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>div+css表格制作</title> <style type="text/css"> .heng { display: table-row; } /* 设置单元格四条边都有边框 */ .shu { height: 30px; width: 100px; display: table-cell; border: 1px solid #000; } /* 设置相邻单元格的左边框不显示 */ .shu + .shu { border-left-style: none; } /* 设置相邻每排单元格不显示上边框 */ .heng + .heng .shu { border-top-style: none; } </style> </head> <body> <div class="heng"> <div class="shu">1</div> <div class="shu">2</div> <div class="shu">3</div> </div> <div class="heng"> <div class="shu">4</div> <div class="shu">5</div> <div class="shu">6</div> </div> <div class="heng"> <div class="shu">7</div> <div class="shu">8</div> <div class="shu">9</div> </div> </body> </html>
5.使用伪类解决单元格边框重叠问题
如果我们把每个div子元素的类shu定义为不显示左边线和下边线,则会得到如下表格:
此时可以使用伪类:first-child和:last-child选择不同位置的单元格加上不同的两个css定义去添加上对应的边线,那么:first-child和:last-child是什么意思?
:first-child:代表第一个子元素
:last-child:代表最后一个子元素
要选择所有排中的第一个单元格,可以写成.heng .shu:first-child,但如果要选择最后一排的所有单元格,就应该写成.heng:last-child .shu,如果写成.heng .shu:last-child就代表选择所有排的最后一个单元格。
现在要完成为所有排中的第一个单元格添加左边线,只需要给.heng .shu:first-child的左边定义1像素黑色实线,此时整个表格只差下边线,我们再次为.heng:last-child .shu下边定义一个1像素黑色实线即可完成整个表格的边框,完整代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>div+css表格制作</title> <style type="text/css"> <!-- .heng { display: table-row; } /*首先设置每个单元格的左边和下边没有边线*/ .shu { height: 30px; width: 100px; display: table-cell; border-top-width: 1px; border-right-width: 1px; border-top-style: solid; border-right-style: solid; border-top-color: #000; border-right-color: #000; } /*给每一排的第一个单元格添加左边线*/ .heng .shu:first-child { border-left-width: 1px; border-left-style: solid; border-left-color: #000; } /*给最后一排的每个单元格添加下边线*/ .heng:last-child .shu { border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #000; } --> </style> </head> <body> <div class="heng"> <div class="shu"></div> <div class="shu"></div> <div class="shu"></div> </div> <div class="heng"> <div class="shu"></div> <div class="shu"></div> <div class="shu"></div> </div> <div class="heng"> <div class="shu"></div> <div class="shu"></div> <div class="shu"></div> </div> </body> </html>
6.使用js解决单元格边框重叠问题
除了上面的方法解决单元格边框重叠问题外,还有js也是一个不错的选择。实现的代码如下:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title>div+css表格制作</title> <style type="text/css"> .heng { display: table-row; } .shu { height: 30px; width: 100px; display: table-cell; border-top: 1px solid #000; border-right: 1px solid #000; /* 初始设置左边和下边没有边线 */ border-left: none; border-bottom: none; } </style> </head> <body> <div class="heng"> <div class="shu">1</div> <div class="shu">2</div> <div class="shu">3</div> </div> <div class="heng"> <div class="shu">4</div> <div class="shu">5</div> <div class="shu">6</div> </div> <div class="heng"> <div class="shu">7</div> <div class="shu">8</div> <div class="shu">9</div> </div> <script> // 等待DOM完全加载后再执行脚本 document.addEventListener('DOMContentLoaded', function() { // 获取所有的行(.heng) const rows = document.querySelectorAll('.heng'); // 遍历每一行 rows.forEach((row, rowIndex) => { // 获取当前行中的所有单元格(.shu) const cells = row.querySelectorAll('.shu'); // 遍历每一个单元格 cells.forEach((cell, cellIndex) => { // 如果是每行的第一个单元格,则添加左边框 if (cellIndex === 0) { cell.style.borderLeft = '1px solid #000'; } // 如果是最后一行的所有单元格,则添加下边框 if (rowIndex === rows.length - 1) { cell.style.borderBottom = '1px solid #000'; } }); }); }); </script> </body> </html>
通过这种方式,你可以使用JavaScript来实现与CSS伪类选择器相似的效果,同时保留了灵活性和动态性。虽然JavaScript提供了强大的功能,但过度依赖它可能会使代码难以维护。尽量将样式规则保留在CSS中,仅在必要时使用JavaScript进行增强。