译者:前端小智
原文:https://medium.com/@bretcameron/parallax-images-sticky-footers-and-more-8-useful-css-tricks-eef12418f676
CSS是一种独特的语言。乍一看,这似乎很简单,但是,某些在理论上看起来很简单的效果在实践中往往不那么明显。
在本文中,我将分享一些有用的技巧和技巧,它们代表了我在学习CSS过程中的关键进展。本文并不是要演示CSS可以变得多么复杂。相反,它分享了一些在大多数CSS教程中不太可能找到的有用技巧。
想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你!
1. Sticky Footer
这个非常常见的需求,但对于初学者来说可能是个难题。
对于大多数项目,不管内容的大小,都希望页脚停留在屏幕的底部—如果页面的内容经过了视图端口,页脚应该进行调整。
在CSS3之前,如果不知道脚的确切高度,就很难达到这种效果。虽然我们称它为粘性页脚,但你不能简单地用 position: sticky
来解决这个问题,因为它会阻塞内容。
今天,最兼容的解决方案是使用 Flexbox。主要的做法是在包含页面主要内容的
div
上使用不太知名的 flex-grow
属性,在下面的示例中,我使用的是 main
标签。
flex-grow
控制 flex 项相对于其他 flex 元素填充其容器的数量。当值为 0
时,它不会增长,所以我们需要将它设置为 1
或更多。在下面的示例中,我使用了简写属性 flex: auto
,它将 flex-grow
默认设置为 1
。
为了防止任何不必要的行为,我们还可以在 footer
标签中添加 flex-shrink: 0
。flex-shrink
实际上与 flex-growth
属性相反,控制 flex 元素收缩到适合其容器的大小,将它设置为 0
刚防止 footer
标签收缩,确保它保留其尺寸。
// html
<div id="document">
<main>
<h1>Everything apart from the footer goes here</h1>
<p>Add more text here, to see how the footer responds!</p>
</main>
<footer>
<h1>The footer goes here</h1>
</footer>
</div>
// css
#document {
height: 100vh;
display: flex;
flex-direction: column;
}
main {
flex: auto;
}
footer {
flex-shrink: 0;
}
/* Other styling elements, that are not necessary for the example */
* {
margin: 0;
font-family: Candara;
}
h1, p {
padding: 20px;
}
footer {
color: white;
background: url(https://images.unsplash.com/photo-1550795598-717619d32900?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=676&q=80);
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
footer > h1 {
text-shadow: 1px 1px 4px #00000080;
}
2. Zoom-on-Hover
[外链图片转存失败(img-d9KvgPaO-1562111209743)(https://user-gold-cdn.xitu.io/2019/4/16/16a24c071fb8dce3?w=645&h=479&f=gif&s=3212691)]
zoom-on-hover 效果是将注意力吸引到可点击图像上的好方法。当用户将鼠标悬停在上面时,图像会稍微放大,但其尺寸保持不变。
为了达到这个效果,需要用 div
标签包裹 img
标签。
要使此效果生效,需要设置父元素的 width
和 height
,并确保将 overflow
设置为 hidden
,然后,你可以将任何类型的转换动画效果应用于内部图像。
// html
<div class="img-wrapper">
[外链图片转存失败(img-E8hW9usC-1562111209743)(https://source.unsplash.com/random/400x400)]
</div>
<!-- Additional examples -->
<div class="img-wrapper">
[外链图片转存失败(img-NQPQVqn9-1562111209744)(https://source.unsplash.com/random/401x401)]
</div>
<div class="img-wrapper">
[外链图片转存失败(img-X1wksi6R-1562111209744)(https://source.unsplash.com/random/402x402)]
</div>
// css
.img-wrapper {
width: 400px;
height: 400px;
overflow: hidden;
}
.inner-img {
transition: 0.3s;
}
.inner-img:hover {
transform: scale(1.1);
}
3. 即时夜间模式
如果你正在寻找一个快速的方法来应用“夜间模式”皮肤到你的网站,可以使用 invert
和 hue-rotate
过滤器。
filter: invert()
的范围是从 0 到 1,其中 1
从白色变为黑色。
filter: hue-rotate()
改变元素的颜色内容,使它们或多或少保持相同的分离水平, 其值范围为 0deg
至 360deg
。
通过将这些效果组合在 body
标签上,可以快速试用网站的夜间模式(注意,为了影响背景,你必须给它一个颜色。)
使用这些设置,我们可以给谷歌的主页一个即时改造:
4.自定义的要点
要为无序列表创建自定义项目符号,可以使用 content
属性和 ::before
伪元素。
在下面的 CSS 中,我使用 .complete
和 .incomplete
两个类来区分两种不同类型的项目符号。
ul {
list-style: none;
}
ul.complete li::before {
content: '? ';
}
ul.incomplete li::before {
content: '☐ ';
}
额外用途:面包屑导航
利用 content
属性有许多更有用的方法,这里忍不住又多介绍一种。
由于用于分隔面包屑的斜杠和其他符号具有样式性,所以在CSS中定义它们很有意义。和本文中的许多例子一样,这种效果依赖于CSS3中提供的伪类——last-child—
—:
.breadcrumb a:first-child::before {
content: " » ";
}
.breadcrumb a::after {
content: " /";
}
.breadcrumb a:last-child::after {
content: "";
}
5. 视差图像 (Parallax Images)
这种引人注目的效果越来越受欢迎,当用户滚动页面时,它可以给页面带来生气。
当一个页面的正常图像随着用户滚动而移动时,视差图像看起来是固定的——只有通过它可见的窗口才会移动。
仅 CSS 示例
// html
<div class="wrapper">
<h1>Scroll Down</h1>
<div class="parallax-img"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.</p>
</div>
<div class="wrapper">
</div>
// css
.wrapper {
height: 100vh;
}
.parallax-img {
height: 100%;
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* Other styling elements, that are not necessary for the example */
body {
margin: 0;
background: #000;
}
* {
font-family: Candara;
color: white;
}
h1 {
margin: 15px;
text-align: center;
}
p {
margin: 15px;
font-size: 1.1rem;
}
.parallax-img {
background-image: url('https://source.unsplash.com/random/1920x1080');
}
CSS + JavaScript 示例
要获得更高级的效果,可以使用 JavaScript 在用户滚动时向图像添加移动。
// html
<div class="block">
[外链图片转存失败(img-nE4T8Fwm-1562111209748)(https://unsplash.it/1920/1920/?image=1005)]
<h2>Parallax Speed -1</h2>
</div>
<div class="block">
[外链图片转存失败(img-aBOtxHHx-1562111209749)(https://unsplash.it/1920/1920/?image=1067)]
<h2>Parallax Speed 1</h2>
</div>
<div class="block">
[外链图片转存失败(img-0Ppzg6ij-1562111209749)(https://unsplash.it/1920/1920/?gravity=center)]
<h2>Parallax Speed -0.25</h2>
</div>
<div class="block">
[外链图片转存失败(img-jS3XIBm2-1562111209750)(https://unsplash.it/1920/1920/?image=1080)]
<h2>Parallax Speed 0.25</h2>
</div>
<div class="block">
[外链图片转存失败(img-s9WxQmIr-1562111209751)(https://unsplash.it/1920/1920/?random)]
<h2>Parallax Speed -0.75</h2>
</div>
<div class="block">
[外链图片转存失败(img-43EBBz3u-1562111209753)(https://unsplash.it/1920/1920/?blur)]
<h2>Parallax Speed 0.75</h2>
</div>
// css
@import url(https://fonts.googleapis.com/css?family=Amatic+SC:400,700);
html, body{
margin: 0;
padding: 0;
height: 100%;
width: 100%;
font-family: 'Amatic SC', cursive;
}
.block{
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
font-size: 16px;
}
.block h2{
position: relative;
display: block;
text-align: center;
margin: 0;
top: 50%;
transform: translateY(-50%);
font-size: 10vw;
color: white;
font-weight: 400;
}
.img-parallax {
width: 100vmax;
z-index: -1;
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%,0);
pointer-events: none
}
// js
// I know that the code could be better.
// If you have some tips or improvement, please let me know.
$('.img-parallax').each(function(){
var img = $(this);
var imgParent = $(this).parent();
function parallaxImg () {
var speed = img.data('speed');
var imgY = imgParent.offset().top;
var winY = $(this).scrollTop();
var winH = $(this).height();
var parentH = imgParent.innerHeight();
// The next pixel to show on screen
var winBottom = winY + winH;
// If block is shown on screen
if (winBottom > imgY && winY < imgY + parentH) {
// Number of pixels shown after block appear
var imgBottom = ((winBottom - imgY) * speed);
// Max number of pixels until block disappear
var imgTop = winH + parentH;
// Porcentage between start showing until disappearing
var imgPercent = ((imgBottom / imgTop) * 100) + (50 - (speed * 50));
}
img.css({
top: imgPercent + '%',
transform: 'translate(-50%, -' + imgPercent + '%)'
});
}
$(document).on({
scroll: function () {
parallaxImg();
}, ready: function () {
parallaxImg();
}
});
});
6. 裁剪图像动画
与粘性页脚一样,在 CSS3 之前裁剪图像也非常棘手。现在,我们有两个属性使裁剪变得简单,object-fit
和 object-position
,它们一起允许你更改图像的尺寸而不影响它的长宽比。
以前,总是可以在照片编辑器中裁剪图像,但是在浏览器中裁剪图像的一个很大的优势是可以将图像大小调整为动画的一部分。
为了尽可能简单地演示这种效果,下面的示例使用 <input type="checkbox">
标记触发这种效果。这样,我们可以利用CSS的 :checked
伪类,我们不需要使用任何JavaScript:
// html
<input type="checkbox" />
<br />
[外链图片转存失败(img-86jXSy7L-1562111209755)(https://source.unsplash.com/random/1920x1080)]
input {
transform: scale(1.5)
margin:10px 5px;
}
img {
width: 1920px;
height: 1080px;
transition: 0s;
}
input:checked +br + img{
width: 500px;
height: 500px;
object-fit: cover;
object-position: left-top;
transition: width 2s, height 4s;
}
7. 混合模式(Blend Modes)
如果你有使用 Photoshop 的经验,你可能知道它不同的混合模式是多么强大,可以创建有趣的效果。但是你知道 Photoshop 的大部分混合模式也可以在 CSS 中使用吗?
当图像的被设置为 background-color:lightblue; blend-mode:difference ;
,这就是Medium 的主页的样子:
此外,背景并不是利用混合模式的唯一方法。mix-blend-mode
属性允许你将元素与其现有背景进行混合。例如,使用如下样式创建这样的效果:
// html
<h1>This is an example title</h1>
// css
h1 {
mix-blend-mode: color-dodge;
font-family: Candara;
font-size: 5rem;
text-align: center;
margin: 0;
padding: 20vh 200px;
color: lightsalmon;
}
html,
body {
margin: 0;
background-color: white;
}
body {
background-image: url(https://images.unsplash.com/photo-1550589348-67046352c5f3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1353&q=80);
background-repeat: no-repeat;
background-size: cover;
min-height: 100vh;
overflow: hidden;
}
8. Pinterest-style 图像
CSS Grid和Flexbox使得实现多种不同类型的响应式布局变得更加容易,并且允许我们在页面上很容易地将元素垂直居中——这在以前是非常困难的。
然而,它们不太适合的一种布局风格是 Pinterest 使用的布局风格,即每个元素的垂直位置都根据其上方元素的高度而变化。
实现此目的的最佳方法是使用 CSS 的列属性套件。 这些最常用于创建多个报纸样式的文本列,但这是另一个很好的用例。
要实现这一点,需要将元素包装在 div
中,并为该包装器提供一个 column-width
和 column-gap
属性。
然后,为了防止任何元素被分割到两个列中,使用 column-break-inside:avoid
将其添加到单个元素中。
// html
<div id="columns">
<figure>
[外链图片转存失败(img-aEvBJtbe-1562111209758)(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/cinderella.jpg)]
<figcaption>Cinderella wearing European fashion of the mid-1860’s</figcaption>
</figure>
<figure>
[外链图片转存失败(img-xpLzLZiE-1562111209759)(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/rapunzel.jpg)]
<figcaption>Rapunzel, clothed in 1820’s period fashion</figcaption>
</figure>
<figure>
[外链图片转存失败(img-uFN0Cwbu-1562111209760)(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/belle.jpg)]
<figcaption>Belle, based on 1770’s French court fashion</figcaption>
</figure>
<figure>
[外链图片转存失败(img-sIpStmrp-1562111209760)(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/mulan_2.jpg)]
<figcaption>Mulan, based on the Ming Dynasty period</figcaption>
</figure>
<figure>
[外链图片转存失败(img-aAwpq3KG-1562111209761)(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/sleeping-beauty.jpg)]
<figcaption>Sleeping Beauty, based on European fashions in 1485</figcaption>
</figure>
<figure>
[外链图片转存失败(img-CrkY5HEL-1562111209762)(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/pocahontas_2.jpg)]
<figcaption>Pocahontas based on 17th century Powhatan costume</figcaption>
</figure>
<figure>
[外链图片转存失败(img-JdhTYoQ4-1562111209762)(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/snow-white.jpg)]
<figcaption>Snow White, based on 16th century German fashion</figcaption>
</figure>
<figure>
![在这里插入图片描述](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9zMy11cy13ZXN0LTIuYW1hem9uYXdzLmNvbS9zLmNkcG4uaW8vNDI3My9hcmllbC5qcGc)
<figcaption>Ariel wearing an evening gown of the 1890’s</figcaption>
</figure>
<figure>
[外链图片转存失败(img-EuEwxXCJ-1562111209764)(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/tiana.jpg)]
<figcaption>Tiana wearing the <i>robe de style</i> of the 1920’s</figcaption>
</figure>
<small>Art © <a href="//clairehummel.com">Claire Hummel</a></small>
</div>
// css
@font-face{font-family:'Calluna';
src:url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/callunasansregular-webfont.woff') format('woff');
}
body {
background: url(//subtlepatterns.com/patterns/scribble_light.png);
font-family: Calluna, Arial, sans-serif;
min-height: 1000px;
}
#columns {
column-width: 320px;
column-gap: 15px;
width: 90%;
max-width: 1100px;
margin: 50px auto;
}
div#columns figure {
background: #fefefe;
border: 2px solid #fcfcfc;
box-shadow: 0 1px 2px rgba(34, 25, 25, 0.4);
margin: 0 2px 15px;
padding: 15px;
padding-bottom: 10px;
transition: opacity .4s ease-in-out;
display: inline-block;
column-break-inside: avoid;
}
div#columns figure img {
width: 100%; height: auto;
border-bottom: 1px solid #ccc;
padding-bottom: 15px;
margin-bottom: 5px;
}
div#columns figure figcaption {
font-size: .9rem;
color: #444;
line-height: 1.5;
}
div#columns small {
font-size: 1rem;
float: right;
text-transform: uppercase;
color: #aaa;
}
div#columns small a {
color: #666;
text-decoration: none;
transition: .4s color;
}
div#columns:hover figure:not(:hover) {
opacity: 0.4;
}
@media screen and (max-width: 750px) {
#columns { column-gap: 0px; }
#columns figure { width: 100%; }
}
上面的例子也是 CSS:not()
伪类的一个很好的例子。他将它与 :hover
一起使用,这样除了盘旋的元素外,其他元素都将淡出。
其它的资源
总的来说,我希望下面的例子已经了说明了一些有用的 CSS 效果,甚至可能会让你注意到一些你没有见到过的特性。
像这样的特性并不属于“简单技巧”的范畴,它们可以自己进行相当深入的探索。所以我不打算在这里描述它们,下面介绍一些很好资源来了解它们:
Keyframe animation
Scroll-snapping
多级导航
3D 效果
CSS的打印
设计原则