实现这样的一个九宫格(300 x 300),鼠标hover的时候边框高亮
主要涉及几个方面:
- 布局
- 盒模型
- 格与格之间的边框处理
- 边框的层叠问题
布局上我们可以采用float、inline-block、table-cell、flex、grid等
这里以Flex布局为例
我们先创建一个九宫格,再来逐步完善细节
先创建九宫格
<ul class="grid">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
html,body,ul,li {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.grid {
width: 300px;
display: flex;
flex-wrap: wrap; // 设置换行,才能实现一个九宫格
}
.grid li {
width: 100px;
height: 100px;
border: 4px solid #000000;
text-align: center; // 文字水平居中
line-height: 100px; // 文字垂直居中
box-sizing: boder-box; // 设置盒模型
}
这样我们实现了一个九宫格,其中注意设置flex-wrap: wrap;
和box-sizing: boder-box;
flex-wrap
属性默认nowrap
,表示不拆行不拆列,如果我们不设置,会发现9个格子都挤在同一行,无法实现九宫格,所以设置为warp
,表示在必要时候可拆行或拆列
box-sizing
涉及盒模型相关知识,默认取值是content-box
,表示元素width
的值为content
的width
,不包括padding
和border
,设置为boder-box
则表示元素width
的值为content
+padding
+border
例如我们这里不设置box-sizing
,可知九宫格容器宽为300px
,一个格子宽设为100px
,边框为4px
,那么一个格子总宽就为108px
,三个格子则需要324px
,此时第三个格子就会被换行移动至第二行,此时需要把格子宽设置为92px
才能实现一个九宫格,如果边框大小变动,又得重新计算格子宽度,比较麻烦,所以我们设置为boder-box
则方便许多
解决边框问题
只要视力没问题的,应该都看得出上面创建的九宫格中,格子与格子直接的边框并不符合我们的要求,我们可以采用“负边距”方法来解决,简单理解就是第二列和第三列的格子往左移动一个边框大小,第二行和第三行的格子往上移动一个边框大小,第一列和第一行不动
直接上代码
.grid li {
width: 100px;
height: 100px;
border: 4px solid #000000;
text-align: center; // 文字水平居中
line-height: 100px; // 文字垂直居中
box-sizing: boder-box; // 设置盒模型
// 以下为新增代码
margin-left: -4px;
margin-top: -4px;
}
// 以下为新增代码
.gird li:nth-child(3n+1) { // 表示第1、4、7个格子
margin-left: 0;
}
.grid li:nth-child(-n+3) { // 表示前3个格子
margin-top: 0;
}
这里涉及到的知识点是利用负边距来解决边框问题,以及CSS的高级选择器:nth-child(n)
:nth-child(n)
选择器表示匹配属于其父元素的第n
个子元素,不论元素的类型,n
的取值可以是数字、关键词或者公式,注意公式的格式是an+b
,n
是计数器,从0开始,b
是偏移量
比如:
:nth-child(2)
表示取其父元素中的第2个子元素
:nth-child(odd)
表示取其父元素中下标为奇数的子元素(第一个子元素是1)
:nth-child(even)
表示取其父元素中下标为偶数的子元素(第一个子元素是1)
:nth-child(3n+0)
表示取其父元素中下标为是3的倍数的子元素(n从0开始算起)
加上hover效果
鼠标移上去使对应格子边框红色高亮
.grid li:hover {
boder-color: red;
}
加上之后查看效果:
解决边框重叠问题
加上hover效果之后发现边框被重叠,可以通过设置z-index
来解决
.grid li:hover {
boder-color: red;
// 以下为新增代码
z-index: 2;
}
最终得到我们想要的九宫格
其他布局基本大同小异,这里提供其他布局的代码及注释
使用float
<ul class="grid">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
html,body,ul,li {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.grid {
width: 300px;
float: left;
}
.grid li {
float: left;
width: 100px;
height: 100px;
margin-left: -4px;
margin-top: -4px;
line-height: 100px;
text-align: center;
color: #444;
border: 4px solid #444;
position: relative; // 为了让z-index起效果,需要加上这个
box-sizing: border-box;
}
.grid li:nth-child(3n+1) {
margin-left: 0;
}
.grid li:nth-child(-n+3) {
margin-top: 0;
}
.grid li:hover {
border-color: red;
z-index: 2;
}
grid
<ul class="grid">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
html,body,ul,li {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.grid {
width: 300px;
display: grid;
grid-template-columns: 100px 100px 100px; // 设置三列,每列100px
grid-template-rows: 100px 100px 100px; // 设置三行,每行100px
}
.grid li {
text-align: center;
line-height: 100px;
border: 4px solid #000000;
box-sizing: border-box;
margin-left: -4px;
margin-top: -4px;
}
.grid li:nth-child(3n+1) {
margin-left: 0;
}
.grid li:nth-child(-n+3) {
margin-top: 0;
}
.grid li:hover {
border-color: red;
z-index: 2;
}
inline-block
<ul class="grid">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
html,body,ul,li {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.grid {
width: 300px;
font-size: 0; // 消除inline-block元素间的空格
}
.grid li {
width: 100px;
height: 100px;
display: inline-block;
font-size: 16px; // 父元素设置了0,这里需要重新设置一下
text-align: center;
line-height: 100px;
border: 4px solid #000000;
box-sizing: border-box;
position: relative; // 为了让z-index起效果,需要加上这个
margin-left: -4px;
margin-top: -4px;
}
.grid li:nth-child(3n+1) {
margin-left: 0;
}
.grid li:nth-child(-n+3) {
margin-top: 0;
}
.grid li:hover {
border-color: red;
z-index: 2;
}
table-cell
使用table
布局,这里不知道有没有更好的方法
<ul class="grid">
<li>
<span>1</span>
<span>2</span>
<span>3</span>
</li>
<li>
<span>4</span>
<span>5</span>
<span>6</span>
</li>
<li>
<span>7</span>
<span>8</span>
<span>9</span>
</li>
</ul>
html,body,ul,li {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.grid {
width: 300px;
display: table;
}
.grid li {
display: table-row;
}
.grid li span {
float: left; // 因为table-cell会导致margin不起作用,所以加上这个才会起作用
width: 100px;
height: 100px;
margin-left: -4px;
margin-top: -4px;
line-height: 100px;
text-align: center;
color: #444;
border: 4px solid #444;
display: table-cell;
position: relative; // 为了让z-index起效果,需要加上这个
box-sizing: border-box;
}
.grid li span:first-child { // 每个li内的第一个span
margin-left: 0;
}
.grid li:first-child span { // 第一个li内的每个span
margin-top: 0;
}
.grid li span:hover {
border-color: red;
z-index: 2;
}
结语
本人在写页面这方面算是新手,难免有错误,希望各位看官可以不吝赐教,共同进步。
热门评论
写的不错,用jquery瀑布流的思想可以解决多少空格的都可以,m*n格