CSS Grid 布局

CSS Grid(网格) 布局(又称为 “Grid(网格)” ),是一个二维的基于网格的布局系统它的目标是完全改变我们基于网格的用户界面的布局方式。

网格容器(Grid Container)

应用 display: grid的元素。这是所有网格项(Grid Items)的直接父级元素。在这个例子中,container 就是网格容器(Grid Container)
举例:

<div class="container">
  <div class="item item-1"></div>
  <div class="item item-2"></div>
  <div class="item item-3"></div>
</div>

网格项(Grid Item)

网格容器(Grid Container)的子元素(直接子元素)。这里item元素就是网格项(Grid Item),但是 sub-item不是。
举例

<div class="container">
  <div class="item"></div> 
  <div class="item">
    <p class="sub-item"></p>  //不是网格项(Grid Item)
  </div>
  <div class="item"></div>
</div>

网格线(Grid Line)

构成网格结构的分界线。它们既可以是垂直的(“列网格线(column grid lines)”),也可以是水平的(“行网格线(row grid lines)”),并位于行或列的任一侧。例如,这里的黄线就是一条列网格线。

网格线(Grid Line)

网格轨道(Grid Track)

两条相邻网格线之间的空间。你可以把它们想象成网格的列或行。下图是第二条和第三条 行网格线 之间的 网格轨道(Grid Track)。

网格轨道(Grid Track)

网格单元格(Grid Cell)

两个相邻的行和两个相邻的列网格线之间的空间。这是 Grid(网格) 系统的一个“单元”。下图是第1至第2条 行网格线 和第2至第3条 列网格线 交汇构成的 网格单元格(Grid Cell)。

网格单元格(Grid Cell)

网格区域(Grid Area)

4条网格线包围的总空间。一个 网格区域(Grid Area) 可以由任意数量的 网格单元格(Grid Cell) 组成。下图是 行网格线1和3,以及列网格线1和3 之间的网格区域。


网格区域(Grid Area)

父元素 网格容器(Grid Container) 属性

1. display

将元素定义为网格容器,并为其内容建立新的 网格格式上下文。
值:

  • grid :生成一个块级网格

  • inline-grid :生成一个内联网格

  • subgrid :如果你的网格容器本身是另一个网格的网格项(即嵌套网格),你可以使用这个属性来表示
    你希望它的行/列的大小继承自它的父级网格容器,而不是自己指定的。

如果你想要设置为网格容器元素本身已经是网格项(嵌套网格布局),用这个属性指明这个容器内部的网格项的行列尺寸直接继承其父级的网格容器属性。

.container {
    display: grid | inline-grid | subgrid;
}

注意:在 网格容器(Grid Container) 上使用columnfloatclearvertical-align 不会产生任何效果。

2. grid-template-columns / grid-template-rows

使用空格分隔的值列表,用来定义网格的列和行。这些值表示 网格轨道(Grid Track) 大小,它们之间的空格表示网格线。
值:

  • <track-size>: 可以是长度值,百分比,或者等份网格容器中可用空间(使用 fr 单位)
  • <line-name>:你可以选择的任意名称
.container {
    grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
    grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}

举例:

.container{
    grid-template-columns: 40px 50px auto 50px 40px; //表示一共5列
    grid-template-rows: 25% 100px auto; //表示一共3行
}
分隔线默认名称

但是你可以明确的指定网格线(Grid Line)名称,即 <line-name> 值。请注意网格线名称的括号语法:

.container {
    grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
    grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}

分隔线自定义名称

请注意,一条网格线(Grid Line)可以有多个名称。例如,这里的第二条 行网格线(row grid lines) 将有两个名字:row1-end 和row2-start :

.container{
    grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}

如果你的定义包含多个重复值,则可以使用 repeat() 表示法来简化定义:

.container {
    grid-template-columns: repeat(3, 20px [col-start]) 5%;
}

上面的代码等价于:

.container {
    grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;
}

fr 单元允许你用等分网格容器剩余可用空间来设置 网格轨道(Grid Track) 的大小 。例如,下面的代码会将每个网格项设置为网格容器宽度的三分之一:

.container {
    grid-template-columns: 1fr 1fr 1fr;
}

剩余可用空间是除去所有非灵活网格项之后计算得到的。在这个例子中,可用空间总量减去 50px 后,再给 fr 单元的值3等分:

.container {
    grid-template-columns: 1fr 50px 1fr 1fr;
}

3.grid-template-areas

通过引用 grid-area 属性指定的 网格区域(Grid Area) 名称来定义网格模板。重复网格区域的名称导致内容跨越这些单元格。一个点号(.)代表一个空的网格单元。这个语法本身可视作网格的可视化结构。

值:

  • <grid-area-name>:由网格项的 grid-area 指定的网格区域名称
  • .(点号) :代表一个空的网格单元
  • none:不定义网格区域
    示例:
.container {
  grid-template-columns: 50px 50px 50px 50px;
  grid-template-rows: auto;
  grid-template-areas: 
    "header header header header"
    "main main . sidebar"
    "footer footer footer footer";
}

.item-a {
  grid-area: header;
}
.item-b {
  grid-area: main;
}
.item-c {
  grid-area: sidebar;
}
.item-d {
  grid-area: footer;
}

上面的代码将创建一个 4 列 3 行的网格。整个顶行将由 header 区域 组成。中间一排将由两个 main 区域,一个是空单元格,一个 sidebar 区域组成。最后一行全是 footer 区域组成。

image

你的声明中的每一行都需要有相同数量的单元格。

4. grid-template

用于定义 grid-template-rowsgrid-template-columnsgrid-template-areas 缩写属性。

值:

  • none:将所有三个属性设置为其初始值
  • subgrid:将grid-template-rowsgrid-template-columns的值设为 subgridgrid-template-areas设为初始值
  • <grid-template-rows> / <grid-template-columns>:将 grid-template-columnsgrid-template-rows设置为相应地特定的值,并且设置grid-template-areasnone

例子:

.container {
  grid-template:
    "header header header" 25px  // 行高 rows
    "footer footer footer" 25px  // 行高 rows
    / auto 50px auto; //  列宽 columns
}

等价于:

.container {
  grid-template-rows: 25px 25px;
  grid-template-columns: auto 50px auto;
  grid-template-areas: 
    "header header header" 
    "footer footer footer";
}

由于 grid-template不会重置 隐式 网格属性(grid-auto-columnsgrid-auto-rows, 和 grid-auto-flow),
这可能是你想在大多数情况下做的,建议使用 grid属性而不是 grid-template

5. grid-column-gap / grid-row-gap

指定网格线(grid lines)的大小。你可以把它想象为设置列/行之间间距的宽度

示例:

.container {
  grid-template-columns: 100px 50px 100px;
  grid-template-rows: 80px auto 80px; 
  grid-column-gap: 10px; // 列与列间隙 10px
  grid-row-gap: 15px;  //行与行间隙15px
}

列/行之间间距的宽度 gap

注:只能在 列/行 之间创建间距,网格外部边缘不会有这个间距。

6. grid-gap

grid-column-gapgrid-row-gap的缩写语法

值:

  • <grid-row-gap> <grid-column-gap>:长度值

示例:

.container{
  grid-template-columns: 100px 50px 100px;
  grid-template-rows: 80px auto 80px; 
  grid-gap: 10px 15px; // <grid-row-gap> <grid-column-gap>;
}

7. justify-items

沿着 行轴线(row axis) 对齐 网格项(grid items) 内的内容(相反的属性是 align-items沿着列轴线对齐)。该值适用于容器内的所有网格项。

值:

  • start:将内容对齐到网格区域(grid area)的左侧
  • end:将内容对齐到网格区域的右侧
  • center:将内容对齐到网格区域的中间(水平居中)
  • stretch:填满网格区域宽度(默认值)
.container {
    justify-items: start | end | center | stretch;
}

示例:

.container {
  justify-items: start;
}

image
.container{
  justify-items: end;
}

image
.container{
  justify-items: center;
}

image
.container{
  justify-items: stretch;
}

image

这些行为也可以通过单独网格项(grid items) 的 justify-self属性设置。

8. align-items

沿着 列轴线(column axis) 对齐 网格项(grid items) 内的内容(相反的属性是 justify-items沿着行轴线对齐)。该值适用于容器内的所有网格项。

值:

  • start:将内容对齐到网格区域(grid area)的顶部
  • end:将内容对齐到网格区域的底部
  • center:将内容对齐到网格区域的中间(垂直居中)
  • stretch:填满网格区域高度(默认值)
.container {
  align-items: start | end | center | stretch;
}

示例:

.container {
  align-items: start;
}

image
.container {
  align-items: end;
}

image
.container {
  align-items: center;
}

image
.container {
  align-items: stretch;
}

image

这些行为也可以通过单独网格项(grid items) 的 align-self属性设置。

9. justify-content

有时,你的网格合计大小可能小于其 网格容器(grid container) 大小。 如果你的所有 网格项(grid items) 都使用像 px 这样的非灵活单位设置大小,在这种情况下,您可以设置网格容器内的网格的对齐方式。 此属性沿着 行轴线(row axis) 对齐网格(相反的属性是 align-content,沿着列轴线对齐网格)。

值:

  • start:将网格对齐到 网格容器(grid container) 的左边
  • end:将网格对齐到 网格容器 的右边
  • center:将网格对齐到 网格容器 的中间(水平居中)
  • stretch:调整 网格项(grid items) 的宽度,允许该网格填充满整个 网格容器 的宽度
  • space-around:在每个网格项之间放置一个均匀的空间,左右两端放置一半的空间
  • space-between:在每个网格项之间放置一个均匀的空间,左右两端没有空间
  • space-evenly:在每个栅格项目之间放置一个均匀的空间,左右两端放置一个均匀的空间
.container {
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;    
}

示例:

.container {
  justify-content: start;
}

image
.container {
  justify-content: end;
}

image
.container {
  justify-content: center;
}

image
.container {
  justify-content: stretch;
}

image
.container {
  justify-content: space-around;
}

image
.container {
  justify-content: space-between;
}

image

CSS 代码:

.container {
  justify-content: space-evenly;
}

image

10. align-content

有时,你的网格合计大小可能小于其 网格容器(grid container) 大小。 如果你的所有 网格项(grid items) 都使用像 px 这样的非灵活单位设置大小,在这种情况下,您可以设置网格容器内的网格的对齐方式。 此属性沿着 列轴线(column axis) 对齐网格(相反的属性是 justify-content,沿着行轴线对齐网格)。

值:

  • start:将网格对齐到 网格容器(grid container) 的顶部
  • end:将网格对齐到 网格容器 的底部
  • center:将网格对齐到 网格容器 的中间(垂直居中)
  • stretch:调整 网格项(grid items) 的高度,允许该网格填充满整个 网格容器 的高度
  • space-around:在每个网格项之间放置一个均匀的空间,上下两端放置一半的空间
  • space-between:在每个网格项之间放置一个均匀的空间,上下两端没有空间
  • space-evenly:在每个栅格项目之间放置一个均匀的空间,上下两端放置一个均匀的空间
.container {
  align-content: start |  end  | center | stretch | space-around | space-between | space-evenly;  
}

示例:

.container {
  align-content: start;  
}

image
.container {
2\.  align-content:  end;  
}

image
.container {
  align-content: center;   
}

image
.container {
  align-content: stretch;  
}

image
.container {
  align-content: space-around;  
}

image
.container {
  align-content: space-between;  
}

image

CSS 代码:

.container {
  align-content: space-evenly;  
}

image

11. grid-auto-columns / grid-auto-rows

指定任何自动生成的网格轨道(grid tracks)(又名隐式网格轨道)的大小。在你明确定位的行或列(通过 grid-template-rows / grid-template-columns),超出定义的网格范围时,隐式网格轨道被创建了。

值:
– <track-size>:可以是长度值,百分比,或者等份网格容器中可用空间(使用 fr 单位)

.container {
  grid-auto-columns:  <track-size>  ...;
  grid-auto-rows:  <track-size>  ...;
}

为了说明如何创建隐式网格轨道,请考虑一下以下的代码:

.container {
  grid-template-columns:  60px  60px;
  grid-template-rows:  90px  90px
}

image

生成了一个2×2的网格。

但现在想象一下,你使用 grid-columngrid-row 来定位你的网格项(grid items),像这样:

.item-a {
  grid-column:  1  /  2;
  grid-row:  2  /  3;
}

.item-b {
  grid-column:  5  /  6;
  grid-row:  2  /  3;
}

image

我们告诉 .item-b 从第 5 条列网格线开始到第 6 条列网格线结束,但我们从来没有定义过 第5 或 第6 列网格线。
因为我们引用的网格线不存在,所以创建宽度为 0 的隐式网格轨道以填补空缺。我们可以使用 grid-auto-columnsgrid-auto-rows 来指定这些隐式轨道的大小:

.container {
  grid-auto-columns:  60px;
}

image

12. grid-auto-flow

如果你有一些没有明确放置在网格上的网格项(grid items),自动放置算法 会自动放置这些网格项。该属性控制自动布局算法如何工作。

值:

  • row:告诉自动布局算法依次填充每行,根据需要添加新行
  • column:告诉自动布局算法依次填入每列,根据需要添加新列
  • dense:告诉自动布局算法在稍后出现较小的网格项时,尝试填充网格中较早的空缺
.container {
  grid-auto-flow: row | column | row dense | column dense
}

请注意,dense 集可能导致你的网格项出现乱序。

示例:

考虑以下 HTML :

<section class="container">
  <div class="item-a">item-a</div>
  <div class="item-b">item-b</div>
  <div class="item-c">item-c</div>
  <div class="item-d">item-d</div>
  <div class="item-e">item-e</div>
</section>

你定义一个有 5 列和 2 行的网格,并将 grid-auto-flow设置为 row(也就是默认值):

.container {
  display: grid;
  grid-template-columns:  60px  60px  60px  60px  60px;
  grid-template-rows:  30px  30px;
  grid-auto-flow: row;
}

将网格项放在网格上时,只能为其中的两个指定位置:

CSS 代码:

.item-a {
  grid-column:  1;
  grid-row:  1  /  3;
}
.item-e {
  grid-column:  5;
  grid-row:  1  /  3;
}

因为我们把 grid-auto-flow设成了 row ,所以我们的网格看起来会是这样。注意 我们没有进行定位的网格项(item-bitem-citem-d)会这样排列在可用的行中:

image

相反地,如果我们把 grid-auto-flow设成了 columnitem-bitem-citem-d会沿着列向下排列:

.container {
  display: grid;
  grid-template-columns:  60px  60px  60px  60px  60px;
  grid-template-rows:  30px  30px;
  grid-auto-flow: column;
}

image

13. grid

在一个声明中设置所有以下属性的简写: grid-template-rows, grid-template-columns, grid-template-areas, grid-auto-rows, grid-auto-columns, 和 grid-auto-flow。它还将grid-column-gapgrid-column-gap设置为初始值,即使它们不可以通过grid属性显式地设置。

值:

  • none:将所有子属性设置为其初始值
  • <grid-template-rows> / <grid-template-columns>:将 grid-template-rowsgrid-template-columns 分别设置为指定值,将所有其他子属性设置为其初始值
  • <grid-auto-flow> [<grid-auto-rows> [ / <grid-auto-columns>] ] :分别接受所有与 grid-auto-flowgrid-auto-rowsgrid-auto-columns 相同的值。如果省略了 grid-auto-columns,它被设置为由 grid-auto-rows 指定的值。如果两者都被省略,他们就会被设置为初始值
.container {
  grid: none |  <grid-template-rows>  /  <grid-template-columns>  |  <grid-auto-flow>  [<grid-auto-rows>  [/  <grid-auto-columns>]];
}

例子:

以下两个代码块是等效的:

.container {
  grid:  200px  auto  /  1fr  auto  1fr;
}

.container {
  grid-template-rows:  200px  auto;
  grid-template-columns:  1fr  auto  1fr;
  grid-template-areas: none;
}

以下两个代码块也是等效的:

.container {
  grid: column 1fr  /  auto;
}

.container {
  grid-auto-flow: column;
  grid-auto-rows:  1fr;
  grid-auto-columns:  auto;
}

它也接受一个更复杂但相当方便的语法来一次设置所有内容。您可以 grid-template-areasgrid-template-rowsgrid-template-columns,并所有其他的子属性都被设置为它们的初始值。这么做可以在它们网格区域内相应地指定网格线名字和网格轨道的大小。用最简单的例子来描述:

.container {
  grid:  "header header header"  1fr  
           "footer footer footer"  25px 
          /  auto  50px  auto;
}

等价于:

.container {
  grid-template-areas: 
    "header header header"
    "footer footer footer";
  grid-template-rows: 1fr  25px ;
  grid-template-columns: auto 50px auto;    
}

子元素 网格项(Grid Items) 属性

1. grid-column-start / grid-column-end / grid-row-start / grid-row-end

通过指定 网格线(grid lines) 来确定网格内 网格项(grid item) 的位置。 grid-column-start/ grid-row-start是网格项目开始的网格线,grid-column-end / grid-row-end 是网格项结束的网格线。
值:

  • <line> :可以是一个数字引用一个编号的网格线,或者一个名字来引用一个命名的网格线

  • span <number> :该网格项将跨越所提供的网格轨道数量

  • span <name> :该网格项将跨越到它与提供的名称位置

  • auto :表示自动放置,自动跨度,默认会扩展一个网格轨道的宽度或者高度

示例:

.item-a {
    grid-column-start: 2;
    grid-column-end: five;
    grid-row-start: row1-start
    grid-row-end: 3
}
网格项位置,grid-column-start,grid-column-end,grid-row-start,grid-row-end 的示例
.item-b {
  grid-column-start:  1;
  grid-column-end: span col4-start;
  grid-row-start:  2
  grid-row-end: span 2
}

网格项位置,grid-column-start,grid-column-end,grid-row-start,grid-row-end 的示例

如果没有声明指定 grid-column-end / grid-row-end,默认情况下,该网格项将占据1个轨道。

项目可以相互重叠。您可以使用 z-index 来控制它们的重叠顺序。

2. grid-column / grid-row

分别为 grid-column-start+ grid-column-endgrid-row-start + grid-row-end的缩写形式。

值:

  • <start-line> / <end-line>:每个网格项都接受所有相同的值,作为普通书写的版本,包括跨度
.item {
  grid-column:  <start-line>  / <end-line> | <start-line> / span <value>;
  grid-row:  <start-line>  / <end-line> | <start-line> / span <value>;
}

示例:

.item-c {
  grid-column:  3  / span 2;
  grid-row: third-line /  4;
}

image

如果没有声明分隔线结束位置,则该网格项默认占据 1 个网格轨道。

3. grid-area

为网格项提供一个名称,以便可以 被使用网格容器 grid-template-areas属性创建的模板进行引用。 另外,这个属性可以用作grid-row-start+ grid-column-start + grid-row-end+ grid-column-end的缩写。

值:

  • <name>:你所选的名称
  • <row-start> / <column-start> / <row-end> / <column-end>:数字或分隔线名称
.item {
  grid-area:  <name>  |  <row-start>  / <column-start> /  <row-end>  /  <column-end>;
}

示例:

作为为网格项分配名称的一种方法:

.item-d {
  grid-area: header
}

作为grid-row-start + grid-column-start + grid-row-end + grid-column-end属性的缩写形式

.item-d {
  grid-area:  1  / col4-start /  last-line /  6
}

image

4. justify-self

沿着 行轴线(row axis) 对齐 网格项 内的内容( 相反的属性是 align-self,沿着列轴线(column axis)对齐)。此值适用于单个网格项内的内容。

值:

  • start:将内容对齐到网格区域的左侧
  • end:将内容对齐到网格区域的右侧
  • center:将内容对齐到网格区域的中间(水平居中)
  • stretch:填充整个网格区域的宽度(这是默认值)

示例:

.item-a {
  justify-self: start;
}

image
.item-a {
  justify-self:  end;
}

image
.item-a {
  justify-self: center;
}

image
.item-a {
  justify-self: stretch;
}

image

要为网格中的所有网格项设置 行轴线(row axis) 线上对齐方式,也可以在 网格容器 上设置 justify-items属性。

5. align-self

沿着 列轴线(column axis) 对齐 网格项 内的内容( 相反的属性是 justify-self ,沿着 行轴线(row axis) 对齐)。此值适用于单个网格项内的内容。

值:

  • start:将内容对齐到网格区域的顶部
  • end:将内容对齐到网格区域的底部
  • center:将内容对齐到网格区域的中间(垂直居中)
  • stretch:填充整个网格区域的高度(这是默认值)
.item{
  align-self: start |  end  | center | stretch;
}

示例:

.item-a {
  align-self: start;
}

image
.item-a {
  align-self:  end;
}

</pre>

image
.item-a {
  align-self: center;
}

image
.item-a {
  align-self: stretch;
}

image

要为网格中的所有网格项设置 列轴线(column axis) 上的对齐方式,也可以在 网格容器 上设置 align-items属性。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容