精华内容
下载资源
问答
  • C# 自定义属性在propertyGrid控件中显示 演示demo
  • CSS Grid 布局完全指南(图解 Grid 详细教程) 转自:https://www.html.cn/archives/8510/ CSS Grid 布局是 CSS 中最强大的布局系统。与 flexbox 的一维布局系统不同,CSS Grid 布局是一个二维布局系统,也就意味着它...

    CSS Grid 布局完全指南(图解 Grid 详细教程)

    在这里插入图片描述
    CSS Grid 布局是 CSS 中最强大的布局系统。与 flexbox 的一维布局系统不同,CSS Grid 布局是一个二维布局系统,也就意味着它可以同时处理列和行。通过将 CSS 规则应用于 父元素 (成为 Grid Container 网格容器)和其 子元素(成为 Grid Items 网格项),你就可以轻松使用 Grid(网格) 布局。

    简介


    CSS Grid(网格) 布局(又称为 “Grid(网格)” ),是一个二维的基于网格的布局系统,它的目标是完全改变我们基于网格的用户界面的布局方式。CSS 一直用来布局我们的网页,但一直以来都存在这样或那样的问题。一开始我们用表格(table),然后是浮动(float),再是定位(postion)和内嵌块(inline-block),但是所有这些方法本质上都是只是 hack 而已,并且遗漏了很多重要的功能(例如垂直居中)。Flexbox 的出现很大程度上改善了我们的布局方式,但它的目的是为了解决更简单的一维布局,而不是复杂的二维布局(实际上 Flexbox 和 Grid 能协同工作,而且配合得非常好)。Grid(网格) 布局是第一个专门为解决布局问题而创建的 CSS 模块,只要我们一直在制作网站,我们就一直要讨论这些问题。



    有两个主要因素激发了我创建本指南的灵感。第一个是 Rachel Andrew 出色的书籍 为 CSS Grid 布局做好准备 。这本书对 Grid 布局做了全面,清晰的介绍 ,也是本指南的基础。我强烈建议你购买并阅读。另一个灵感来自 Chris Coyier 的 Flexbox 布局完整指南,这也是我学习 flexbox 首选的资源。这篇文章是帮助了很多人,这点从 Google “flexbox” 排名第一就可以看出来。你会发现那篇文章和我的文章有很多相似之处,为什么不跟随最好的文章呢?


    本指南的目的是介绍存在于最新版本的规范中 Grid(网格) 概念。所以我不会覆盖过时的 IE 语法,而且随着规范的逐渐成熟,我会尽我最大的努力去更新这个指南。

    基础知识和浏览器支持


    首先,你必须使用 【display: grid】 将容器元素定义为一个 grid(网格) 布局,使用 【grid-template-columns】 和 【grid-template-rows】 设置 列 和 行 的尺寸大小,然后通过 【grid-column 】和 【grid-row 】将其子元素放入这个 grid(网格) 中。与 flexbox 类似,网格项(grid items)的源(HTML结构)顺序无关紧要。你的 CSS 可以以任何顺序放置它们,这使得使用 媒体查询(media queries)重新排列网格变得非常容易。定义整个页面的布局,然后完全重新排列布局以适应不同的屏幕宽度,这些都只需要几行 CSS ,想象一下就让人兴奋。Grid(网格) 布局是有史以来最强大的 CSS 模块之一。

    截至2017年3月,许多浏览器都提供了对 CSS Grid 的原生支持,而且无需加浏览器前缀:Chrome(包括 Android ),Firefox,Edge,Safari(包括iOS)和 Opera 。 另一方面,Internet Explorer 10和11支持它,但是是一个过时的语法实现。 现在是时候使用 Grid 布局网页了!


    这个浏览器支持 CSS Grid 的数据,来自Caniuse ,你可以查看更多的细节。 数字表示支持以上功能的浏览器版本号。


    桌面(Desktop) 浏览器


    ChromeOperaFirefoxIEEdgaSafari
    57445211*(旧语法)1610.1

    手机(Mobile) / 平板(Tablet)浏览器


    iOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox
    10.346No677063

    除了微软之外,浏览器厂商似乎还没有对 Grid(网格) 搞自己的一套实现(比如加前缀),直到规范完全成熟。这是一件好事,因为这意味着我们不必担心学习多个语法。

    在生产中使用 Grid 只是时间问题。 但现在是学习的时候了。

    重要术语


    在深入了解 Grid 的概念之前,理解术语是很重要的。由于这里涉及的术语在概念上都很相似,如果不先记住 Grid 规范定义的含义,很容易混淆它们。但是别担心,术语并不多。

    网格容器(Grid Container)


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

    HTML代码:

    <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】 不是。

    HTML代码:

    <div class="container">
      <div class="item"></div> 
      <div class="item">
        <p class="sub-item"></p>
      </div>
      <div class="item"></div>
    </div>
    

    网格线(Grid Line)


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

    在这里插入图片描述


    网格轨道(Grid Track)


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

    在这里插入图片描述


    网格单元格(Grid Cell)


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

    在这里插入图片描述

    网格区域(Grid Area)


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

    在这里插入图片描述

    Grid(网格) 属性目录



    网格容器(Grid Container) 属性


    • display
    • grid-template-columns
    • grid-template-rows
    • grid-template-areas
    • grid-template
    • grid-column-gap
    • grid-row-gap
    • grid-gap
    • justify-items
    • align-items
    • place-items
    • justify-content
    • align-content
    • place-content
    • grid-auto-columns
    • grid-auto-rows
    • grid-auto-flow
    • grid

    网格容器(Grid Container) 属性


    • grid-column-start
    • grid-column-end
    • grid-row-start
    • grid-row-end
    • grid-column
    • grid-row
    • grid-area
    • justify-self
    • align-self
    • place-self

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


    display


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

    值:

    • 【grid】:生成一个块级网格
    • 【inline-grid 】:生成一个内联网格

    CSS代码:

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

    注意:通过嵌套元素(也称为子网格,即 subgrid )向下传递网格参数的能力已移至 CSS Grid 规范的 Level 2 版本。这里有 一个快速解释


    grid-template-columns / grid-template-rows


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

    值:

    • 【track-size】: 可以是长度值,百分比,或者等份网格容器中可用空间(使用 fr 单位)
    • 【line-name】:你可以选择的任意名称

    CSS代码:

    .container {
      grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
      grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
    }
    

    示例:

    当你在 网格轨道(Grid Track) 值之间留出空格时,网格线会自动分配正数和负数名称:

    CSS代码:

    .container {
      grid-template-columns: 40px 50px auto 50px 40px;
      grid-template-rows: 25% 100px auto;
    }
    

    在这里插入图片描述

    但是你可以明确的指定网格线(Grid Line)名称,例如 值。请注意网格线名称的括号语法:

    CSS 代码:

    .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 :

    CSS代码:

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

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

    CSS 代码:

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

    上面的代码等价于:

    CSS 代码:

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

    如果多行共享相同的名称,则可以通过其网格线名称和计数来引用它们。
    CSS 代码:

    .item {
      grid-column-start: col-start 2;
    }
    

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

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

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

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

    grid-template-areas


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

    值:

    • 【grid-area-name】:由网格项的 grid-area 指定的网格区域名称
    • .(点号) :代表一个空的网格单元
    • none:不定义网格区域

    CSS 代码:

    .container {
      grid-template-areas: 
        "<grid-area-name> | . | none | ..."
        "...";
    }
    

    示例:

    CSS 代码:

    .item-a {
      grid-area: header;
    }
    .item-b {
      grid-area: main;
    }
    .item-c {
      grid-area: sidebar;
    }
    .item-d {
      grid-area: footer;
    }
     
    .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";
    }
    

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

    在这里插入图片描述
    你的声明中的每一行都需要有相同数量的单元格。

    你可以使用任意数量的相邻的 点. 来声明单个空单元格。 只要这些点.之间没有空隙隔开,他们就代表一个单独的单元格。

    注意你 不能 用这个语法来命名网格线,只是命名 网格区域 。当你使用这种语法时,区域两端的网格线实际上会自动命名。如果你的网格区域的名字是 foo,该区域的起始行网格线 和 起始列网格线 的名称将为 foo-start,而最后一条行网格线 和 最后一条列网格线 的名称将为 foo-end。这意味着某些网格线可能有多个名字,如上例中最左边的网格线,它将有三个名称:header-startmain-startfooter-start

    grid-template


    用于定义 【grid-template-rows】 ,【grid-template-columns】 ,【grid-template-areas 】简写属性。

    值:

    • 【none】:将所有三个属性设置为其初始值
    • 【grid-template-rows/ grid-template-columns】:将 【grid-template-columns】 和 【grid-template-rows 】设置为相应地特定的值,并且设置【grid-template-areas】为none

    CSS 代码:

    .container {
      grid-template: none | <grid-template-rows> / <grid-template-columns>;
    }
    

    这个属性也接受一个更复杂但非常方便的语法来指定三个上诉属性。这里有一个例子:

    CSS 代码:

    .container {
      grid-template:
        [row1-start] "header header header" 25px [row1-end]
        [row2-start] "footer footer footer" 25px [row2-end]
        / auto 50px auto;
    }
    

    等价于:

    CSS 代码:

    .container {
      grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end];
      grid-template-columns: auto 50px auto;
      grid-template-areas: 
        "header header header" 
        "footer footer footer";
    }
    

    grid-column-gap / grid-row-gap


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

    值:

    • 【line-size】 :长度值

    CSS 代码:

    .container {
      grid-column-gap: <line-size>;
      grid-row-gap: <line-size>;
    }
    

    示例:

    CSS 代码:

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

    在这里插入图片描述
    只能在 列/行 之间创建间距,网格外部边缘不会有这个间距。

    注意:这两个属性将删除 【grid-】 前缀,就是将 【grid-column-gap】 和 【grid-row-gap】重命名为 【column-gap】 和 【row-gap】。 Chrome 68+Safari 11.2 Release 50+Opera 54+ 已经支持无前缀的属性。

    grid-gap


    【grid-column-gap 】和 【grid-row-gap 】的简写语法

    值:

    • 【grid-row-gap】 【grid-column-gap】:长度值

    CSS 代码:

    .container {
      grid-gap: <grid-row-gap> <grid-column-gap>;
    }
    

    示例:

    CSS 代码:

    .container {
      grid-template-columns: 100px 50px 100px;
      grid-template-rows: 80px auto 80px; 
      grid-gap: 15px 10px;
    }
    

    如果【grid-row-gap】没有定义,那么就会被设置为等同于 【grid-column-gap】 的值。例如下面的代码是等价的:

    CSS 代码:

    .container{
      /* 设置 grid-column-gap 和 grid-row-gap */  
      grid-column-gap: 10px;
      grid-row-gap: 10px; 
     
      /* 等价于 */  
      grid-gap: 10px 10px;
     
      /* 等价于 */  
      grid-gap: 10px;
    }
    

    注意:这个属性将删除 【grid- 】前缀,就是将 【grid-gap】 重命名为 【gap】。 Chrome 68+Safari 11.2 Release 50+Opera 54+ 已经支持无前缀的属性。

    justify-items


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

    值:

    • start:将网格项对齐到其单元格的左侧起始边缘(左侧对齐)
    • end:将网格项对齐到其单元格的右侧结束边缘(右侧对齐)
    • center:将网格项对齐到其单元格的水平中间位置(水平居中对齐)
    • stretch:填满单元格的宽度(默认值)

    CSS 代码:

    .container {
      justify-items: start | end | center | stretch;
    }
    

    示例:

    CSS 代码:

     .container {
          justify-items: start;
        }
    

    在这里插入图片描述
    CSS 代码:

    .container{
      justify-items: end;
    }
    

    在这里插入图片描述
    CSS 代码:

    .container{
      justify-items: center;
    }
    

    在这里插入图片描述
    CSS 代码:

    .container{
      justify-items: stretch;
    }
    

    在这里插入图片描述
    这些行为也可以通过每个单独网格项(grid items) 的 【justify-self】 属性设置。


    align-items


    沿着 block(列)轴线对齐网格项(grid items)(相反的属性是 justify-items 沿着 inline(行)轴线对齐)。此值适用于容器内的所有网格项。
    值:
    • start:将网格项对齐到其单元格的顶部起始边缘(顶部对齐)
    • end:将网格项对齐到其单元格的底部结束边缘(底部对齐)
    • center:将网格项对齐到其单元格的垂直中间位置(垂直居中对齐)
    • stretch:填满单元格的高度(默认值)

    CSS 代码:

    .container {
      align-items: start | end | center | stretch;
    }
    

    示例:

    CSS 代码:

    .container {
      align-items: start;
    }
    

    在这里插入图片描述
    CSS 代码:

    .container {
      align-items: end;
    }
    

    在这里插入图片描述
    CSS 代码:

    .container {
      align-items: center;
    }
    

    在这里插入图片描述
    CSS 代码:

    .container {
      align-items: center;
    }
    

    在这里插入图片描述
    这些行为也可以通过每个单独网格项(grid items) 的 align-self 属性设置。

    place-items


    `place-items` 是设置 `align-items` 和 `justify-items` 的简写形式。

    值:

    • <align-items> <justify-items>:第一个值设置 align-items 属性,第二个值设置
      justify-items 属性。如果省略第二个值,则将第一个值同时分配给这两个属性。

    除 Edge 之外的所有主要浏览器都支持 place-items 简写属性。

    有关更多详细信息,请参阅align-itemsjustify-items

    justify-content


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

    值:

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

    CSS 代码:

    .container {
      justify-content: start | end | center | stretch | space-around | space-between | space-evenly;    
    }
    

    示例:

    CSS 代码:

    .container {
      justify-content: start;
    }
    

    在这里插入图片描述
    CSS 代码:

    .container {
      justify-content: end;
    }
    

    在这里插入图片描述
    CSS 代码:

    .container {
      justify-content: center;
    }
    

    在这里插入图片描述
    CSS 代码:

    .container {
      justify-content: stretch;
    }
    

    在这里插入图片描述
    CSS 代码:

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

    在这里插入图片描述
    CSS 代码:

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

    在这里插入图片描述
    CSS 代码:

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

    在这里插入图片描述

    align-content


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

    值:

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

    CSS 代码:

    .container {
      align-content: start | end | center | stretch | space-around | space-between | space-evenly;  
    }
    

    示例:

    CSS 代码:

    .container {
      align-content: start; 
    }
    

    在这里插入图片描述
    CSS 代码:

    .container {
      align-content: end;   
    }
    

    在这里插入图片描述
    CSS 代码:

    .container {
      align-content: center;    
    }
    

    在这里插入图片描述
    CSS 代码:

    .container {
      align-content: stretch;   
    }
    

    在这里插入图片描述
    CSS 代码:

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

    在这里插入图片描述
    CSS 代码:

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

    在这里插入图片描述
    CSS 代码:

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

    在这里插入图片描述

    place-content


    place-content 是设置 align-content 和 justify-content 的简写形式。

    值:

    • <align-content> <justify-content>:第一个值设置 align-content 属性,第二个值设置
      justify-content 属性。如果省略第二个值,则将第一个值同时分配给这两个属性。

    除 Edge 之外的所有主要浏览器都支持 place-content 简写属性。

    有关更多详细信息,请参阅align-contentjustify-content


    grid-auto-columns / grid-auto-rows


    指定任何自动生成的网格轨道(grid tracks)(又名隐式网格轨道)的大小。当网格中的网格项多于单元格时,或者当网格项位于显式网格之外时,就会创建隐式轨道。(参见显式网格和隐式网格之间的区别)

    值:

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

    CSS 代码:

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

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

    CSS 代码:

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

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

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

    CSS 代码:

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

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

    CSS 代码:

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

    grid-auto-flow


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

    值:

    • row:告诉自动布局算法依次填充每行,根据需要添加新行 (默认)
    • column:告诉自动布局算法依次填入每列,根据需要添加新列
    • dense:告诉自动布局算法在稍后出现较小的网格项时,尝试填充网格中较早的空缺

    CSS 代码:

    .container {
      grid-auto-flow: row | column | row dense | column dense
    }
    

    请注意,dense 只会更改网格项的可视顺序,并可能导致它们出现乱序,这对可访问性不利。

    示例:

    考虑以下 HTML :

    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(也就是默认值):

    CSS 代码:

    .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-b,item-c,item-d)会这样排列在可用的行中:

    相反地,如果我们把 grid-auto-flow 设成了 column ,那么 item-b,item-c,item-d 会沿着列向下排列:

    CSS 代码:

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

    grid


    在一个声明中设置所有以下属性的简写: grid-template-rows, grid-template-columns, grid-template-areas, grid-auto-rows, grid-auto-columns, 和 grid-auto-flow 。(注意:您只能在单个网格声明中指定显式或隐式网格属性)。

    值:

    • none:将所有子属性设置为其初始值。
    • <grid-template>:与grid-template 简写的工作方式相同。
    • <grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns>?:将grid-template-rows 设置为指定的值。 如果 auto-flow 关键字位于斜杠的右侧,则会将grid-auto-flow 设置为 column。 如果另外指定了 dense 关键字,则自动放置算法使用 “dense” 算法。如果省略 grid-auto-columns ,则将其设置为 auto
    • [ auto-flow && dense? ]<grid-auto-rows>? / <grid-template-columns>:将 grid-template-columns设置为指定值。 如果 auto-flow 关键字位于斜杠的左侧,则会将grid-auto-flow 设置为 row 。 如果另外指定了
      dense 关键字,则自动放置算法使用 “dense” 打包算法。 如果省略 grid-auto-rows ,则将其设置为 auto

    例子:

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

    CSS 代码:

    .container {
      grid: 100px 300px / 3fr 1fr;
    }
    

    CSS 代码:

    .container {
      grid-template-rows: 100px 300px;
      grid-template-columns: 3fr 1fr;
    }
    

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

    CSS 代码:

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

    CSS 代码:

    .container {
      grid-auto-flow: row;
      grid-template-columns: 200px 1fr;
    }
    

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

    CSS 代码:

    .container {
      grid: auto-flow dense 100px / 1fr 2fr;
    }
    

    CSS 代码:

    .container {
      grid-auto-flow: row dense;
      grid-auto-rows: 100px;
      grid-template-columns: 1fr 2fr;
    }
    

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

    CSS 代码:

    .container {
      grid: 100px 300px / auto-flow 200px;
    }
    

    CSS 代码:

    .container {
      grid-template-rows: 100px 300px;
      grid-auto-flow: column;
      grid-auto-columns: 200px;
    }
    

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

    CSS 代码:

    .container {
      grid: [row1-start] "header header header" 1fr [row1-end]
            [row2-start] "footer footer footer" 25px [row2-end]
            / auto 50px auto;
    }
    

    等价于:

    CSS 代码:

    .container {
      grid-template-areas: 
        "header header header"
        "footer footer footer";
      grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
      grid-template-columns: auto 50px auto;    
    }
    

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


    注意:float,display: inline-block,display: table-cell,vertical-align 和 column-* 属性对网格项无效。

    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:表示自动放置,自动跨度,默认会扩展一个网格轨道的宽度或者高度

    CSS 代码:

    .item {
      grid-column-start: <number> | <name> | span <number> | span <name> | auto
      grid-column-end: <number> | <name> | span <number> | span <name> | auto
      grid-row-start: <number> | <name> | span <number> | span <name> | auto
      grid-row-end: <number> | <name> | span <number> | span <name> | auto
    }
    

    示例:

    CSS 代码:

    .item-a {
      grid-column-start: 2;
      grid-column-end: five;
      grid-row-start: row1-start
      grid-row-end: 3;
    }
    

    CSS 代码:

    .item-b {
      grid-column-start: 1;
      grid-column-end: span col4-start;
      grid-row-start: 2
      grid-row-end: span 2
    }
    

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

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


    grid-column / grid-row


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

    值:

    • <start-line> / <end-line>:每个网格项都接受所有相同的值,作为普通书写的版本,包括跨度

    CSS 代码:

    .item {
      grid-column: <start-line> / <end-line> | <start-line> / span <value>;
      grid-row: <start-line> / <end-line> | <start-line> / span <value>;
    }
    

    示例:

    CSS 代码:

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

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


    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>:数字或分隔线名称

    CSS 代码:

    .item {
      grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
    }
    

    示例:

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

    CSS 代码:

    .item-d {
      grid-area: header
    }
    

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

    CSS 代码:

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

    justify-self


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

    值:

    • start:将网格项对齐到其单元格的左侧起始边缘(左侧对齐)
    • end:将网格项对齐到其单元格的右侧结束边缘(右侧对齐)
    • center:将网格项对齐到其单元格的水平中间位置(水平居中对齐)
    • stretch:填满单元格的宽度(默认值)

    CSS 代码:

    .item {
      justify-self: start | end | center | stretch;
    }
    

    示例:

    CSS 代码:

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

    CSS 代码:

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

    CSS 代码:

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

    CSS 代码:

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

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


    #### align-self

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

    值:

    • start:将网格项对齐到其单元格的顶部起始边缘(顶部对齐)
    • end:将网格项对齐到其单元格的底部结束边缘(底部对齐)
    • center:将网格项对齐到其单元格的垂直中间位置(垂直居中对齐)
    • stretch:填满单元格的高度(默认值)

    CSS 代码:

    .item{
      align-self: start | end | center | stretch;
    }
    

    示例:

    CSS 代码:

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

    CSS 代码:

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

    CSS 代码:

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

    CSS 代码:

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

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

    place-self


    place-self 是设置 align-self 和 justify-self 的简写形式。

    值:

    • auto – 布局模式的 “默认” 对齐方式。
    • <align-self> <justify-self>:第一个值设置 align-self 属性,第二个值设置 justify-self 属性。如果省略第二个值,则将第一个值同时分配给这两个属性。
      示例:

    CSS 代码:

    .item-a {
      place-self: center;
    }
    

    CSS 代码:

    .item-a {
      place-self: center stretch;
    }
    

    除 Edge 之外的所有主要浏览器都支持 place-self 简写属性。

    动画(Animation)


    根据 CSS Grid 布局模块 Level 1 规范,有 5 个可应用动画的网格属性:

    • grid-gap, grid-row-gap,grid-column-gap 作为长度,百分比或 calc。
    • grid-template-columns,grid-template-rows 作为长度,百分比或 calc 的简单列表,只要列表中长度、百分比或calc组件的值不同即可。

    浏览器支持CSS网格属性


    截至今天(2018年5月7日),在测试的几个浏览器中仅实现 (grid-)gap,(grid-)row-gap,(grid-)column-gap 的动画。

    浏览器支持可设置动画的网格属性:

    浏览器(grid-)gap, (grid-)row-gap, (grid-)column-gapgrid-template-columns(grid-template-rows
    Firefox 55+, Firefox 53+ Mobile
    Safari 11.0.2
    Chrome 66+
    Chrome for Android 66+, Opera Mini 33+
    Edge 16+

    CSS网格布局:动画演示


    https://codepen.io/feiwen8772/embed/QJedqL?height=479&theme-id=0&slug-hash=QJedqL&default-tab=result&animations=run&editable=&embed-version=2&user=feiwen8772&name=cp_embed_1

    展开全文
  • dhtmlxGrid中文使用手册

    热门讨论 2011-11-02 17:32:20
    文档主要对dhtmlxGrid 实现的功能进行介绍,以及API操作中文手册。 文档大致目录如下: 一、 dhtmlxGrid 介绍 7 1. 自定义XML: 7 2. 支持多行表头、表尾展现 7 3. 移动、添加、删除列 8 4. 处理大型数据集-支持分页 ...
  • Oracle 19c Grid Infrastructure安装

    千次阅读 2019-09-07 21:58:25
    概述 ...主机为Oracle Linux 7,主机上已安装先决条件包(oracle-database-server-12cR2-preinstall RPM包),数据库使用oracle用户安装,GI准备用grid用户安装。 安装GI要求主机内存至少8G。 Grid In...

    概述

    本文描述在单个主机上(不是RAC)GI 19c的安装。
    Oracle数据库软件19c已安装,但未创建任何数据库。参见这篇文章
    主机为Oracle Linux 7,主机上已安装先决条件包(oracle-database-preinstall-19c),数据库软件用户为oracle,GI准备用grid用户安装。
    安装GI要求主机内存至少8G。
    Grid Infrastructure以下简称GI。

    准备

    创建GI用户

    *** 这一部分非常重要,不要漏任何group,否则在安装过程中会报错,基本都是组没赋完整 ***

    参考文档第6章,GI的安装需要grid用户和以下组:

    # groupadd -g 54321 oinstall
    # groupadd -g 54322 dba
    # groupadd -g 54323 oper
    # groupadd -g 54324 backupdba
    # groupadd -g 54325 dgdba
    # groupadd -g 54326 kmdba
    # groupadd -g 54327 asmdba
    # groupadd -g 54328 asmoper
    # groupadd -g 54329 asmadmin
    # groupadd -g 54330 racdba
    

    由于我们先安装了先决条件包,大部分的group已经安装:

    $ tail /etc/group
    ...
    oinstall:x:54321:oracle
    dba:x:54322:oracle
    oper:x:54323:oracle
    backupdba:x:54324:oracle
    dgdba:x:54325:oracle
    kmdba:x:54326:oracle
    racdba:x:54330:oracle
    

    只剩下54327-53329三个组,因此我们将这几个group补齐:

    groupadd -g 54327 asmdba
    groupadd -g 54328 asmoper
    groupadd -g 54329 asmadmin
    

    接下来创建GI用户,安装手册中提到:

    The Grid user must be a member of the OSASM group (asmadmin) and the OSDBA for ASM group (asmdba).

    安装手册中又提到:

    For Oracle Restart installations, to successfully install Oracle Database, ensure that the grid user is a member of the racdba group.

    这句话的意思是说,如果如果在Oracle Restart环境下安装Oracle数据库,GI用户必须有racdba的权限。

    执行命令如下:

    useradd -u 54322 -g oinstall -G asmadmin,asmdba,asmoper,dba,racdba grid
    

    验证:

    $ id grid
    uid=54322(grid) gid=54321(oinstall) groups=54321(oinstall),54322(dba),54327(asmdba),54329(asmadmin)
    

    设置口令:

    passwd grid
    

    创建目录结构

    GI用户也有自己的ORACLE_HOME和ORACLE_BASE。
    ORACLE_HOME设置为/u01/app/19.0.0/grid,比oracle用户的/u01/app/oracle/product/12.2.0.1/dbhome_1简洁;ORACLE_BASE设为/u01/app/grid,和oracle用户的/u01/app/oracle类似。

    # 使用root用户执行
    mkdir -p  /u01/app/19.0.0/grid
    mkdir -p /u01/app/grid
    chown -R grid:oinstall /u01/app/19.0.0/grid
    chown -R grid:oinstall /u01/app/grid
    

    下载软件

    OTN下载。文件名为linuxx64_12201_grid_home.zip,约2.8G。

    安装和配置GI软件

    本节操作均使用GI用户grid。

    设置环境变量

    在~grid/.bash_profile中添加:

    export ORACLE_HOME=/u01/app/19.0.0/grid
    export ORACLE_BASE=/u01/app/grid
    export PATH=$ORACLE_HOME/bin:$PATH
    

    安装

    在12.2之后,GI的安装就是解压,目标是预设的ORACLE_HOME目录。使用grid用户解压。安装完成后大约7G。解压需要近5分钟。

    $ cd $ORACLE_HOME
    $ unzip -q /vagrant/LINUX.X64_193000_grid_home.zip
    

    存储准备

    建立两个12G的盘,这两个盘是在VirtualBox中分配的动态磁盘,并挂载到主机。主机认到磁盘为sdc和sdd:

    # lsblk
    NAME                MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sdd                   8:48   0   12G  0 disk
    sdb                   8:16   0 15.6G  0 disk
    sdc                   8:32   0   12G  0 disk
    sda                   8:0    0 36.5G  0 disk
    ├─sda2                8:2    0   36G  0 part
    │ ├─vg_main-lv_swap 252:1    0    4G  0 lvm  [SWAP]
    │ └─vg_main-lv_root 252:0    0   32G  0 lvm  /
    └─sda1                8:1    0  500M  0 part /boot
    

    格式化磁盘,输入的指令为n,p,回车,回车,回车,w

    # fdisk /dev/sdc
    # fdisk /dev/sdd
    

    可以看到分区sdc1和sdd1建立成功:

    # lsblk
    NAME                MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sdd                   8:48   0   12G  0 disk
    └─sdd1                8:49   0   12G  0 part
    sdb                   8:16   0 15.6G  0 disk
    sdc                   8:32   0   12G  0 disk
    └─sdc1                8:33   0   12G  0 part
    sda                   8:0    0 36.5G  0 disk
    ├─sda2                8:2    0   36G  0 part
    │ ├─vg_main-lv_swap 252:1    0    4G  0 lvm  [SWAP]
    │ └─vg_main-lv_root 252:0    0   32G  0 lvm  /
    └─sda1                8:1    0  500M  0 part /boot
    

    配置软件

    使用GI用户grid启动配置界面:

    $ cd $ORACLE_HOME
    $ ./gridSetup.sh 
    

    第一次仅设置软件(Set Up Software Only)
    在这里插入图片描述
    只有一个节点,不配置RAC。直接下一步:
    在这里插入图片描述
    配置ASM操作系统组:
    在这里插入图片描述
    ORACLE_HOME在安装时就确定了,这一步确定的是ORACLE_BASE:
    在这里插入图片描述
    root脚本执行配置:
    在这里插入图片描述
    先决条件检查,忽略警告:
    在这里插入图片描述
    安装前回顾:
    在这里插入图片描述
    开始安装:
    在这里插入图片描述
    执行root脚本:

    # /u01/app/19.0.0/grid/root.sh
    Performing root user operation.
    
    The following environment variables are set as:
        ORACLE_OWNER= grid
        ORACLE_HOME=  /u01/app/19.0.0/grid
    
    Enter the full pathname of the local bin directory: [/usr/local/bin]:
    The contents of "dbhome" have not changed. No need to overwrite.
    The contents of "oraenv" have not changed. No need to overwrite.
    The contents of "coraenv" have not changed. No need to overwrite.
    
    Entries will be added to the /etc/oratab file as needed by
    Database Configuration Assistant when a database is created
    Finished running generic part of root script.
    Now product-specific root actions will be performed.
    
    To configure Grid Infrastructure for a Cluster or Grid Infrastructure for a Stand-Alone Server execute the following command as grid user:
    /u01/app/19.0.0/grid/gridSetup.sh
    This command launches the Grid Infrastructure Setup Wizard. The wizard also supports silent operation, and the parameters can be passed through the response file that is available in the installation media.
    

    配置完成:
    在这里插入图片描述

    配置存储持久化

    ASM设备必须设置存储持久化,就是保证设备名,设备的权限在重启后不变化。有3中方式,udev,ASMLIB和ASM Filter Driver (Oracle ASMFD)。
    ASMFD是最新的,不是每一个操作系统都支持,我们另文介绍。ASMLIB过时了,不再讨论。udev是操作系统自带的,好处是不需要额外安装驱动。此处使用udev,参考这篇文章,写得非常全面,感谢作者。
    首先获取磁盘的SCSI ID,这是唯一不变的信息:

    # /usr/lib/udev/scsi_id -g -u -d /dev/sdc
    1ATA_VBOX_HARDDISK_VBb483d0cb-d9040f2a
    # /usr/lib/udev/scsi_id -g -u -d /dev/sdd
    1ATA_VBOX_HARDDISK_VBbc3d0f6f-2c4d4511
    

    使SCSI磁盘成为可信设备:

    # echo "options=-g" >> /etc/scsi_id.config
    

    添加ASM磁盘规则:
    其中的RESULT就是SCSI ID,磁盘的属主为grid:dba,mode是660,因为oracle用户也属于dba组,因此oracle可以访问此设备,即可以在其上安装数据库:

    # cat /etc/udev/rules.d/99-oracle-asmdevices.rules
    KERNEL=="sd?1", SUBSYSTEM=="block", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d /dev/$parent", RESULT=="1ATA_VBOX_HARDDISK_VBb483d0cb-d9040f2a", SYMLINK+="asm-disk1", OWNER="grid", GROUP="dba", MODE="0660"
    KERNEL=="sd?1", SUBSYSTEM=="block", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d /dev/$parent", RESULT=="1ATA_VBOX_HARDDISK_VBbc3d0f6f-2c4d4511", SYMLINK+="asm-disk2", OWNER="grid", GROUP="dba", MODE="0660"
    

    通知系统设备变更:

    # /sbin/partprobe /dev/sdc1
    # /sbin/partprobe /dev/sdd1
    

    以下的脚本可以批量的生成这些命令:

    i=1
    for disk in c d e f; do
            scsiid=$(/usr/lib/udev/scsi_id -g -u -d /dev/sd$disk)
            echo 'KERNEL=="sd?1", SUBSYSTEM=="block", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d /dev/$parent", RESULT=="'${scsiid}'", SYMLINK+="asm-disk'${i}'", OWNER="grid", GROUP="dba", MODE="0660"'
            ((i=i+1))
    done
    
    for disk in c d e f; do
            echo /sbin/partprobe /dev/sd${disk}1
    done
    
    

    在这一步,设备权限和属主已经发生变更:

    # ls -l /dev/sd?1
    brw-rw----. 1 root disk 8,  1 Sep  8 10:28 /dev/sda1
    brw-rw----. 1 grid dba  8, 33 Sep  8 11:31 /dev/sdc1
    brw-rw----. 1 grid dba  8, 49 Sep  8 11:31 /dev/sdd1
    # ls -l /dev/asm*
    lrwxrwxrwx. 1 root root 4 Sep  8 11:31 /dev/asm-disk1 -> sdc1
    lrwxrwxrwx. 1 root root 4 Sep  8 11:31 /dev/asm-disk2 -> sdd1
    
    

    测试udev设置:

    # udevadm test /block/sdc/sdc1
    # udevadm test /block/sdd/sdd1
    

    示例输出如下:

    # udevadm test /block/sdc/sdc1
    calling: test
    version 219
    This program is for debugging only, it does not run any program
    specified by a RUN key. It may show incorrect results, because
    some values may be different, or not available at a simulation run.
    
    === trie on-disk ===
    tool version:          219
    file size:         8201136 bytes
    header size             80 bytes
    strings            2142216 bytes
    nodes              6058840 bytes
    Load module index
    Network interface NamePolicy= disabled on kernel command line, ignoring.
    Created link configuration context.
    timestamp of '/etc/udev/rules.d' changed
    Skipping overridden file: /usr/lib/udev/rules.d/80-net-name-slot.rules.
    Reading rules file: /usr/lib/udev/rules.d/10-dm.rules
    Reading rules file: /usr/lib/udev/rules.d/100-balloon.rules
    Reading rules file: /usr/lib/udev/rules.d/11-dm-lvm.rules
    Reading rules file: /usr/lib/udev/rules.d/13-dm-disk.rules
    Reading rules file: /usr/lib/udev/rules.d/40-redhat-disable-dell-ir-camera.rules
    Reading rules file: /usr/lib/udev/rules.d/40-redhat-disable-lenovo-ir-camera.rules
    Reading rules file: /usr/lib/udev/rules.d/40-redhat.rules
    Reading rules file: /usr/lib/udev/rules.d/42-usb-hid-pm.rules
    Reading rules file: /usr/lib/udev/rules.d/50-udev-default.rules
    Reading rules file: /usr/lib/udev/rules.d/59-fc-wwpn-id.rules
    invalid key/value pair in file /usr/lib/udev/rules.d/59-fc-wwpn-id.rules on line 10, starting at character 26 (';')
    invalid key/value pair in file /usr/lib/udev/rules.d/59-fc-wwpn-id.rules on line 11, starting at character 29 (';')
    invalid key/value pair in file /usr/lib/udev/rules.d/59-fc-wwpn-id.rules on line 12, starting at character 25 (';')
    Reading rules file: /usr/lib/udev/rules.d/60-alias-kmsg.rules
    Reading rules file: /usr/lib/udev/rules.d/60-cdrom_id.rules
    Reading rules file: /usr/lib/udev/rules.d/60-drm.rules
    Reading rules file: /usr/lib/udev/rules.d/60-evdev.rules
    Reading rules file: /usr/lib/udev/rules.d/60-keyboard.rules
    Reading rules file: /usr/lib/udev/rules.d/60-net.rules
    Reading rules file: /usr/lib/udev/rules.d/60-persistent-alsa.rules
    Reading rules file: /usr/lib/udev/rules.d/60-persistent-input.rules
    Reading rules file: /usr/lib/udev/rules.d/60-persistent-serial.rules
    Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage-tape.rules
    Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage.rules
    Reading rules file: /usr/lib/udev/rules.d/60-persistent-v4l.rules
    Reading rules file: /usr/lib/udev/rules.d/60-raw.rules
    Reading rules file: /etc/udev/rules.d/60-vboxadd.rules
    Reading rules file: /usr/lib/udev/rules.d/61-accelerometer.rules
    Reading rules file: /usr/lib/udev/rules.d/64-btrfs-dm.rules
    Reading rules file: /usr/lib/udev/rules.d/64-btrfs.rules
    Reading rules file: /usr/lib/udev/rules.d/69-dm-lvm-metad.rules
    Reading rules file: /usr/lib/udev/rules.d/70-mouse.rules
    Reading rules file: /usr/lib/udev/rules.d/70-power-switch.rules
    Reading rules file: /usr/lib/udev/rules.d/70-touchpad.rules
    Reading rules file: /usr/lib/udev/rules.d/70-uaccess.rules
    Reading rules file: /usr/lib/udev/rules.d/71-seat.rules
    Reading rules file: /usr/lib/udev/rules.d/73-idrac.rules
    Reading rules file: /usr/lib/udev/rules.d/73-seat-late.rules
    Reading rules file: /usr/lib/udev/rules.d/75-net-description.rules
    Reading rules file: /usr/lib/udev/rules.d/75-probe_mtd.rules
    Reading rules file: /usr/lib/udev/rules.d/75-tty-description.rules
    Reading rules file: /usr/lib/udev/rules.d/76-phys-port-name.rules
    Reading rules file: /usr/lib/udev/rules.d/78-sound-card.rules
    Reading rules file: /usr/lib/udev/rules.d/80-drivers.rules
    Skipping empty file: /etc/udev/rules.d/80-net-name-slot.rules
    Reading rules file: /usr/lib/udev/rules.d/80-net-setup-link.rules
    Reading rules file: /usr/lib/udev/rules.d/81-kvm-rhel.rules
    Reading rules file: /usr/lib/udev/rules.d/90-vconsole.rules
    Reading rules file: /usr/lib/udev/rules.d/95-dm-notify.rules
    Reading rules file: /usr/lib/udev/rules.d/95-udev-late.rules
    Reading rules file: /etc/udev/rules.d/99-oracle-asmdevices.rules
    Reading rules file: /usr/lib/udev/rules.d/99-qemu-guest-agent.rules
    Reading rules file: /usr/lib/udev/rules.d/99-systemd.rules
    rules contain 24576 bytes tokens (2048 * 12 bytes), 13540 bytes strings
    2016 strings (25472 bytes), 1350 de-duplicated (12599 bytes), 667 trie nodes used
    GROUP 6 /usr/lib/udev/rules.d/50-udev-default.rules:52
    LINK 'disk/by-path/fc---lun-0-part1' /usr/lib/udev/rules.d/59-fc-wwpn-id.rules:15
    LINK 'disk/by-id/ata-VBOX_HARDDISK_VBb483d0cb-d9040f2a-part1' /usr/lib/udev/rules.d/60-persistent-storage.rules:56
    LINK 'disk/by-path/pci-0000:00:0d.0-ata-3.0-part1' /usr/lib/udev/rules.d/60-persistent-storage.rules:71
    IMPORT builtin 'blkid' /usr/lib/udev/rules.d/60-persistent-storage.rules:89
    probe /dev/sdc1 raid offset=0
    PROGRAM '/usr/lib/udev/scsi_id -g -u -d /dev/sdc' /etc/udev/rules.d/99-oracle-asmdevices.rules:1
    starting '/usr/lib/udev/scsi_id -g -u -d /dev/sdc'
    '/usr/lib/udev/scsi_id -g -u -d /dev/sdc'(out) '1ATA_VBOX_HARDDISK_VBb483d0cb-d9040f2a'
    '/usr/lib/udev/scsi_id -g -u -d /dev/sdc' [20936] exit with return code 0
    OWNER 54322 /etc/udev/rules.d/99-oracle-asmdevices.rules:1
    GROUP 54322 /etc/udev/rules.d/99-oracle-asmdevices.rules:1
    MODE 0660 /etc/udev/rules.d/99-oracle-asmdevices.rules:1
    LINK 'asm-disk1' /etc/udev/rules.d/99-oracle-asmdevices.rules:1
    PROGRAM '/usr/lib/udev/scsi_id -g -u -d /dev/sdc' /etc/udev/rules.d/99-oracle-asmdevices.rules:2
    starting '/usr/lib/udev/scsi_id -g -u -d /dev/sdc'
    '/usr/lib/udev/scsi_id -g -u -d /dev/sdc'(out) '1ATA_VBOX_HARDDISK_VBb483d0cb-d9040f2a'
    '/usr/lib/udev/scsi_id -g -u -d /dev/sdc' [20937] exit with return code 0
    handling device node '/dev/sdc1', devnum=b8:33, mode=0660, uid=54322, gid=54322
    preserve permissions /dev/sdc1, 060660, uid=54322, gid=54322
    preserve already existing symlink '/dev/block/8:33' to '../sdc1'
    found 'b8:33' claiming '/run/udev/links/\x2fasm-disk1'
    creating link '/dev/asm-disk1' to '/dev/sdc1'
    preserve already existing symlink '/dev/asm-disk1' to 'sdc1'
    found 'b8:33' claiming '/run/udev/links/\x2fdisk\x2fby-id\x2fata-VBOX_HARDDISK_VBb483d0cb-d9040f2a-part1'
    creating link '/dev/disk/by-id/ata-VBOX_HARDDISK_VBb483d0cb-d9040f2a-part1' to '/dev/sdc1'
    preserve already existing symlink '/dev/disk/by-id/ata-VBOX_HARDDISK_VBb483d0cb-d9040f2a-part1' to '../../sdc1'
    found 'b8:49' claiming '/run/udev/links/\x2fdisk\x2fby-path\x2ffc---lun-0-part1'
    found 'b8:33' claiming '/run/udev/links/\x2fdisk\x2fby-path\x2ffc---lun-0-part1'
    found 'b8:1' claiming '/run/udev/links/\x2fdisk\x2fby-path\x2ffc---lun-0-part1'
    creating link '/dev/disk/by-path/fc---lun-0-part1' to '/dev/sdc1'
    atomically replace '/dev/disk/by-path/fc---lun-0-part1'
    found 'b8:33' claiming '/run/udev/links/\x2fdisk\x2fby-path\x2fpci-0000:00:0d.0-ata-3.0-part1'
    creating link '/dev/disk/by-path/pci-0000:00:0d.0-ata-3.0-part1' to '/dev/sdc1'
    preserve already existing symlink '/dev/disk/by-path/pci-0000:00:0d.0-ata-3.0-part1' to '../../sdc1'
    created db file '/run/udev/data/b8:33' for '/block/sdc/sdc1'
    .ID_FS_TYPE_NEW=
    ACTION=add
    DEVLINKS=/dev/asm-disk1 /dev/disk/by-id/ata-VBOX_HARDDISK_VBb483d0cb-d9040f2a-part1 /dev/disk/by-path/fc---lun-0-part1 /dev/disk/by-path/pci-0000:00:0d.0-ata-3.0-part1
    DEVNAME=/dev/sdc1
    DEVPATH=/block/sdc/sdc1
    DEVTYPE=partition
    FC_TARGET_LUN=0
    ID_ATA=1
    ID_ATA_FEATURE_SET_PM=1
    ID_ATA_FEATURE_SET_PM_ENABLED=1
    ID_ATA_SATA=1
    ID_ATA_SATA_SIGNAL_RATE_GEN2=1
    ID_ATA_WRITE_CACHE=1
    ID_ATA_WRITE_CACHE_ENABLED=1
    ID_BUS=ata
    ID_FS_TYPE=
    ID_MODEL=VBOX_HARDDISK
    ID_MODEL_ENC=VBOX\x20HARDDISK\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
    ID_PART_ENTRY_DISK=8:32
    ID_PART_ENTRY_NUMBER=1
    ID_PART_ENTRY_OFFSET=2048
    ID_PART_ENTRY_SCHEME=dos
    ID_PART_ENTRY_SIZE=25163776
    ID_PART_ENTRY_TYPE=0x83
    ID_PART_TABLE_TYPE=dos
    ID_PATH=pci-0000:00:0d.0-ata-3.0
    ID_PATH_TAG=pci-0000_00_0d_0-ata-3_0
    ID_REVISION=1.0
    ID_SERIAL=VBOX_HARDDISK_VBb483d0cb-d9040f2a
    ID_SERIAL_SHORT=VBb483d0cb-d9040f2a
    ID_TYPE=disk
    MAJOR=8
    MINOR=33
    PARTN=1
    SUBSYSTEM=block
    TAGS=:systemd:
    USEC_INITIALIZED=2696692
    Unload module index
    Unloaded link configuration context.
    

    重启UDEV设备:

    udevadm control --reload-rules
    

    这样,以后每次重启,这些磁盘的设备名将保持不变,权限也保持不变,即属于grid:dba。

    配置GI

    使用GI用户(grid),再次启动GI设置程序:

    $ cd $ORACLE_HOME
    $ ./gridSetup.sh
    

    这一次,选择配置Oracle Restart,即Config Grid Infrastructure for standalone Server(Oracle Restart):
    在这里插入图片描述
    选择之前配置的两块12G磁盘:
    在这里插入图片描述
    设置ASM口令:
    在这里插入图片描述
    设置管理选项:
    在这里插入图片描述
    设置root脚本执行选项:
    在这里插入图片描述
    先决条件检查,选择忽略,(cvuqdisk那个包是RAC用的):
    在这里插入图片描述
    安装前回顾:
    在这里插入图片描述
    开始安装,很快进入执行root脚本阶段:
    在这里插入图片描述
    执行root脚本:

    # /u01/app/19.0.0/grid/root.sh
    Performing root user operation.
    
    The following environment variables are set as:
        ORACLE_OWNER= grid
        ORACLE_HOME=  /u01/app/19.0.0/grid
    
    Enter the full pathname of the local bin directory: [/usr/local/bin]:
    The contents of "dbhome" have not changed. No need to overwrite.
    The contents of "oraenv" have not changed. No need to overwrite.
    The contents of "coraenv" have not changed. No need to overwrite.
    
    Entries will be added to the /etc/oratab file as needed by
    Database Configuration Assistant when a database is created
    Finished running generic part of root script.
    Now product-specific root actions will be performed.
    Using configuration parameter file: /u01/app/19.0.0/grid/crs/install/crsconfig_params
    The log of current session can be found at:
      /u01/app/grid/crsdata/ol7-vagrant/crsconfig/roothas_2019-09-08_11-50-35AM.log
    2019/09/08 11:50:39 CLSRSC-363: User ignored prerequisites during installation
    LOCAL ADD MODE
    Creating OCR keys for user 'grid', privgrp 'oinstall'..
    Operation successful.
    LOCAL ONLY MODE
    Successfully accumulated necessary OCR keys.
    Creating OCR keys for user 'root', privgrp 'root'..
    Operation successful.
    CRS-4664: Node ol7-vagrant successfully pinned.
    2019/09/08 11:50:51 CLSRSC-330: Adding Clusterware entries to file 'oracle-ohasd.service'
    
    ol7-vagrant     2019/09/08 11:51:50     /u01/app/grid/crsdata/ol7-vagrant/olr/backup_20190908_115150.olr     724960844
    2019/09/08 11:51:51 CLSRSC-327: Successfully configured Oracle Restart for a standalone server
    

    终于看到这个成功的界面了!
    在这里插入图片描述

    安装后

    补充环境变量

    添加以下到GI用户(grid)的.bash_profile中:

    export ORACLE_SID=+ASM
    

    核验

    至此,GI配置全部完成,用于Oracle数据库安装的磁盘组也已就绪。通过asmca也可以确认:
    在这里插入图片描述
    GI设置成功后,我们在/etc/oratab中可以看到ASM实例,这时数据库尚未创建:

    $ tail /etc/oratab
    #
    # The first and second fields are the system identifier and home
    # directory of the database respectively.  The third field indicates
    # to the dbstart utility that the database should , "Y", or should not,
    # "N", be brought up at system boot time.
    #
    # Multiple entries with the same $ORACLE_SID are not allowed.
    #
    #
    +ASM:/u01/app/19.0.0/grid:N             # line added by Agent
    
    

    sqlplus也可以登录到实例:

    [grid@ol7-vagrant ~]$ . oraenv
    ORACLE_SID = [+ASM] ?
    The Oracle base remains unchanged with value /u01/app/grid
    [grid@ol7-vagrant ~]$ sqlplus / as sysdba
    
    SQL*Plus: Release 19.0.0.0.0 - Production on Sun Sep 8 12:27:43 2019
    Version 19.3.0.0.0
    
    Copyright (c) 1982, 2019, Oracle.  All rights reserved.
    
    
    Connected to:
    Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
    Version 19.3.0.0.0
    
    SQL> select name,state,type from v$asm_diskgroup;
    
    NAME                           STATE       TYPE
    ------------------------------ ----------- ------
    DATA                           MOUNTED     NORMAL
    SQL> show parameter asm_diskstring
    
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    asm_diskstring                       string      /dev/sd*
    
    

    重启主机,发现设备的权限没有变化:

    $ ls -l /dev/sd?1
    brw-rw----. 1 root disk 8,  1 Sep  8 12:36 /dev/sda1
    brw-rw----. 1 grid dba  8, 33 Sep  8 12:42 /dev/sdc1
    brw-rw----. 1 grid dba  8, 49 Sep  8 12:42 /dev/sdd1
    
    

    ASM实例也自动启动:

    $ ps -ef|grep ASM
    grid      4280     1  0 12:37 ?        00:00:00 asm_pmon_+ASM
    grid      4282     1  0 12:37 ?        00:00:00 asm_clmn_+ASM
    grid      4285     1  0 12:37 ?        00:00:00 asm_psp0_+ASM
    grid      4309     1  1 12:37 ?        00:00:05 asm_vktm_+ASM
    grid      4313     1  0 12:37 ?        00:00:00 asm_gen0_+ASM
    grid      4316     1  0 12:37 ?        00:00:00 asm_mman_+ASM
    grid      4320     1  0 12:37 ?        00:00:00 asm_gen1_+ASM
    grid      4323     1  0 12:37 ?        00:00:00 asm_diag_+ASM
    grid      4325     1  0 12:37 ?        00:00:00 asm_pman_+ASM
    grid      4327     1  0 12:37 ?        00:00:00 asm_dia0_+ASM
    grid      4329     1  0 12:37 ?        00:00:00 asm_dbw0_+ASM
    grid      4331     1  0 12:37 ?        00:00:00 asm_lgwr_+ASM
    grid      4333     1  0 12:37 ?        00:00:00 asm_ckpt_+ASM
    grid      4335     1  0 12:37 ?        00:00:00 asm_smon_+ASM
    grid      4337     1  0 12:37 ?        00:00:00 asm_lreg_+ASM
    grid      4339     1  0 12:37 ?        00:00:00 asm_pxmn_+ASM
    grid      4341     1  0 12:37 ?        00:00:00 asm_rbal_+ASM
    grid      4343     1  0 12:37 ?        00:00:00 asm_gmon_+ASM
    grid      4345     1  0 12:37 ?        00:00:00 asm_mmon_+ASM
    grid      4347     1  0 12:37 ?        00:00:00 asm_mmnl_+ASM
    grid      4376     1  0 12:37 ?        00:00:00 oracle+ASM (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
    grid      4974  4289  0 12:42 pts/0    00:00:00 grep --color=auto ASM
    
    

    asmcmd命令正常:

    $ asmcmd lsdg
    State    Type    Rebal  Sector  Logical_Sector  Block       AU  Total_MB  Free_MB  Req_mir_free_MB  Usable_file_MB  Offline_disks  Voting_files  Name
    MOUNTED  NORMAL  N         512             512   4096  4194304     24568    24344                0           12172              0             N  DATA/
    $ asmcmd lsdsk
    Path
    /dev/sdc1
    /dev/sdd1
    
    

    各资源均正常:

    $ crsctl stat resource -t
    [grid@ol7-vagrant ~]$ crsctl stat resource -t
    --------------------------------------------------------------------------------
    Name           Target  State        Server                   State details                                                                                    
    --------------------------------------------------------------------------------
    Local Resources
    --------------------------------------------------------------------------------
    ora.DATA.dg
                   ONLINE  ONLINE       ol7-vagrant              STABLE
    ora.LISTENER.lsnr
                   ONLINE  ONLINE       ol7-vagrant              STABLE
    ora.asm
                   ONLINE  ONLINE       ol7-vagrant              Started,STABLE
    ora.ons
                   OFFLINE OFFLINE      ol7-vagrant              STABLE
    --------------------------------------------------------------------------------
    Cluster Resources
    --------------------------------------------------------------------------------
    ora.cssd
          1        ONLINE  ONLINE       ol7-vagrant              STABLE
    ora.diskmon
          1        OFFLINE OFFLINE                               STABLE
    ora.evmd
          1        ONLINE  ONLINE       ol7-vagrant              STABLE
    --------------------------------------------------------------------------------
    
    

    最重要的一点,监听也正常,这个监听是grid用户创建的,后续建立数据库时也建议用GI的监听:

    $ lsnrctl status
    
    LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 08-SEP-2019 12:45:50
    
    Copyright (c) 1991, 2019, Oracle.  All rights reserved.
    
    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=ol7-vagrant)(PORT=1521)))
    STATUS of the LISTENER
    ------------------------
    Alias                     LISTENER
    Version                   TNSLSNR for Linux: Version 19.0.0.0.0 - Production
    Start Date                08-SEP-2019 12:37:09
    Uptime                    0 days 0 hr. 8 min. 40 sec
    Trace Level               off
    Security                  ON: Local OS Authentication
    SNMP                      OFF
    Listener Parameter File   /u01/app/19.0.0/grid/network/admin/listener.ora
    Listener Log File         /u01/app/grid/diag/tnslsnr/ol7-vagrant/listener/alert/log.xml
    Listening Endpoints Summary...
      (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=ol7-vagrant)(PORT=1521)))
      (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
    Services Summary...
    Service "+ASM" has 1 instance(s).
      Instance "+ASM", status READY, has 1 handler(s) for this service...
    Service "+ASM_DATA" has 1 instance(s).
      Instance "+ASM", status READY, has 1 handler(s) for this service...
    The command completed successfully
    
    

    错误

    这几天的安装中,频繁碰到这个错误,原因就是磁盘持久化设置不对。其实就是grid用户没有写磁盘设备的权限。如果这些磁盘属于root,那么可以肯定磁盘持久化没有设置成功。

    INFO:  [Sep 7, 2019 3:16:35 PM] ORA-15018: diskgroup cannot be created
    INFO:  [Sep 7, 2019 3:16:35 PM] Skipping line: ORA-15018: diskgroup cannot be created
    INFO:  [Sep 7, 2019 3:16:35 PM] ORA-15031: disk specification '/dev/sdd' matches no disks
    INFO:  [Sep 7, 2019 3:16:35 PM] Skipping line: ORA-15031: disk specification '/dev/sdd' matches no disks
    INFO:  [Sep 7, 2019 3:16:35 PM] ORA-15025: could not open disk "/dev/sdd"
    INFO:  [Sep 7, 2019 3:16:35 PM] Skipping line: ORA-15025: could not open disk "/dev/sdd"
    INFO:  [Sep 7, 2019 3:16:35 PM] ORA-27041: unable to open file
    INFO:  [Sep 7, 2019 3:16:35 PM] Skipping line: ORA-27041: unable to open file
    INFO:  [Sep 7, 2019 3:16:35 PM] Skipping line:
    INFO:  [Sep 7, 2019 3:16:35 PM] Skipping line:
    INFO:  [Sep 7, 2019 3:16:35 PM] Skipping line:
    INFO:  [Sep 7, 2019 3:16:35 PM] Completed Plugin named: asmca
    
    

    参考

    1. UDEV SCSI Rules Configuration In Oracle Linux 5, 6 and 7
    2. Grid Infrastructure Installation and Upgrade Guide (19c for Linux)
    展开全文
  • CSS Grid Generator CSS Grid Generator是一个由Sarah Drasner创建的免费工具。它是一个可视化设计工具,允许咱们创建一个基本的 grid 布局,然后就可以使用生成对应的代码,帮助咱们快速布局。 第一次进入是界面...

    CSS Grid Generator

    CSS Grid Generator 是一个由Sarah Drasner创建的免费工具。它是一个可视化设计工具,允许咱们创建一个基本的 grid 布局,然后就可以使用生成对应的代码,帮助咱们快速布局。

    第一次进入是界面是这样子的:

     

    640?wx_fmt=png

    CSS Grid 布局示例

    当我正在学习一些东西时,我发现最好的学习方法是使用现有的工具构建实用的东西。在本文中,咱们先从一个简单的布局开始,然后使用CSS Grid Generator创建在实际项目中使用所需的代码。

    首先从一个典型的布局开始,如下所示:

    640?wx_fmt=png

    接着在 CSS Grid Generator 界面的右侧更新对应的以下内容:

    • 行: 4

    • 列: 3

    • 列间距: 20

    • 行间距: 20

    间距让咱们的内容之间有一定的空白。可以只使用列间距,但我想在 HeaderFooter 之前留出一些空白,所以还同时使用行间距。

    640?wx_fmt=png

    接下来,就是需要定义应用程序的不同区域。在 CSS Grid Generator 中,可以单击并拖动到需要合并地方来创建一个区域。咱们希望Footer跨越整个网格,侧边栏占用一个单元格,主内容区域跨越2列,Footer 跨越4列,最终效果,如下:

    640?wx_fmt=png

    这看起来有点像咱们想要的布局,但仍然需要定义一些具体的尺寸。在CSS Grid Generator 会注意到每行和每列旁边都有一个输入框,可用于设置特定大小。

    • Header: 100px height

    • Sidebars: 200px width

    • Footer: 50px height

    640?wx_fmt=png

    这看起来更像更像咱们想要的布局,但是你可能会问1fr是多少。

    轨道可以用任何长度单位来定义。Grid还引入了一个额外的长度单位,以帮助各位创建灵活的Grid轨道。新的fr单元表示网格容器中可用空间的一小部分。

    第二行的1fr会告诉区域占用剩余的可用空间。如果将容器设置为100vh,就会占据整个页面的内容,列也是如此。

    CSS Grid Generated 生成的代码

    640?wx_fmt=png

    点击“请给我示例中的代码”就可以查看对应布局生成的 CSS 代码:

     

    .parent { 
    display: grid; 
    grid-template-columns: 200px 1fr 1fr 200px; 
    grid-template-rows: 100px 1fr 50px; 
    grid-column-gap: 20px;
    grid-row-gap: 20px; 
    .div1 { grid-area: 1 / 1 / 2 / 5; } 
    .div2 { grid-area: 2 / 1 / 3 / 2; } 
    .div3 { grid-area: 2 / 2 / 3 / 4; } 
    .div4 { grid-area: 2 / 4 / 3 / 5; } 
    .div5 { grid-area: 3 / 1 / 4 / 5; } 
    }

    创建一个simple-layout.htm并添加以下代码:

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Simple Layout</title>
      <style>
        body {
          margin: 0;
          padding: 0;
        }
      </style>
    </head>
    <body>

    </body>
    </html>

    接下来添加上面生成的 CSS:

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Simple Layout</title>
      <style>
        body {
          margin: 0;
          padding: 0;
        }
        .parent {
          display: grid;
          grid-template-columns: 200px 1fr 1fr 200px;
          grid-template-rows: 100px 1fr 50px;
          grid-column-gap: 20px;
          grid-row-gap: 20px;
          height: 100vh;
        }

        .div1 {
          grid-area: 1 / 1 / 2 / 5;
        }

        .div2 {
          grid-area: 2 / 1 / 3 / 2;
        }

        .div3 {
          grid-area: 2 / 2 / 3 / 4;
        }

        .div4 {
          grid-area: 2 / 4 / 3 / 5;
        }

        .div5 {
          grid-area: 3 / 1 / 4 / 5;
        }
      </style>
    </head>
    <body>

    </body>
    </html>

    接着添加对应的标签:

     

    <body>
      <div class="parent">
        <div class="div1">
          Header
        </div>
        <div class="div2">
          Left Sidebar
        </div>
        <div class="div3">
          Main Content
        </div>
        <div class="div4">
          Right Sidebar
        </div>
        <div class="div5">
          Footer
        </div>
      </div>

    </body>

    最后添加下面的CSS,它将为.div1 - .div5添加一些背景色:

     

    div:not(.parent) {
      padding: 10px;
      background-color: rgb(199, 199, 199);
    }

    运行:

    640?wx_fmt=png

    这看起来很好,但你希望它占据整个浏览器窗口。所以需要向.parent类添加height: 100vh

     

    .parent {
      display: grid;
      grid-template-columns: 200px 1fr 1fr 200px;
      grid-template-rows: 100px 1fr 50px;
      grid-column-gap: 20px;
      grid-row-gap: 20px;
      height: 100vh;
    }

    最终效果:

    640?wx_fmt=png

    网格轨道(Grid Track) 加餐

    两个相邻的网络线之间为网络轨道。

    640?wx_fmt=png

    图中的同方向 1 和 2, 2 和 3 都是相邻的网络线,当然同方向的 1 和 3 或者不同方向的 1 和 2 就不是相邻的网络线。

    相邻的网络线为网格轨道,如下,黑色1 和 2 之间就构成了网络轨道(背景深橘色):

    640?wx_fmt=png

    上面总共有 5 个网络轨道,水平方向灰色 1 和 2, 2 和 3, 3 和 4,竖直方向黑色的 1 和 2, 2 和 3,共 5 个。

    网格单元(Grid Cell) 加餐

    两个相邻的列网络线和两个相邻的行网络线组成的就是网络单元,如下面的深橘色背景就是网络单元。

    640?wx_fmt=png

    网络单元要与网络项(项目)区别开来,网络项是 Html 中可以找的到 Dom 元素,网络单元是在定义容器的时候,它就会分割出来的一个一个单元格。

    网格区域(Grid Area) 加餐

    四个网络线包围的总空间。

    640?wx_fmt=png

    fr单位(加餐)

    剩余空间分配数,用于在一系列长度值中分配剩余空间,如果多个已指定了多个部分,则剩下的空间根据各自的数字按比例分配。

     

    参考:

    https://www.danvega.dev/blog/2019/08/08/css-grid-generator

    慕课网:grid 教程

    展开全文
  • KendoGrid的使用

    千次阅读 2019-09-03 09:38:26
    $(".k-grid-content").find("tr:eq(" + 行+ ") td:eq(列)").text(data);//前台頁面賦值 $("#CommonReport_TableList").data("kendoGrid").dataSource._data[行].列名= data;//後台賦值 <style type="text/css...

    前后台赋值:

     $(".k-grid-content").find("tr:eq(" + 行+ ") td:eq(列)").text(data);//前台頁面賦值
     $("#CommonReport_TableList").data("kendoGrid").dataSource._data[行].列名= data;//後台賦值
    <style type="text/css">
        .red {
            color: red;
        }
    
        .hide {
            display: none;
        }
    
        .k-grid tr:hover {
            background-color: #ebebeb;
        }
    
        .k-grid-content td .k-button {
            width: 70px;
            display: inline;
        }
    
        .sectionGrid.k-grid > .k-grid-content, .k-grid > .k-grid-content {
            overflow: scroll;
        }
    
        #right {
            right: 0;
            top: 20px;
            bottom: 46px;
            left: 12px;
            position: absolute;
        }
    </style>
    <script src="~/JS/kendo.messages.zh-TW.js"></script>
    <script src="~/JS/kendo.culture.zh-TW.js"></script>
    <script src="~/Scripts/jquery.autogrow-textarea.js"></script>
    @*LZX--用戶處理人操作*@
    <script id="UserCL_ToolBar" type="text/x-kendo-template">
        @*用戶人處理表頭*@
        @*<a class="k-button k-button-icontext k-grid-delete hide" onclick="SaveUserCL();" name="UserCL_Save"><span class="k-icon k-grid-panel"></span>保存</a>*@
        <a class="k-button k-button-icontext k-grid-delete hide" onclick="UserCLBtnClick();" name="UserCL_Add"><span class="k-icon k-grid-panel"></span>批量追加</a>
        <a class="k-button k-button-icontext k-grid-delete hide" onclick="UserCLBtnClick();" name="UserCL_Update"><span class="k-icon k-grid-panel"></span>批量更新</a>
        <a class="k-button k-button-icontext k-grid-delete hide" onclick="UserCLBtnClick();" name="UserCL_Delete"><span class="k-icon k-delete"></span>批量删除</a>
        <a class="k-button k-button-icontext k-grid-panel hide" onclick="UserCL_RefreshGrid()" name="UserCL_Refresh"><span class="k-icon k-panel"></span>刷新</a>
    </script>
    <script>
        kendo.culture("zh-TW");
        var UserCL_GlobledataSource;
        var jsonData = [];          //data的參數數據
        var idArr = {};             //批量刪除的Id
        var fields = {};            //屬性
        var columns = [];           //前台表格表頭字段
        //var UserCL_tbody = $("#UserCL_List").children(".k-grid-content").children(0).children("tbody");//取到表格的tbody
        //var UserCL_operation_check = $("[name='operation_check']");//表格中的複選框 判斷:UserCL_operation_check[0].checked
       
        //初始化
        function UserCL_InitData() {
            debugger
            var getURL = "";
            $("#UserCL_List").html(null);
            getURL = "/Maintenance/BasicData/GetFlowWorkcenterList";
            fields = {
                Id: { type: "int"},
                FlowName: { type: "string", editable: true },
                ActivityNo: { type: "string", editable: true },
                Workcenter: { type: "string", editable: true },
                AuthorDisp: { type: "string", editable: false, defaultValue: $("#UserSel1").val() },
                Author: { type: "string", editable: false, defaultValue: $("#UserCL_UserName").val() },
                RoleID: { type: "string", editable: true },
                RoleType: { type: "string", editable: false, nullable: false, defaultValue: "User" }
            }
         
            columns = [
             {
                 headerTemplate: '<input type="checkbox" id="UserCL_check_all" />',
                 template: "<input type='checkbox' name='operation_check'  width='30' style=''/>",
                 width: "30px",
             },
             {
                 field: "Id",
                 title: "Id", width: "auto"
             },
             {
                 field: "FlowName",
                 title: "流程名稱", width: "auto",
                 editor: FlowNameDropDownEditor
             }, {
                 field: "ActivityNo",
                 title: "環節編號", width: "auto"
             }, {
                 field: "Workcenter",
                 title: "關鍵字", width: "auto",
                 filterable: {}
             }, {
                 field: "AuthorDisp",
                 title: "處理人(中文)", width: "auto",
             }, {
                 field: "Author",
                 title: "處理人", width: "auto"
             }, {
                 field: "RoleType",
                 title: "角色類型", width: "100px"
             }
            ];
            UserCL_GlobledataSource = new kendo.data.DataSource({
                transport: {
                    read: {
                        url: getURL,
                        type: "Post",
                        dataType: "json",
                        data: { FlowName: $("#flowName").val() }
                    },
                    //傳參設置
                    parameterMap: function (options, operation) {
                        switch (operation) {
                            case "read":
                                return options;
                                break;
                            default:
                                break;
                        }
    
                    }
                },
                batch: true,
                pageSize: 9999,
                sync: function (e) {
                    console.log("sync complete");
                    UserCL_GlobledataSource.read();
                },
                schema: {
                    model: {
                        id: "Id",
                        fields: fields
                    },
                }
            });
    
    
        }
    
        //綁定數據
        function UserCL_BindData() {
            $("#UserCL_List").kendoGrid({
                dataSource: UserCL_GlobledataSource,
                groupable: true,
                sortable: true,
                filterable: true,
                resizable: true,
                pageable: {
                    refresh: true,
                    pageSizes: true,
                    buttonCount: 5
                },
                selectable: 'row',
                toolbar: [
                             //{ name: "create", text: "添加" },
                             { template: kendo.template($("#UserCL_ToolBar").html()) }
                ],
                editable: {
                    mode: "inline",
                },
                columns: columns
            });
            //隱藏指定的列
            var grid = $("#UserCL_List").data("kendoGrid");
            grid.hideColumn("Id");
        }
    
        //批量刪除
        function UserCL_DeleteManyData() {
            idArr = {};
            if (confirm("确定要删除吗") == true) {
                var arr = $("#UserCL_List").find("input[type=checkbox]:checked").parent().next("td");//获取集合arr
                var length = arr.length;
                for (var i = 0; i < length; i++) {
                    idArr[i] = arr[i].innerText;
                }
                $.ajax({
                    url: deleteManyURL,
                    type: "Post",
                    dataType: "json",
                    data: { IdArr: idArr },
                    success: function (data) {
                        if (data == "" || data == null) {
                            alert("批量刪除異常");
                            return false;
                        }
                        return true;
                    }
                });
            }
            RefreshGrid();
            return false;
        }
    
        //更新KendoGrid
        function UserCL_RefreshGrid() {
            var grid = $("#UserCL_List").data("kendoGrid");
            grid.dataSource.read();
        }
    
        //全選點擊事件的綁定
        $(document).on("click", "#UserCL_check_all", function () {
            //checkbox的點擊事件綁定
            if ($("#UserCL_check_all").is(":checked")) {
                $("[name='operation_check']").each(function () {
                    $(this).prop("checked", true);
                });
            } else {
                $("[name='operation_check']").each(function () {
                    $(this).removeAttr("checked");
                });
            }
        });
    
    </script>
    <script>
        /************LZX_處理人操作**************/
        $(function () {
            GetUserSearchTip();
            
        });
        //處理人模態框的顯示與隱藏
        function ShowHandlerOperation() {
            if ($("#flowName").val() == "" || $("#flowName").val() == null || $("#flowName").val() == "--------------請選擇--------------") {
                alert("流程名字不能為空,請選擇!");
                return false;
            } else {
                var radioVal = $("[name='HandlerOperationType']:checked").val();
                $('#HandlerOperationModel').modal('toggle');
                SetUserRadioType();
                if (radioVal == "更新") {
                    UserCL_InitData();
                    UserCL_BindData();
                    SetUserCLListHeight();
                    $("[name='UserCL_Add']").addClass("hide");
                    $("[name='UserCL_Delete']").addClass("hide");
                    $("[name='UserCL_Refresh']").removeClass("hide");
                    $("[name='UserCL_Update']").removeClass("hide");
                } else if (radioVal == "刪除") {
                    UserCL_InitData();
                    UserCL_BindData();
                    SetUserCLListHeight();
                    $("[name='UserCL_Add']").addClass("hide");
                    $("[name='UserCL_Delete']").removeClass("hide");
                    $("[name='UserCL_Refresh']").removeClass("hide");
                    $("[name='UserCL_Update']").addClass("hide");
                } else if (radioVal == "追加") {
                    $("[name='UserCL_Add']").removeClass("hide");
                    $("[name='UserCL_Delete']").addClass("hide");
                    $("[name='UserCL_Refresh']").addClass("hide");
                    $("[name='UserCL_Update']").addClass("hide");
                }
                //全選
                $("#UserCL_check_all").click();
    
                //KendoGrid 彈框表報過濾input無法輸入處理!
                $("#FilterModel").modal('toggle');
                $("#FilterModel").modal('toggle');
            }
        }
    
        //获取搜索栏的自动提示信息
        function GetUserSearchTip() {
            debugger
            $.ajax({
                url: "/Maintenance/BasicData/GetUserSearchTip",
                data: {},
                async: false,
                type: "post",
                success: function (data) {
                    var UserSelList1 = $("#UserSelList1");
                    var UserSelList2 = $("#UserSelList2");
                    UserSelList1.html();
                    UserSelList2.html();
                    if (data != null && data != "") {
                        for (var i = 0; i < data.length; i++) {
                            UserSelList1.append('<option value="' + data[i] + '">' + data[i] + '</option>');
                            UserSelList2.append('<option value="' + data[i] + '">' + data[i] + '</option>');
    
                        }
                    }
                }
            });
        }
    
        //設置相應單選的樣式
        function SetUserRadioType() {
            debugger
            var radioVal = $("[name='HandlerOperationType']:checked").val();
            //所有隱藏
            $("[name='Update']").addClass("hide");
            //部分顯示
            switch (radioVal) {
                case "追加":
                    $("#UserCL_List").html(null);
                    UserCL_InitData();
                    UserCL_BindData();
                    SetUserCLListHeight();
                    $("[name='UserCL_Add']").removeClass("hide");
                    $("[name='UserCL_Delete']").addClass("hide");
                    $("[name='UserCL_Refresh']").addClass("hide");
                    $("[name='UserCL_Update']").addClass("hide");
                    break;
                case "更新":
                    $("[name='Update']").removeClass("hide");
                    UserCL_InitData();
                    UserCL_BindData();
                    SetUserCLListHeight();
                    $("[name='UserCL_Add']").addClass("hide");
                    $("[name='UserCL_Delete']").addClass("hide");
                    $("[name='UserCL_Refresh']").removeClass("hide");
                    $("[name='UserCL_Update']").removeClass("hide");
                    break;
                case "刪除":
                    UserCL_InitData();
                    UserCL_BindData();
                    SetUserCLListHeight();
                    $("[name='UserCL_Add']").addClass("hide");
                    $("[name='UserCL_Delete']").removeClass("hide");
                    $("[name='UserCL_Refresh']").removeClass("hide");
                    $("[name='UserCL_Update']").addClass("hide");
                    break;
            }
    
        }
    
        //通過 中文名||英文名 獲取User信息
        function GetUserInfoByName(Name) {
            debugger
            var UserName = "";
            $.ajax({
                url: "/Maintenance/BasicData/GetUserInfoByName",
                data: { Name: Name },
                async: false,
                type: "post",
                success: function (data) {
                    if (data.UserName != null && data.UserName != "") {
                        UserName = data.UserName;
                        $("#UserCL_UserName").val(data);
                    }
                }
            });
            return UserName;
        }
    
        //設置表格高度
        function SetUserCLListHeight() {
            $("#UserCL_List").children(".k-grid-content").css("height", "420px");
        }
    
        //確認
        function UserCLBtnClick() {
            var userCL_tbody = $("#UserCL_List").children(".k-grid-content").children(0).children("tbody");//取到表格的tbody
            var userCL_operation_check = $("[name='operation_check']");         //表格中的複選框 判斷:UserCL_operation_check[0].checked
            var radioVal = $("[name='HandlerOperationType']:checked").val();    //單選框的值
            var isCheckNum = 0;                                                 //記錄已成功處理選中數據的數量
            var checkLength = userCL_operation_check.length;                    //已選中的行數
            var userCL_tbody_length = userCL_tbody.children().length;           //表裡面行的數量
            var newUserName = "";                                               //用於存放新的處理人的賬號
            var isUserExist = false;                                            //所選中的行是否有處理人
            var userSel1 = $("#UserSel1").val().trim();                         //舊
            var userSel2 = $("#UserSel2").val().trim();                         //新
            if ($("[name='operation_check']:checked").length > 0) {
                switch (radioVal) {
                    case "追加":
                        if (userSel1 == "" || userSel1 == null) {
                            alert("處理人不能為空!");
                            return false;
                        } else {
                            var addErrorNum = 0;
                            var userName = GetUserInfoByName(userSel1);
                            for (var i = 0; i < userCL_tbody_length; i++) {
                                //中文名正則表達式
                                var regx = /^[\u4E00-\u9FA5]+$/;
    
                                //選中並且無當前需要追加的處理人
                                if (regx.test(userSel1)) {
                                    //input:中文名
                                    if (userCL_operation_check[i].checked && ($("#UserCL_List").data("kendoGrid")._data[i].AuthorDisp.toString().indexOf(userSel1) < 0)) {
                                        if (!AddUserCL(userSel1, $("#UserCL_List").data("kendoGrid")._data[i].ID)) {
                                            //失敗
                                            addErrorNum++;
                                            break;
                                        } else {
                                            //成功
                                            userCL_operation_check.eq(i).prop("checked", false);
                                        }
                                    }
                                } else {
                                    //input:英文賬號
                                    if (userCL_operation_check[i].checked && ($("#UserCL_List").data("kendoGrid")._data[i].Author.toString().indexOf(userSel1) < 0)) {
                                        if (!AddUserCL(userSel1, $("#UserCL_List").data("kendoGrid")._data[i].ID)) {
                                            //失敗
                                            addErrorNum++;
                                            break;
                                        } else {
                                            //成功
                                            userCL_operation_check.eq(i).prop("checked", false);
                                        }
                                    }
                                }
                            }
                            if (addErrorNum == 0) {
                                alert("追加處理人成功!");
                            }
                            UserCL_RefreshGrid();
                        }
                        break;
    
                    case "更新":
                        if (userSel1 == "" || userSel1 == null) {
                            alert("處理人不能為空!");
                            return false;
                        } else if (userSel2 == "" || userSel2 == null) {
                            alert("新處理人不能為空!");
                            return false;
                        } else {
                            var updateErrorNum = 0;
                            for (var i = 0; i < userCL_tbody_length; i++) {
                                //中文名正則表達式
                                var regx = /^[\u4E00-\u9FA5]+$/;
    
                                if (regx.test(userSel1)) {
                                    //input:中文名
                                    if (userCL_operation_check[i].checked && $("#UserCL_List").data("kendoGrid")._data[i].AuthorDisp.toString().indexOf(userSel1) >= 0) {
                                        if (!UpdateUserCL(userSel1, userSel2, $("#UserCL_List").data("kendoGrid")._data[i].ID)) {
                                            //失敗
                                            //alert("更新第" + (i + 1) + "行失敗!");
                                            updateErrorNum++;
                                            break;
                                        }
                                        isUserExist = true;
                                    } else if ((i + 1) == userCL_tbody_length && isUserExist == false) {
                                        updateErrorNum++;
                                        alert("表中無法匹配到處理人:" + userSel1);
                                    }
                                } else {
                                    //input:英文賬號
                                    if (userCL_operation_check[i].checked && $("#UserCL_List").data("kendoGrid")._data[i].Author.toString().indexOf(userSel1) >= 0) {
                                        if (!UpdateUserCL(userSel1, userSel2, $("#UserCL_List").data("kendoGrid")._data[i].ID)) {
                                            //失敗
                                            //alert("更新第" + (i + 1) + "行失敗!");
                                            updateErrorNum++;
                                            break;
                                        }
                                        isUserExist = true;
                                    } else if ((i + 1) == userCL_tbody_length && isUserExist == false) {
                                        updateErrorNum++;
                                        alert("表中無法匹配到處理人:" + userSel1);
                                    }
                                }
    
                            }
                            if (updateErrorNum == 0) {
                                alert("更新處理人成功!");
                            }
                            UserCL_RefreshGrid();
                        }
                        break;
    
                    case "刪除":
    
                        var deleteErrorNum = 0;
                        if (userSel1 == "" || userSel1 == null) {
                            alert("處理人不能為空!");
                            return false;
                        } else {
                            for (var i = 0; i < userCL_tbody_length; i++) {
                                //中文名正則表達式
                                var regx = /^[\u4E00-\u9FA5]+$/;
    
                                if (regx.test(userSel1)) {
                                    //input:中文名
                                    if (userCL_operation_check[i].checked && $("#UserCL_List").data("kendoGrid")._data[i].AuthorDisp.indexOf(userSel1) >= 0) {
                                        if (DeleteUserCL(userSel1, $("#UserCL_List").data("kendoGrid")._data[i].ID) == false) {
                                            //失敗
                                            deleteErrorNum++;
                                            break;
                                        }
                                        isUserExist = true;
                                    } else if ((i + 1) == userCL_tbody_length && isUserExist == false) {
                                        deleteErrorNum++;
                                        alert("表中無法匹配到處理人:" + userSel1);
                                    }
                                } else {
                                    //input:英文賬號
                                    if (userCL_operation_check[i].checked && $("#UserCL_List").data("kendoGrid")._data[i].Author.indexOf(userSel1) >= 0) {
                                        if (DeleteUserCL(userSel1, $("#UserCL_List").data("kendoGrid")._data[i].ID) == false) {
                                            //失敗
                                            deleteErrorNum++;
                                            break;
                                        }
                                        isUserExist = true;
                                    } else if ((i + 1) == userCL_tbody_length && isUserExist == false) {
                                        deleteErrorNum++;
                                        alert("表中無法匹配到處理人:" + userSel1);
                                    }
                                }
                            }
                            if (deleteErrorNum == 0) {
                                //成功
                                alert("刪除處理人" + userSel1 + "成功!");
                            }
                            UserCL_RefreshGrid();
                        }
                        break;
    
                }
            } else {
                alert("請勾選需要處理的行!");
            }
            return false;
        }
    
        //更新
        function UpdateUserCL(OldName, NewName, ID) {
            var state = false;
            $.ajax({
                url: "/Maintenance/BasicData/UpdateUserCL",
                data: { OldName: OldName, NewName: NewName, ID: ID },
                async: false,
                type: "post",
                success: function (data) {
                    if (data != "success") {
                        alert("處理人" + OldName + ":" + data);
                        state = false;
                    } else if (data == "success") {
                        state = true;
                    }
                }
            });
            return state;
        }
    
        //刪除
        function DeleteUserCL(Name, ID) {
            debugger
            var state = false;
            $.ajax({
                url: "/Maintenance/BasicData/DeleteUserCL",
                data: { Name: Name, ID: ID },
                async: false,
                type: "post",
                success: function (data) {
                    if (data != "success") {
                        alert(data);
                        state = false;
                    } else if (data == "success") {
                        state = true;
                    }
                }
            });
            return state;
        }
    
        //追加
        function AddUserCL(Name, ID) {
            debugger
            var state = false;
            $.ajax({
                url: "/Maintenance/BasicData/AddUserCL",
                data: { Name: Name, ID: ID },
                async: false,
                type: "post",
                success: function (data) {
                    if (data != "success") {
                        alert(data);
                        state = false;
                    } else if (data == "success") {
                        state = true;
                    }
                }
            });
            return state;
        }
    
        //保存
        function SaveUserCL() {
            var date = new Date();
            var currentTime = date.Format("yyyy-MM-dd hh:mm:ss");
            var dataGrid = $("#UserCL_List").data("kendoGrid");
            var data = dataGrid._data;
            var list = [];
            if (data.length == 0) {
                kendo.ui.showInfoDialog({
                    message: "请添加行并输入数据!"
                });
            } else {
    
                list.push({
                    "ID": data[0].ID,
                    "FlowName": data[0].FlowName,
                    "ActivityNo": data[0].ActivityNo,
                    "Workcenter": data[0].Workcenter,
                    "RoleID": data[0].RoleID,
                    "RoleType": data[0].RoleType,
                    "AuthorDisp": data[0].AuthorDisp,
                    "Author": data[0].Author,
                    "Operator": data[0].Operator,
                    "OperatorDate": currentTime
                });
                if (list[0].ActivityNo == "" || list[0].ActivityNo == null) {
                    alert("環節編號不能為空!");
                    return false;
                } else if (list[0].Workcenter == "" || list[0].Workcenter == null) {
                    alert("關鍵字不能為空!");
                    return false;
                } else if (list[0].AuthorDisp == "" || list[0].AuthorDisp == null) {
                    alert("處理人(中文)不能為空!");
                    return false;
                } else if (list[0].Author == "" || list[0].Author == null || list[0].Author == "false") {
                    alert("處理人不能為空!");
                    return false;
                } else {
                    $.ajax({
                        url: "/Maintenance/BasicData/CreateFlowWorkcenter",
                        data: { model: JSON.stringify(list) },
                        async: false,
                        type: "post",
                        success: function (data) {
                            alert(data.Status);
                            SetUserRadioType();
                        }
                    });
                }
            }
    
        }
    
        //刷新
        function UserCL_RefreshGrid() {
            refreshGridData("UserCL_List");
            SetUserCLListHeight();
        }
    
        //设置日期返回格式 2019-03-29 11:15:53
        Date.prototype.Format = function (format) {
            var o = {
                "M+": this.getMonth() + 1, //month 
                "d+": this.getDate(), //day 
                "h+": this.getHours(), //hour 
                "m+": this.getMinutes(), //minute 
                "s+": this.getSeconds(), //second 
                "q+": Math.floor((this.getMonth() + 3) / 3), //quarter 
                "S": this.getMilliseconds() //millisecond 
            }
            if (/(y+)/.test(format)) {
                format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
            }
            for (var k in o) {
                if (new RegExp("(" + k + ")").test(format)) {
                    format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
                }
            }
            return format;
        }
    
    </script>

     

    展开全文
  • Selenium Grid使用

    万次阅读 2019-06-14 13:20:31
    什么是Selenium Grid Selenium Grid是Selenium套件的一部分,它专门用于并行运行多个测试用例在不同的浏览器、操作系统和机器上。 Selenium Grid有两个版本——老版本Grid 1和新版本Grid 2。我们只对新版本做介绍,...
  • c# PropertyGrid中复杂类型自定义显示(装)自用
  • 前端基础知识(grid布局)

    千次阅读 多人点赞 2019-03-19 22:16:31
    参考链接 grid布局简介 CSS Grid(网格)布局,是一个二维的基于网络的布局系统。Flexbox 的出现很大程度上改善了我们的布局方式,但它的目的是为了解决更简单的一维...采用grid布局的元素,被称为grid容器(grid...
  • WPF经典教程之Grid、UniformGrid布局

    千次下载 热门讨论 2014-10-05 00:39:21
    Grid UniformGrid容器 一、Grid Grid是以表格形式组织控件的一种布局方式,与Java AWT中的GridLayout类似,但区别在于..... 更多WPF资源:http://cleopard.download.csdn.net/
  • pytorch F.affine_grid F.grid_sample探究

    千次阅读 2020-08-27 17:20:03
    在pytorch框架中, F.affine_grid 与 F.grid_sample(torch.nn.functional as F)联合使用来对图像进行变形。 F.affine_grid 根据形变参数产生sampling grid,F.grid_sample根据sampling grid对图像进行变形。 需要...
  • wxPython Grid 表格控件的使用

    千次阅读 2020-01-12 16:05:29
    因工作原因使用了一下 ...这个代码展示了 Grid 的使用,可以“增删改”,按列排序,隐藏某一列的显示(就像在 Excel 里为了看东西方便)。界面设计可以先用 wxFormBuilder 设计好,把代码 copy 过来。有些问题不好...
  • html中的grid布局

    千次阅读 2020-06-16 22:53:51
    3、grid-template-columns 指定多少列,各占多少,repeat(num,px/fr/rem)函数可快熟设置多少列多少宽 4、grid-row/columns-gap 设置行间距或列间距 5、grid-auto-rows 设置div高度,指定为100px,则每个div都为100...
  • CSS栅格布局grid详解

    千次阅读 2019-11-12 14:48:35
    栅格布局分为常规栅格和行内栅格,值分别为display:grid;和display:inline-grid;但是大多数栅格布局都是块级的。这里有一个需要注意的是,如果我们给一个标签设置了栅格布局,有的css属性和功能也就无法使用了,...
  • 轻松上手CSS Grid网格布局

    千次阅读 多人点赞 2019-07-05 22:18:18
    今天刚好要做一个好多div格子错落组成的布局,不是田字格,不是九宫格,12个格子这样子,看起来...css grid好像就是长这样子的?会不会很简单呢?反正也不熟,实在不行就当学习了。说干就干,说不定能偷点懒呢哈哈~
  • 锐浪Grid++Report报表Web(Java)版使用手册。 非常详细。 内容列表: 1.报表设计器安装文件 2.报表设计器的使用 3.报表页面和JS文件及使用手册 4.报表后台代码的文件及使用手册(整合Struts) (附加.html,.js,.java,....
  • Grid Generation Methods(网格生成方法) Grid Generation Methods 2nd Edition Dec 2009 Grid Generation Methods 2nd Edition This book is an introduction to structured and unstructured grid methods ...
  • css display:grid布局

    万次阅读 2018-05-10 13:12:32
    简介CSS Grid布局 (又名"网格"),是一个基于二维网格布局的系统,主要目的是改变我们基于网格设计的用户接口方式。如我们所知,CSS 总是用于网页的样式设置,但它并没有起到很好的作用。刚开始的时候...
  • AgGrid框架的使用感受及前景分析

    千次阅读 2019-12-21 13:36:12
    免责声明:文章源于本人闲情雅致,没有任何广告意图我向来是不屑于使用前端框架的,最多用一些ui组件,但是ag-grid这个框架太TM好用了。这篇文章介绍下aggrid的一些哲学思想和我的使...
  • 关于grid_search中param_grid可以选取哪些参数(以keras为例) 最近在学习调参时看到了 grid_search (也就是网格搜索算法) https://cloud.tencent.com/developer/article/1447855 细节可以见上面这篇文章 官方...
  • css grid 深度解析

    千次阅读 2018-03-24 14:21:03
    自从去年年半年开始,CSS Grid布局的相关教程在互联网上就铺天盖地,可谓是声势浩大。就针对于Web布局而言,个人认为Grid布局将是Web布局的神器,它改变了以往任何一种布局方式或者方法。不管以前的采用什么布局方法...
  • Grid++Report 5.6 去水印版

    热门讨论 2013-04-09 23:35:03
    Grid++Report 5.6 去水印版
  • CSS进阶之关于网格布局(Grid) 你了解哪些

    千次阅读 多人点赞 2021-05-15 17:19:33
    CSS 进阶:网格布局(Grid)及其基本属性 网格布局(Grid)是最强大的 CSS 布局方案。起初我也认为 flex 布局就可以完成绝大部分布局场景,但谁不希望用更直观、更简洁的方式来布局自己的网页呢,于是 Grid 就是...
  • Python Tkinter Grid布局管理器详解

    千次阅读 2018-12-24 14:34:43
    Grid(网格)布局管理器会将控件放置到一个二维的表格里。主控件被分割成一系列的行和列,表格中的每个单元(cell)都可以放置一个控件。         注意:不要试图在一个主窗口中混合使用pack和grid (1)...
  • GridStudio是一位外国小哥开源到Git的Web应用程序。他集成了Python优秀的科学计算编程及数据csv表格化的能力。准备条件:虚拟机+PC(任意系统)。本篇只提供从0-1的流程思路,具体操作需要读者自己实操!
  • display:grid; 布局

    千次阅读 2019-06-12 19:57:16
    CSS一直用来布局网页,但一直都... Flexbox的出现在一定程度上解决了这个问题,但是它的目的是为了更简单的一维布局,而不是复杂的二维布局(Flexbox和Grid实际上一起工作得很好)。 只要我们一直在制作网站,我们就...
  • Laravel-admin grid 列的使用与显示

    千次阅读 2019-11-25 16:29:34
    model-grid 内置了很多对于列的操作方法,可以通过这些方法很灵活的操作列数据。 列属性 列对象的setAttributes()方法用来给当前这一列的每一行添加HTML属性, 比较有用的一个场景是给当前列增加样式 $grid->...
  • vue-grid-layout 的使用

    千次阅读 2021-01-04 17:38:50
    vue-grid-layout中文文档 我需要用到这里面的可拖拽的效果。 碰到的问题 在安装完这个插件之后,在IE上无法打开,并报错缺少:,最终是下面这篇文章解决问题 Vue项目下IE报错 SCRIPT1003: 缺少 ‘:’,导致页面空白...
  • griddatepickercustomfiltering,动态设置显示kendoui grid控件某一列的格式
  • ag-grid在Vue项目中的基本使用

    万次阅读 2018-11-01 11:41:38
    ag-grid官网 1、安装 npm install ag-grid-community ag-grid-vue --save-dev 2、在main.js中引入ag-grid的样式文件 // 引入ag-grid的样式文件 import '../node_modules/ag-grid-community/dist/styles/ag-grid...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 394,814
精华内容 157,925
关键字:

grid