常,我们希望限制元素相对于其父元素的宽度,同时使其具有动态性。因此,有一个基础宽度或高度的能力,使其扩展的基础上,可用的空间。比如说,我们有一个按钮,它的宽度应该是最小的,不应该低于它的宽度。这就是最大和最小属性变得方便的地方。
在本文中,我们将详细介绍CSS的最大和最小宽度和高度属性,并使用可能的用例和技巧详细解释每一个属性。
首先要讨论的是与宽度相关的属性。我们有min-width和max-width,它们中的每一个都很重要,都有自己的用例。
设置min-width的值时,其好处在于防止width属性使用的值变得小于min-width的指定值。 请注意,min-width的默认值是auto,它解析为0。
让我们举一个基本的例子来说明这一点。
我们有一个按钮,里面有一个变化的文本。文本的范围可能从一个单词到多个单词。为了确保即使只有一个单词,它也有最小宽度,应该使用min-width。
最小宽度为100px,这样即使按钮的内容很短,比如Done,或者只有一个图标,它仍然足够大,可以被注意到。在使用阿拉伯语等多语言网站时,这一点非常重要。 考虑以下来自Twitter的示例:
在以前的情况下,按钮上带有单词“تم”,表示完成。 按钮的宽度太小,因此在后面的案例中,我增加了它的最小宽度。
在内容较长的情况下,min-width可以扩展按钮的宽度,而水平方向上的padding应该被添加,以实现一个合适的外观按钮。
在设置max-width值时,它的好处在于防止width属性使用的值超过max-width的指定值。max-width的默认值是none。
max-width的常见且简单的用例是将其与图像一起使用。 考虑以下示例:
图像比它的父元素大。通过使用max-width: 100%,图像的宽度不会超过其父图像的宽度。如果图像比父图像小,则max-width: 100%不会对图像产生实际影响,因为它比父图像小。
当min-width和max-width都用于一个元素时,它们中的哪一个将覆盖另一个?换句话说,哪个优先级更高?
html
<div class="wrapper">
<div class="sub"></div>
</div>
css
.sub {
width: 100px;
min-width: 50%;
max-width: 100%;
}
初始width值为100px,并在其上加上min-width和max-width值。 结果是元素宽度未超过其包含的块/父元素的50%。
除了最小和最大宽度属性外,我们还具有与高度相同的属性。
设置min-height的值时,其好处在于防止使用的height属性值变得小于min-height的指定值。 请注意,最小高度的默认值为auto,它解析为0。
我们用一个简单的例子来演示一下。
我们有一个带有描述文本的部分。目标是为section设置一个最小高度,这样它就可以处理短或长内容。考虑下面的基本情况
.sub {
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
min-height: 100px;
color: #fff;
background: #3c78dB;
}
最小高度为100px,使用flexbox时,内容水平和垂直居中。 如果内容更长,会发生什么? 例如一段?
是的,你猜对了!section的高度将展开以包含新内容。有了它,我们就可以构建灵活的组件,并对其内容做出响应。
事例源码:https://codepen.io/shadeed/pen/cfb600cf30acdae9cf6f9cb5347a37cf
在设置max-height值时,它的好处在于防止height属性使用的值超过max-height的指定值。注意,max-height的默认值是none。
考虑下面的示例,其中我为内容设置了max-height。 但是,因为它大于指定的空间,所以会发生溢出。 因此,文本超出了其父边界。
我们将介绍min-width,min-height,max-width和max-height的一些常见和不常见的用例。
当有一个标签列表时,建议限制一个标签的最小宽度,这样如果它的内容很短,它的外观就不会受到影响。
通过具有这种灵活性,无论内容有多短,标签都将看起来不错。 但是,如果内容作者输入了一个非常长的标签名称,而他使用的内容管理系统没有标签的最大字符长度,将会发生什么情况呢? 我们也可以使用max-width。
.c-tag {
display: inline-block;
min-width: 100px;
max-width: 250px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
/*Other styles*/
}
通过使用max-width,标签宽度将被限制为特定值。 但是,这还不够,标签名称应被截断。
事例地址:https://codepen.io/shadeed/pen/320e42b7ad75c438a9e633417d737d16
对于按钮的最小值和最大值有不同的用例,因为按钮组件有多种变体。考虑下面的图:
请注意,按钮的“Get”宽度太小。 如果不设置最小宽度,则由于任何原因而没有文本时,情况可能会变得更糟。 在这种情况下,设置最小宽度很重要。
min-width的默认值是auto,它被计算为0。当一个元素是一个flex项时,min-width的值不会计算为零。flex 项目的最小大小等于其内容的大小。
根据CSSWG:
默认情况下,flex项目不会缩小到它们的最小内容大小(最长单词或固定大小元素的长度)以下。要更改此设置,请设置min-width或 min-height属性。
考虑下面的例子
这个人的名字有一个很长的单词,这导致了溢出和水平滚动。尽管如此,我还是在标题中添加了下面的CSS来截断它
.c-person__name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
由于title是flex项目,因此解决方案是重置min-width并将其强制为零。
.c-person__name {
/*Other styles*/
min-width: 0;
}
下面是修复后的样子
根据CSSWG:
在弹性项目的主轴上可见溢出的项目上,当在弹性项目的主轴min-size属性中指定时,指定自动最小尺寸。
意味着,将overflow设置为visible值以外的值会导致min-width被计算为0,这解决了我们不设置min-width: 0的问题。
事例源码:https://codepen.io/shadeed/pen/398ccffcd437a2fb042f5ce3bdd68c57
虽然与min-width相比,这是一个不太常见的问题,但是它可能发生。 只是为了确认,问题与不能少于其内容的弹性项目有关。 结果min-height值被设置为与内容一样长。
考虑以下示例:
用红色表示的文本应该在父文本中裁剪。因为面板主体是一个flex项目,所以它的min-height与它的内容相等。为了防止这种情况,我们应该重新设置最小高度值。看看HTML和CSS是怎么样的。
HTML
<div class="c-panel">
<h2 class="c-panel__title"><!-- Title --></h2>
<div class="c-panel__body">
<div class="c-panel__content"><!-- Content --></div>
</div>
</div>
CSS
.c-panel {
display: flex;
flex-direction: column;
height: 180px;
}
.c-panel__body {
min-height: 0;
}
.c-panel__content {
overflow-y: scroll;
height: 100%;
}
通过向面板主体添加min-height: 0,这将重置该属性,并且现在应该可以正常工作。
事例源码:https://codepen.io/shadeed/pen/dea75b84b1fcfd03e5c21173a40afc20?editors=0100
在某些情况下,我们有一个最小宽度的元素,但同时,它没有最大宽度。这可能会导致组件太宽,而我们并不想这样做。考虑以下示例
由于宽度是以像素为单位定义的,因此不能保证上面的方法适用于移动视口。为了解决这个问题,我们可以使用百分比来代替像素作为最小和最大属性。考虑下面这个具有article主体的示例。
我为图像添加了以下CSS:
img {
min-width: 35%;
max-width: 70%;
}
事例源码:https://codepen.io/shadeed/pen/11f49fd1a35ad06ce241bee17c3d3124
#### 页面包装器/容器
最常用的`max-width`用例之一是页面包装器或容器。通过向页面添加最大宽度,我们可以确保内容对用户来说是可读的、易于浏览的。
下面是一个包装器的例子,它是居中的,左右两边有水平的填充。
.wrapper {
max-width: 1170px;
padding-left: 16px;
padding-right: 16px;
margin-left: auto;
margin-right: auto;
}
ch 是一个相对于数字0的大小,1ch 就是数字 0 的宽度。如定义一个3ch的宽度,那么就只能装下 3个0。
<!-- HTML代码 -->
<div>0000</div>
/* CSS代码 */
div {
width: 3ch;
background: powderblue;
}
在前面的wrapper元素示例中,我们可以利用ch单元,因为它是一个article 主体。
.wrapper {
max-width: 70ch;
/* Other styles */
}
在某些情况下,我们面临着使手风琴或移动菜单具有意想不到的内容高度的挑战。在这种情况下,max-height可能是一个很好的解决方案。
请考虑以下示例:
单击菜单按钮后,菜单应随动画从上到下滑动。 如果没有固定的高度(不建议这样做),除非使用JavaScript,否则这是不可能的。 但是,对于max-height,这是可能的。 想法是为高度添加一个较大的值,例如max-height:20rem,可能无法达到,然后我们可以使用动画从max-height: 0变换到max-height: 20rem。
.c-nav {
max-height: 0;
overflow: hidden;
transition: 0.3s linear;
}
.c-nav.is-active {
max-height: 22rem;
}
点击菜单按钮可以看到动画的运行。
事例源码:https://codepen.io/shadeed/pen/164c7ef67f5d4541bddb8bc12b2772da
一般来说,我不喜欢给元素添加固定的高度。我觉得这样做,会破坏流式布局的结构。但有些情况设置固定高度却很有用。
考虑下面的例子,在这里我们有一个设置了固定高度的hero部分。
是,当内容较长时,它会溢出并离开hero包装器,这可不太好。
为了预先解决这个问题,我们可以使用min-height来代替height。我们可以用这种方式先解决问题,尽管这可能会导致页面看起来很奇怪,但是我认为应该首先防止内容管理系统(CMS)中发生这样的事情。这样,问题就解决了,看起来也不错。
内容溢出的问题不仅在于内容是否大于固定的hero 高度。它可以发生在屏幕大小调整作为文本换行的结果。
如果改用min-height,则上述情况根本不会发生。
对于模态组件,它需要最小和最大宽度,以便可以适应移动设备到PC的屏幕上的适应。
思路1
.c-modal__body {
width: 600px;
max-width: 100%;
}
思路2
.c-modal__body {
width: 100%;
max-width: 600px;
}
对于我来说,我更喜欢第二个思路,因为我只需要定义max-width: 600px。modal是一个<div>元素,因此它已经具有其父元素的100%宽度,对吗?
考虑下面为模态设计简化的测试案例。 请注意,如果可用视口空间不足,则宽度如何更改为其父级的100%。
事例源码:https://codepen.io/shadeed/pen/5dcb1c4c6773cc3a97a766c327c36443
当一个网站的内容不够长,它希望看到页脚粘到底部。让我们用一个可视化的例子来更好地展示这一点。
请注意,页脚未粘贴在浏览器窗口的末尾。 那是因为内容不足以达到浏览器窗口高度的长度。 修复后,其外观应如下所示:
首先,将body元素作为flexbox容器,然后将其最小高度设置为视口高度的100%。
事例源码:https://codepen.io/shadeed/pen/aeb14f2819b9cc4805275b88c2d55645?editors=1100
为了使比例容器能够根据视口大小进行响应缩放,引入了padding hack。 现在,我们可以通过组合CSS中的视口单位和最大宽度/高度来模仿相同的行为。
我们有一个尺寸为644 * 1000像素的图像。 为了使其流畅,我们需要以下内容:
人才们的 【三连】 就是小智不断分享的最大动力,如果本篇博客有任何错误和建议,欢迎人才们留言,最后,谢谢大家的观看。
作者:Ahmad shaded 译者:前端小智 来源:sitepoint 原文:https://www.impressivewebs.com/min-max-width-height-css
本文中,我们看看开发人员使用JavaScript和正则表达式在他的网站上缩小元素的过程。阅读更多!
我创建了一个ShareButton Web组件,虽然效果并不好,但我喜欢它,并在创建Web组件时了解了很多关于Web组件的生态系统。
这个项目的主要目标是将所有内容封装在一个ES6类中。我这样做是因为我不想从我的元素发出任何非开发人员控制的Web请求。我认为我已经实现了这个目标,但是代码的可读性受损,因为我不得不内联定义元素的HTML和CSS。
它看起来很像这样:
const overlay = document.createElement('div');
overlay.id = 'overlay';
overlay.innerHTML = `
<div id="urlbar">
<input type="url" id="url" />
<button id="copy" aria-label="Copy to clipboard">
<slot name="clipboard">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M16 1H4C3 1 2 2 2 3v14h2V3h12V1zm3 4H8C7 5 6 6 6 7v14c0 1 1 2 2 2h11c1 0 2-1 2-2V7c0-1-1-2-2-2zm0 16H8V7h11v14z"/>
</svg>
</slot>
</button>
<button id="mailto" aria-lable="Mail to">
<slot name="mailto">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 id="android" aria-label="Share on Android">
<slot name="android">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M6 18c0 .6.5 1 1 1h1v3.5c0 .8.7 1.5 1.5 1.5s1.5-.7 1.5-1.5V19h2v3.5c0 .8.7 1.5 1.5 1.5s1.5-.7 1.5-1.5V19h1c.6 0 1-.5 1-1V8H6v10zM3.5 8C2.7 8 2 8.7 2 9.5v7c0 .8.7 1.5 1.5 1.5S5 17.3 5 16.5v-7C5 8.7 4.3 8 3.5 8zm17 0c-.8 0-1.5.7-1.5 1.5v7c0 .8.7 1.5 1.5 1.5s1.5-.7 1.5-1.5v-7c0-.8-.7-1.5-1.5-1.5zm-5-5.8L16.8 1c.2-.3.2-.6 0-.8-.2-.2-.5-.2-.7 0l-1.3 1.4C13.7 1.2 13 1 12 1c-1 0-2 .2-2.7.6L7.8 0H7v1l1.5 1C7 3.2 6 5 6 7h12c0-2-1-3.8-2.5-4.8zM10 5H9V4h1v1zm5 0h-1V4h1v1z"/>
</svg>
</slot>
</button>
</div>
<div class="buttons">
<slot name="buttons"></slot>
</div>`;
这并不坏,但这也意味着我的元素不可能被最大限度地缩小。事实上,除了聚合物工具(专注于解析HTML导入)之外,我找不到任何有关部署经过优化的自定义元素(如果我错了,请告诉我)的工具或指导。
我不认为作为一名元素作者,我应该将整个构建链和工具生态系统强加给我的元素用户。我也相信我应该能够为用户提供尽可能小的内置文件,为用户提供默认的快速体验,而无需跳过这些环节。
我不希望任何超级复杂的基础架构将单独的CSS和JS文件合并到一个输出中; 我只想让自定义元素的开发版本与我部署的版本完全相同......只是更小。
我希望通过这篇文章,至少你可以看到我的过程,并了解我如何缩小我的自定义元素。
我用过babili。这是一个压缩ES6类的非常整洁的工具。它仍然是试验性的,但我没有遇到任何重大问题。
npm install babili --save-dev
您可以通过许多不同的方式运行它,我选择通过STDOUT将数据传输到它。
cat xyz | babili
这很有效,但它将字符串留下,因为它假定(正确)这些字符串的输出和格式是有意的。如果我想让元素尽可能小,那么我需要缩小嵌入到元素中的CSS和HTML。
那么你如何解决这样的问题呢?
我选择了打破压缩HTML并将CSS压缩成两个额外步骤的问题。
我无法轻松找出一种可扩展的方式来推断字符串是CSS,并且需要压缩,所以我上了旧学校并复制了我在Google Web Starter Kit中看到的一些东西 - 自定义标记,用于定义需要的东西被处理。
自定义标记只是浏览器忽略的普通注释,但是缩小器也会被删除。
我编写了这个简单的脚本,它从STDIN中读取,加载整个文件,然后查找自定义注释,然后使用简单的正则表达式在运行替换函数之前查找注释和内容,然后再打印整个输出回STDOUT。
它包括clean-css,它似乎会做的伎俩。
const CleanCSS = require('clean-css');
const process = require('process');
let input = '';
process.stdin.on('readable', () => {
let chunk = process.stdin.read();
if(chunk != null) input += chunk;
})
process.stdin.on('end', () => {
let cssRe = /\/\*compress\*\/(.|[\n\r])+?\/\*endcompress\*\//;
let compressedOutput = input.replace(cssRe, (match, p1, offset, string) => {
let output = new CleanCSS({}).minify(match);
return output.styles;
});
process.stdout.write(compressedOutput);
process.exit();
});
我不得不加强我的内联CSS /*compress*/和/*endcompress*/注释,这对于任何阅读源代码的开发人员来说都可能有点混乱,但它确实给了我很大的灵活性。
我为HTML缩小做了完全相同的事情。这个html-minifier软件包非常整齐,我玩弄了一些理想的默认设置,运行良好。
const minify = require('html-minifier').minify;
const process = require('process');
let input = '';
process.stdin.on('readable', () => {
let chunk = process.stdin.read();
if(chunk != null) input += chunk;
})
process.stdin.on('end', () => {
let cssRe = /<!--compress-->(.|[\n\r])+?<!--endcompress-->/;
let compressedOutput = input.replace(cssRe, (match, p1, offset, string) => {
return minify(match, { removeAttributeQuotes: true, removeComments: true, collapseWhitespace: true });
});
process.stdout.write(compressedOutput);
process.exit();
});
共享按钮具有build压缩CSS和HTML 的自定义脚本,最后它执行ES6缩小操作,并确保用于分发和包含的文件尽可能小。
"scripts": {
"build": "cat share-button.js | node build/compress-css.js | node build/compress-html.js | babili > dist/share-button.min.js"
}
将它整合到我的博客中
我打算写一篇关于部署Web组件的咆哮,但最后它非常简单。
1.从我的项目中安装元素。
npm install sharebutton --save
2.将它添加到我的构建部署中。
install:
- npm install
- cp node_modules/sharebutton/dist/share-button.min.js static/javascripts/share-button.js
我认为这是值得的。该元素现在是7917字节与11700字节,大约减小了33%(gzip,与2742比较是2792字节),所以我现在很高兴(尽管我认为我可以做得更好)。我现在也有一个可以用于其他元素的进程,并且所有内容都封装在这个包中。
我支持自己进入一个角落,选择内联CSS和HTML,但我仍然认为这是构建自定义元素的最佳解决方案。
这里介绍的解决方案将在缩小元素方面做得很好,但是它不会做得很好,例如,因为自定义元素对外部元素不透明,所以我可以在缩小CSS选择器,ID等方面做得更好。 。但CSS,HTML和JS没有足够的耦合度,足以让我有信心做到这一点。
我很乐意在这个过程中得到你的想法,如果你做了类似的事情,并有更好的结果。
JSS是CSS的创作工具,它允许你使用JavaScript以声明,无冲突和可重用的方式描述样式。它可以在浏览器,服务器端或在构建时在Node中编译。JSS与框架无关。它由多个包组成:核心部分,插件以及框架集成等。
https://github.com/cssinjs/jss stars:5.1k
如果你已经对使用JSS感兴趣,可以使用在线代码编辑器。在CodeSandbox(一个非常实用的在线编辑器,可以用来学习各种编程技能)上尝试Hello World示例。以下是三种不同框架下的用法(代码图片生成自carbon网站):
JSS生成实际的CSS,而不是内联样式。它支持每个现有的CSS功能。CSS规则只创建一次,并使用其类名与元素重复使用,与内联样式相反。此外,当DOM元素更新时,将应用先前创建的CSS规则。
JSS默认生成唯一的类名。它允许避免典型的CSS问题,默认情况下一切都是全局的。它完全消除了命名约定的需要。
使用JavaScript作为宿主语言使我们有机会以常规CSS无法实现的方式重用CSS规则。您可以利用JavaScript模块,变量,函数,数学运算等。如果做得好,它仍然可以完全声明。
CSS规则的明确使用允许您跟踪消费者并确定是否可以安全地删除或修改它。
使用JavaScript函数和Observable可以在浏览器中动态生成样式,使有机会访问应用程序状态,浏览器API或远程数据以进行样式设置。你不仅可以定义一次样式,还可以在任何时间点以有效的方式更新样式。
JSS可以高效地处理CSS更新,可以使用它创建复杂的动画。使用函数值,Observables并将它们与CSS过渡相结合,可以为用户控制的动画提供最大的性能。对于预定义的动画,使用@keyframes和transition更好,因为它们将完全取消阻止JavaScript线程。
要优化第一次绘制的时间,你可以使用服务器端渲染并提取关键CSS。可以将CSS的呈现与HTML的呈现结合起来,这样就不会生成未使用的CSS。它将导致在服务器端呈现期间提取的最小关键CSS,并允许内联它。
JSS核心实现了基于插件的架构。它允许您创建可以实现自定义语法或其他强大功能的自定义插件。JSS有许多官方插件,可以单独安装或使用默认预设。社区插件的一个很好的例子是jss-rtl。
由于各种插件,JSS允许您使用现有的全局类名来嵌套,全局选择器和组合。例如,允许您以比CSS更可读的方式表达属性。如果要直接从浏览器开发工具复制粘贴样式,也可以使用模板字符串。jss-plugin-expandbox-shadow
另一个有用的插件示例是,它允许您完全隔离元素与全局级联规则,并可能覆盖不需要的属性。在创建应该在第三方文档内部呈现的窗口小部件时尤其有用。jss-plugin-isolate
React-JSS包提供了一些额外的功能:
CSS不需要额外的构建管道配置。无论你选择构建JavaScript的工具是什么,它都可以与JSS一起使用。
yarn add jss
yarn add jss-preset-default //使用默认设置
import jss from 'jss' import preset from 'jss-preset-default' jss.setup(preset()) // 创造你的style. const style = { myButton: { color: 'green' } } //编译样式,应用插件。 const sheet = jss.createStyleSheet(style) //如果要在客户端上呈现,请将其插入DOM。 sheet.attach() //如果要渲染服务器端,请获取CSS文本。 sheet.toString()
import jss from 'jss' import camelCase from 'jss-plugin-camel-case' import somePlugin from 'jss-some-plugin' //使用插件。 jss.use(camelCase(), somePlugin()) // Create your style. const style = { myButton: { color: 'green' } } //编译样式,应用插件。 const sheet = jss.createStyleSheet(style) // 如果要在客户端上呈现,请将其插入DOM sheet.attach() // 如果要渲染服务器端,请获取CSS文本。 sheet.toString()
<head> <title>JSS</title> <!-- 自定义插入点 --> </head>
import jss from 'jss' jss.setup({insertionPoint: 'custom-insertion-point'})
<head> <title>JSS in body</title> </head> <body> <div id="insertion-point"> 这可能是你选择的任何DOM节点,可以作为插入点。 </div> </body
import jss from 'jss' jss.setup({ insertionPoint: document.getElementById('insertion-point') })
通过两张图片来体验:
JSS的功能是十分强大的,不仅仅让写css的方式放到了JavaScript,这样对更加喜爱编写javascript的小伙伴来说是值得尝试的,而且还支持服务器端渲染等更多高级的特性,前端技术百花齐放,但目前仍然不变的是掌握JavaScript者得天下的时代!
*请认真填写需求信息,我们会在24小时内与您取得联系。