整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

下一代 CSS:@container

下一代 CSS:@container

章转自掘金@优弧 https://juejin.cn/post/7044181023696879652

Chrome 正在试验 CSS @container 查询器功能,这是由 Oddbird 的 Miriam Suzanne 和一群网络平台开发者支持的 CSS 工作组 Containment Level 3 规范。@container 查询器使我们能够根据父容器的大小来设置元素的样式

你可以把这些想象成一个媒体查询(@media),但不是依靠 viewport 来调整样式,而是你的目标元素的父容器会调整这些样式。

容器查询将是自 CSS3 以来 Web 样式的最大变化,将会改变我们对“响应式设计”含义的看法。

viewport 和用户代理不再是我们创建响应式布局和 UI 样式的唯一目标。通过容器查询,元素将能够定位自己的父元素并相应地应用自己的样式。这意味着存在于侧边栏、主体或头图中的相同元素可能会根据其可用大小和动态看起来完全不同。

@container 实例

在本示例中,我在父级中使用了两张带有以下标记的卡片:

<div class="card-container">
    <div class="card">
        <figure> ...</figure>
        <div>
            <div class="meta">
                <h2>...</h2>
                <span class="time">...</span>
            </div>
            <div class="notes">
                <p class="desc">...</p>
                <div class="links">...</div>
            </div>
            <button>...</button>
        </div>
    </div>
</div>
复制代码

然后,我在将查询容器样式的父级(.card-container)上设置 Containment(contain 属性)。我还在 .card-container 的父级上设置了一个相对网格布局,因此它的 inline-size 将根据该网格而改变。这就是我使用 @container 查询的内容:

.card-container {
  contain: layout inline-size;
  width: 100%;
}
复制代码

现在,我可以查询容器样式来调整样式!这与使用基于宽度的媒体查询设置样式的方式非常相似,当元素小于指定尺寸时使用 max-width 设置样式,当元素大于指定尺寸时使用 min-width。

/* 当父容器宽度小于 850px,
不再显示 .links
并且减小 .time 字体尺寸 */

@container (max-width: 850px) {
  .links {
    display: none;
  }

  .time {
    font-size: 1.25rem;
  }

  /* ... */
}

/* 当父容器宽度小于 650px 时,
减小 .card 元素之间的网格间距到 1rem */

@container (max-width: 650px) {
  .card {
    gap: 1rem;
  }

  /* ... */
}
复制代码

容器查询 + 媒体查询

容器查询的最佳功能之一是能够将 微观上的布局宏观上的布局 分开。我们可以使用容器查询设置单个元素的样式,创建细微的微观布局,并使用媒体查询(宏布局)设置整个页面布局的样式。这创造了一个新的控制水平,使界面更具响应性。

这是另一个示例。它展示了使用媒体查询进行宏观布局(即日历从单面板到多面板)和微观布局(即日期布局/大小和事件边距/大小移动),以创建一个漂亮的和谐的查询。

容器查询 + CSS 网格

我个人最喜欢的查看容器查询影响的方法之一是查看它们在网格中的工作方式。以下面的植物贸易 UI 为例:

本网站根本没有使用媒体查询。相反,我们只使用容器查询和 CSS 网格来在不同的视图中显示购物卡组件。

在产品网格中,布局使用了 grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); 标记创建。这将创建一个布局,告诉卡片占用可用的小数空间,直到它们的大小达到 230px,然后下一格切换到下一行。你可以在 1linelayouts.com 上查看更多网格技巧。

然后,我们有一个容器查询,当卡片宽度小于 350px 时,它会将卡片样式设置为采用垂直块布局,并通过应用 display: flex(默认情况下具有内联流)转换为水平内联布局。

@container (min-width: 350px) {
  .product-container {
    padding: 0.5rem 0 0;
    display: flex;
  }

  /* ... */
}
复制代码

这意味着每张卡片拥有自己的响应式样式。这是我们使用产品网格创建宏观布局以及使用产品卡片创建微观布局的另一个示例,酷毙了!

用法

为了使用@container,首先需要创建一个具有 Containment 的父元素。为此,我们需要在父级上设置 contain: layout inline-size。因为我们目前只能将容器查询应用于内联轴,所以我们只可以使用 inline-size。这也可以防止我们的布局在块方向上中断。

设置 contain: layout inline-size 会创建一个新的 Containment 块 和新的块格式上下文,让浏览器将其与布局的其余部分分开,现在我们就可以使用容器查询了!

限制

目前,您不能使用基于高度的容器查询,只能使用块轴方向上的查询。为了让网格子元素与 @container 一起工作,我们需要添加一个容器元素。尽管如此,添加容器仍可让我们获得所需的效果。

试试看

您现在可以在 Chromium 中试验 @container 属性,方法是导航到:Chrome Canary 中的 chrome://flags 页面并打开 #experimental-container-queries 标志。

,Mayuyu来介绍Go语言中一个重要的东西,叫做container。具体源码可以参考Go语言的源代码,如下

路径:/usr/local/go/src/pkg/container

Github上的路径为:https://github.com/astaxie/gopkg/tree/master/container

container的结构如下

可以看出包含三部分:heap,list和ring。下面分别介绍

1. heap

heap即为堆,是一种常用的数据结构,在源码里面,提供了接口,在实际使用时需要实现。

下面是一个关于heap使用的实例。

代码:

package main

import (
    "fmt"
    "container/heap"    
)

//heap提供了接口,需要自己实现如下方法
type Heap []int

//构造的是小顶堆,大顶堆只需要改一下下面的符号
func (h *Heap) Less(i, j int) bool {
    return (*h)[i] < (*h)[j]
}

func (h *Heap) Swap(i, j int) {
    (*h)[i], (*h)[j]=(*h)[j], (*h)[i]
}

func (h *Heap) Len() int {
    return len(*h)
}

func (h *Heap) Pop() interface{} {
    x :=(*h)[h.Len() - 1]
    *h=(*h)[: h.Len() - 1]
    return x
}

func (h *Heap) Push(x interface{}) {
    *h=append(*h, x.(int))
}

func (h *Heap) Remove(idx int) interface{} {
    h.Swap(idx, h.Len() - 1)
    return h.Pop()
}

func main(){
    
    //创建一个heap
    h :=&Heap{}
    
    heap.Init(h)
    //向heap中插入元素
    h.Push(5)
    h.Push(2)
    h.Push(1)
    h.Push(8)
    h.Push(4)
    h.Push(6)
    h.Push(2)

    //输出heap中的元素,相当于一个数组,原始数组
    fmt.Println(h)

    //这里必须要reheapify,建立好堆了
    heap.Init(h)

    //小顶堆对应的元素在数组中的位置
    fmt.Println(h)

    //移除下标为5的元素,下标从0开始
    h.Remove(5)

    //按照堆的形式输出
    for h.Len() > 0 {
        fmt.Printf("%d ", heap.Pop(h))
    }
    fmt.Println()
}

2. list

list类型是双向链表,具体用法如下

代码:

package main

import (
    "fmt"
    "container/list"    
)

func main(){

    //创建一个双向链表
    ls :=list.New()

    //向双向链表中插入26个小写字母
    for i :=97; i < 123; i++ {
        ls.PushFront(i)     //PushFront()代表从头部插入,同样PushBack()代表从尾部插入
    }

    //遍历双向链表ls中的所有字母
    for it :=ls.Front(); it !=nil; it=it.Next() {
        fmt.Printf("%c ", it.Value)
    }
    fmt.Println()
}

3. ring

ring是一个环形链表,具体用法可以参考如下代码

代码:

package main

import (
    "fmt"
    "container/ring"    //闭环包引入,详见/usr/local/go/src/pkg/container/ring
)

func main(){
    //创建10个元素的闭环
    r :=ring.New(10)

    //给闭环中的元素赋值
    for i :=1; i <=r.Len(); i++ {
        r.Value=i
        r=r.Next()
    }

    //循环打印闭环中的元素值
    r.Do(
        func(p interface{}){
            println(p)
        })
    
    //获得当前元素之后的第5个元素
    r5 :=r.Move(5)
    fmt.Println(r5)
    fmt.Println(r)

    //链接当前元素r与r5,相当于删除了r与r5之间的元素
    r1 :=r.Link(r5)
    fmt.Println(r1)
    fmt.Println(r)
}

本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/p/13475647.html


个网页前端是由HTML DOM与嵌套组合形成视图结加上 CSS 样式的修饰形成视图,由JavaScript 接受用户的交互请求,以事件机制来响应用户交互操作而形成的。CSS是前台页面形式最重要的部分,它负责控制DOM元素的页面布局和颜色、大小的属性。

在CSS中有一著名的盒子模型理论,可以用它来控制DOM的位置。基于div+css技术的“盒子模型”的出现大大代替了传统的table表格嵌套。

虽然其十分好用,但是对于很多新手来说,却很难搞清楚它几个属性和内容之间的联系个区别。

盒子模型概念

所有页面的元素都可以看做一个盒子,占据着一定的页面空间。一般来说这些被占据的空间往往会比单纯的内容要大。因此,可以通过盒子的边框和距离等参数来控制内容的位置。

Div+CSS 盒子模型

说明:

1、Margin:中文叫外边距,主要作用是控制边框外(Border以外)的区域,外边距是透明的

2、Border:中文叫边框,是围绕在内边距(Padding)和内容外的边框。注意,它不是透明的

3、Padding:中文叫内边距,控制内容周围的区域,内边距是透明的

4、Content:内容,盒子的内容,显示文本和图像。

5、在Css文件中设置的Div的Css.width和Css. height就是内容的宽和高。

6、盒子实际尺寸有可能大于内容尺寸:

盒子模型的总宽度等于content(宽)+padding(左右)+border(左右)+margin(左右);

盒子模型的总高度等于content(高)+padding(上下)+border(上下)+margin(上下);

实例演示--原始样式

接下来通过实例演示的方式来一一讲解Margin、Border、Padding的作用和区别。

页面如图所示:


原始样式

代码:

HTML:
<body>
    <div class="TsetUpper"></div>
    <div class="TsetMiddle"></div>
    <div class="TsetDown"></div>
</body>
CSS:
.TsetUpper{
	width: 400px;
	height: 200px;
	background-color: black;
	position: relative;
	margin: auto;
	text-align: center;
}
.TsetMiddle{
	width: 600px;
	height: 200px;
	background-color: red;
	position: relative;
	margin: auto;
}
.TsetDown{
	width: 400px;
	height: 200px;
	background-color: black;
	position: relative;
	margin: auto;
	text-align: center;
}

Border

元素边框:我们可以在CSS边框属性中设置元素边框的样式和颜色。

按如下代码设置Div(TsetMiddle)的Border(边框):

border-style:solid;
border-width: 10px;
border-color: aqua;

刷新页面如下图:此时TsetMiddle这个盒子的总宽度已经变成200+30+30了,而且可以设置其底色和线条样式。

Border

Margin

margin 控制周围的元素区域。margin 没有背景颜色,是完全透明的。通过margin可以控制元素与四周元素的空隙距离;

按如下代码设置Div(TsetMiddle)的margin(外边距):

margin: 30px auto;

刷新页面如下图:此时TsetMiddle这个盒子的总宽度已经变成200+30(Border)+30(Margin)+30(Border)+30(Margin)了。

Margin

Padding

Padding:当元素的 padding(填充)内边距被清除时,所释放的区域将会受到元素背景颜色的填充。

按如下代码设置Div(TsetMiddle)的margin(外边距):

padding: 30px;

刷新页面如下图:此时TsetMiddle这个盒子的总宽度已经变成200+30(Padding)+30(Border)+30(Margin)+30(Padding)+30(Border)+30(Margin)了。

Padding

总结

1、各属性的值可以用px为单位,也可以用em,百分比等。

2、可以利用盒子的各种属性,调整其内容在父容器中的位置。