1. 自适应内部元素的宽度max-width: min-content;
如果不给元素指定一个具体的 height,它就会自动适应其内容的高度。尝试对width 也实现类似的行为。
使 figure 元素能跟它所包含的图片一样宽(图片的尺寸往往不是固定的),而且是水平居中的。
- 让
<figure>
元素浮动会让它得到正确的宽度,但同时也彻底改变了它的布局模式 - 对 figure 应用 display: inline-block 会让它根据内容来决定自身的尺寸,但很难继续完成水平居中
- 对 fifigure 应用一个固定的 width 或max-width ,然后对 figure > img 应用 max-width: 100%。可是这个方法无法实现响应式
width 和 height 属性有一个新的关键字 min-content
。这个关键字将解析为这个容器内部最大的不可断行元素的宽度(即最宽的单词、图片或具有固定宽度的盒元素)。
figure {width: min-content;margin: auto;
}
<!DOCTYPE html>
<html><head><style> figure {/*回退机制*//* max-width: 300px;*//*把 figure 设置为恰当的宽度,并让它水平居中*/max-width: min-content;margin: auto;}figure > img {max-width: inherit;}/* Basic styling */figure {padding: 10px;border: 1px solid silver;} </style></head><body><p>Let’s assume we have some text here. Bacon ipsum dolor sit amet turkeyveniam shankle, culpa short ribs kevin t-bone occaecat.</p><figure><img src="http://csssecrets.io/images/adamcatlace.jpg" /><figcaption>The great Sir Adam Catlace was named after Countess Ada Lovelace, thefirst programmer ever.</figcaption></figure><p>We also have some more text here. Et laborum venison nostrud, ut veniamsint kielbasa ullamco pancetta.</p></body>
</html>
2. 精确控制表格列宽——table-layout: fixed
table-layout
的默认值是 auto,其行为模式是我们最为熟悉的表格布局行为
对表格应用 table-layout: fixed
之后的效果。按从上到下的顺序总结为:
- 如果不指定任何宽度,则各列的宽度将是平均分配的;
- 后续的表格行并不会影响列宽;
- 给单元格指定很大的宽度也会直接生效,并不会自动缩小;
- overflow 和 text-overflow属性都是可以正常生效的;
- 如果overflow 的值是 visible,则单元格的内容有可能会溢出
对 <table>
元素或其他具有 display: table 样式的元素应用table-layout: fixed
属性
请注意,为了确保
table-layout: fixed
奏效,需要为这些表格元素指定一个宽度(哪怕是 100%)。同样,为了让 text-overflow:ellipsis 发挥作用,还需要为那一列指定宽度
<!DOCTYPE html>
<html><head><style> body {background: #ddd;}section {width: 500px;margin: 2em;background: white;}table {border-collapse: collapse;margin-bottom: 1em;width: 100%;}section + section table {table-layout: fixed;}td {border: 1px solid #aaa;}td.preformatted {white-space: pre;font-family: Consolas, Monaco, monospace;text-overflow: ellipsis;overflow: hidden;} </style></head><body><section><h1>With table-layout: auto</h1><div><table><tr><td>If we don’t…</td><td>specify a cell width, they will be assigned one that depends ontheir contents. Notice how the cell with the more content here ismuch wider.</td></tr></table><table><tr><td>If we don’t…</td><td>specify a cell width, they will be assigned one that depends ontheir contents. Notice how the cell with the more content here ismuch wider.</td></tr><tr><td>All rows take part in calculating the widths, not just the firstone.</td><td>Notice how the dimensions here are different than the previousexample.</td></tr></table><table><tr><td style="width: 1000px">If we specify a width, it will not always be followed. I have awidth of <code>1000px</code>…</td><td style="width: 2000px">…and I have a width of <code>2000px</code>. Because there’s notenough space for <code>3000px</code>, they are reducedproportionally, to 33.3% and 66.6% of the total width.</td></tr></table><table><tr><td>If we prevent word wrapping, the table can become so wide it growsbeyond its container.</td><td class="preformatted">…and <code>text-overflow: ellipsis</code> doesn’t help either.</td></tr></table><table><tr><td>Large images and blocks of code can also cause the same issue.</td><td><img src="http://lea.verou.me/book/panoramic.jpg" /></td></tr></table></div></section><section><h1>With table-layout: fixed</h1><div></div></section></body><script> document.querySelector("section + section div").innerHTML = document.querySelector("section:first-of-type div").innerHTML; </script>
</html>
3. 根据兄弟元素的数量来设置样式
当一个列表不断延长时,通过隐藏控件或压缩控件等方式来节省屏幕空间,以此提升用户体验
li:first-child:nth-last-child(1) { /* 相当于li:only-child */
}
用兄弟选择符(~
)来命中之后的所有兄弟元素
li:first-child:nth-last-child(4)
CSS选择器——找一个同时匹配:first-child
和:nth-last-child(4)
的元素,这个元素需要是父元素的第一个子元素,同时还需要是从后往前数的第四个子元素
li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li {/* 当列表正好包含四项时,命中所有列表项 */
}
/* 定义mixin */
@mixin n-items($n) {&:first-child:nth-last-child(#{$n}),&:first-child:nth-last-child(#{$n}) ~ & {@content;}
}
/* 调用时是这样的: */
li {@include n-items(4) {/* 属性与值写在这里 */}
}
3.1 根据兄弟元素的数量范围来匹配元素
:nth-child(n+b)
这种形式的表达式可以选中从第 b 个开始的所有子元素:nth-child(-n+b)
这种形式的表达式可以选中开头的 b 个元素
:nth-child(n+4)
将会选中除了第一、二、三个子元素之外的所有子元素
li:first-child:nth-last-child(n+4),
li:first-child:nth-last-child(n+4) ~ li {/* 当列表至少包含四项时,命中所有列表项 */
}
li:first-child:nth-last-child(-n+4),
li:first-child:nth-last-child(-n+4) ~ li {
/* 当列表最多包含四项时,命中所有列表项 */
}
li:first-child:nth-last-child(n+2):nth-last-child(-n+6),
li:first-child:nth-last-child(n+2):nth-last-child(-n+6) ~ li {
/* 当列表包含2~6项时,命中所有列表项 */
}
<!DOCTYPE html>
<html><head><style> /* Hide "color" 4 items or more */.palette li:first-child:nth-last-child(n + 4) .color-options a:after,.paletteli:first-child:nth-last-child(n + 4)~ li.color-optionsa:after {content: none;}/* Hide word when 6 items or more */.palette li:first-child:nth-last-child(n + 6) .color-options a,.palette li:first-child:nth-last-child(n + 6) ~ li .color-options a {color: transparent;font-size: 0;}.palette li:only-child .delete {display: none;}/* From this point it’s just styling */.palette {display: flex;height: 200px;max-width: 900px;font: bold 90%/1 sans-serif;}.palette li {flex: 1;list-style: none;background: #d6e055;}.color-options {background: rgba(0, 0, 0, 0.5);padding: 10px;margin: 0 10px;overflow: hidden;border-radius: 0 0 10px 10px;}.color-options .add {float: left;}.color-options .delete {float: right;}.color-options a {color: white;text-decoration: none;}.color-options a:before {display: inline-block;font-size: 1rem;width: 1.3rem;margin-right: 0.3rem;text-align: center;line-height: 1.3;background: white;border-radius: 50%;letter-spacing: normal;}.color-options .add:before {content: "✚";color: #590;}.color-options .delete:before {content: "✖";color: #b00;}.color-options a:after {content: " color";font-weight: normal;} </style></head><body><ul class="palette"><li><div class="color-options"><a class="add" href="#">Add</a><a class="delete" href="#">Delete</a></div></li></ul></body><script> function $$(expr, con) {return [].slice.call((con || document).querySelectorAll(expr));}var colors = ["#D6E055", // Agave"#082323","#E6E2AF","#A7A37E","#EFECCA","#046380", // Sandy stone beach"#1C171D","#FEE169","#CDD452","#F9722E","#C9313D", // Sushi Maki"#2E95A3","#50B8B4","#C6FFFA","#E2FFA8" // Agave],palette = document.querySelector(".palette"),template = palette.firstElementChild;function addColor(template) {var li = template.cloneNode(true);var color = colors.pop();colors.unshift(color);li.style.background = color;palette.insertBefore(li, template.nextSibling);}palette.onclick = function(evt) {var button = evt.target;if (button.className == "add") {addColor(button.parentNode.parentNode);} else if (button.className == "delete") {var li = button.parentNode.parentNode;li.parentNode.removeChild(li);}}; </script>
</html>
4. 满幅的背景,定宽的内容
最常见的方法就是添加一层额外的HTML元素:外层用来实现满幅的背景,内层用来实现定宽的内容。后者是通过margin: auto
实现水平居中的。
<footer><div class="wrapper"><!-- 页脚的内容写在这里 --></div>
</footer>
footer {background: #333;
}
.wrapper {max-width: 900px;margin: 1em auto;
}
4.1 用 calc()
替代 margin: auto
不需要添加一层额外的元素,把这个calc()
长度值应用到父元素的 padding 上
<!DOCTYPE html>
<html><head><style> header,section,footer {padding: 1em calc(50% - 350px);}footer {background: #333;color: white;}header {background: orange;color: white;}section + section {background: #eee;}body {margin: 0;font: 100%/1.5 sans-serif;} </style></head><body><header><h1>Fluid background, <br />fixed content</h1></header><section><h1>Heading</h1><p>Bacon ipsum dolor amet voluptate et shoulder, ipsum flank tongueexercitation commodo sed beef ribs drumstick in venison laborum. Laborisut enim id drumstick, et aute esse. Consequat ad kielbasa anim pork lointurkey qui cupidatat drumstick doner labore. Nulla sirloin jerky do sedmagna meatloaf. Ribeye ea ut elit leberkas laboris sausage corned beefdrumstick cillum non.</p></section><section><h1>Another heading</h1><p>Nostrud landjaeger cillum beef cow tail cupidatat non mollit voluptatejowl. Enim sunt in, flank hamburger proident qui. Id aute excepteurchuck magna tempor ipsum pork chop t-bone. Frankfurter meatball porkloin beef et leberkas pork. Pig ball tip pancetta in.</p><p>Ribeye in veniam ipsum flank. Elit incididunt t-bone proident meatball.Porchetta exercitation prosciutto sausage chuck ut eu brisket shankpastrami turkey sunt laboris tenderloin anim. Landjaeger do venisonlaboris kevin.</p></section><footer><p>© 2015 Lea Verou (j/k, feel free to use wherever)</p><p>Consectetur et t-bone pork loin. Tri-tip cupim in, spare ribs velitexercitation in. Tempor cillum fugiat, nisi leberkas reprehenderit animlaboris proident cow. Eu fatback kevin sint, ad shoulder in venisonpicanha. Sausage drumstick capicola, culpa boudin pork belly minim auteipsum biltong picanha venison nulla adipisicing.</p></footer></body>
</html>
5. 垂直居中
在 CSS 中对元素进行水平居中是非常简单的:
- 如果它是一个行内元素,就对它的父元素应用 text-align: center;
- 如果它是一个块级元素,就对它自身应用 margin: auto。
5.1 基于绝对定位的方案
<!DOCTYPE html>
<html><head><style> main {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%); /*解除对固定尺寸的依赖*/padding: 1em 1.5em;box-sizing: border-box;background: #655;color: white;text-align: center;}h1 {margin: 0 0 0.2em;font-size: 150%;}p {margin: 0;}body {background: #fb3;font: 100%/1.5 sans-serif;} </style></head><body><main><h1>Am I centered yet?</h1><p>Center me, please!</p></main></body>
</html>
5.2 基于视口单位的解决方案 margin: 50vh auto 0;
不使用绝对定位,仍然可以采用 translate() 技巧来把这个元素以其自身宽高的一半为距离进行移动
main {width: 18em;padding: 1em 1.5em;margin: 50vh auto 0;transform: translateY(-50%);box-sizing: border-box;background: #655;color: white;text-align: center;
}
5.3 基于 Flexbox 的解决方案
先给这个待居中元素的父元素设置 display:flex
,再给这个元素自身设置 margin: auto
注意,当我们使用 Flexbox 时,
margin: auto
不仅在水平方向上将元素居中,垂直方向上也是如此。
还可以将匿名容器(即没有被标签包裹的文本节点)垂直居中
<main>Center me, please!</main>
main {display: flex;align-items: center;justify-content: center;width: 18em;height: 10em;
}
<!DOCTYPE html>
<html><head><style> * {margin: 0;}body {display: flex;min-height: 100vh;}main {padding: 1em 2em;margin: auto;box-sizing: border-box;background: #655;color: white;text-align: center;}h1 {margin-bottom: 0.2em;font-size: 150%;}body {background: #fb3;font: 100%/1.5 sans-serif;} </style></head><body><main><h1>Am I centered yet?</h1><p>Center me, please!</p></main></body>
</html>
5.4 align-self: center;
6. 紧贴底部的页脚
6.1 固定高度的解决方案
这个方案不仅要求我们确保页脚内的文本永远不会折行,而且每当我们改变页脚的尺寸时,都需要跟着调整min-height 值
<!DOCTYPE html>
<html><head><style> main {min-height: calc(100vh - 5em - 7em);}/* Toggle checkbox to alternate between short/long content */#contents:checked ~ p {display: none;}/* Basic styling */body {margin: 0;font: 100%/1.5 Palatino Linotype, Palatino, serif;}h1 {margin: 0.5em 0 0;}header {text-align: center;height: 3em;}main,footer {display: block;padding: 0.5em calc(50% - 400px);}footer {background: linear-gradient(#222, #444);color: white;height: 6em;} </style></head><body><header><h1>Site name</h1></header><main><input type="checkbox" id="contents" /><label for="contents">Toggle contents</label><p>Bacon ipsum dolor sit amet turkey veniam shankle, culpa short ribs kevint-bone occaecat. Et laborum venison nostrud, ut veniam sint kielbasaullamco pancetta. Qui drumstick tail, bacon leberkas shoulder capicolalaborum. Minim ipsum bacon, mollit laboris t-bone pariatur. Ham hockreprehenderit sint beef, sausage pig eiusmod t-bone shankle strip steak.</p><p>Cow enim excepteur, boudin dolore lorem magna fugiat consequatvoluptate. Picanha fugiat chicken, cupim aliquip magna filet mignonprosciutto ut nostrud. Kielbasa rump frankfurter sunt corned beef.Andouille in cillum deserunt, rump et picanha landjaeger tongue anim.</p><p>Ad meatball ipsum ground round shank. Quis ipsum meatball exercitation.Laborum swine spare ribs, sunt ball tip magna t-bone venison. Velitdoner voluptate non occaecat do ribeye kevin strip steak et. Essebiltong shank ribeye dolor pariatur aute deserunt non est eiusmod porkbelly pancetta pork chop. Pork chop id consectetur rump, meatball shortloin brisket tail andouille deserunt alcatra irure prosciutto do.</p><p>Dolore reprehenderit ex, meatball doner commodo consectetur ea ribeye.Ad aliqua kevin, chuck excepteur minim et cow esse ham hock landjaeger.Alcatra bresaola dolore tempor do, excepteur in velit flank officiadolore meatloaf corned beef picanha. Eu pancetta brisket eiusmod ipsumaute sausage, culpa rump shoulder excepteur nostrud venison sed porkloin. Tempor proident do magna ground round. Ut venison frankfurter etveniam dolore. Pig pork belly beef ribs kevin, doner exercitation magnaesse shankle.</p><p>Flank anim chuck boudin id consectetur bresaola ham pork loin cupimandouille frankfurter. Proident do ball tip nostrud nulla sed,frankfurter ut commodo corned beef ut. Ex aute in, pig deserunt beefribs turducken pastrami irure ball tip pork belly pork chop sausage id.Chicken sunt nisi tempor sed. In eiusmod non fatback tempor tenderloinpastrami adipisicing cow lorem ut tail jerky cupidatat venison. Jowlconsequat commodo pork loin ipsum pork belly prosciutto aute beef. Balltip shoulder aliqua, fugiat landjaeger kevin pork chop beef ribsleberkas hamburger cillum turkey ut doner culpa.</p></main><footer><p>© 2015 No rights reserved.</p><p>Made with ♥ by an anonymous pastafarian.</p></footer></body>
</html>
6.2 Flexbox方案
- 首先,对
<body>
元素设置display: flex
,因为它是这三个主要区块的父元素, - 当父元素获得这个属性之后,就可以对其子元素触发“伸缩盒布局模型”。
- 我们还需要把 flex-flow 设置为 column,否则子元素会被水平排放在一行上
把 <body>
的 min-height 属性指定为 100vh,这样它就至少会占据整个视口的高度 而内容区块的高度应该可以自动伸展并占满所有的可用空间。我们只要给 <main>
这个容器的 flflex 属性指定一个大于 0 的值(比如 1 即可)
body {display: flex;flex-flow: column;min-height: 100vh;
}
main {flex: 1;
}
最后
最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。
有需要的小伙伴,可以点击下方卡片领取,无偿分享