8个有用的 CSS 技巧:视差图像,sticky footer 等等

译者:前端小智
原文: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: 0flex-shrink 实际上与 flex-growth 属性相反,控制 flex 元素收缩到适合其容器的大小,将它设置为 0 刚防止 footer 标签收缩,确保它保留其尺寸。

clipboard.png
    // 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

clipboard.png

zoom-on-hover 效果是将注意力吸引到可点击图像上的好方法。当用户将鼠标悬停在上面时,图像会稍微放大,但其尺寸保持不变。

为了达到这个效果,需要用 div 标签包裹 img 标签。

要使此效果生效,需要设置父元素的 widthheight ,并确保将 overflow 设置为 hidden,然后,你可以将任何类型的转换动画效果应用于内部图像。

// html
<div class="img-wrapper">
    <img class="inner-img" src="https://source.unsplash.com/random/400x400" />
</div>

<!-- Additional examples -->

<div class="img-wrapper">
    <img class="inner-img" src="https://source.unsplash.com/random/401x401" width="400px" height="400px" />
</div>

<div class="img-wrapper">
    <img class="inner-img" src="https://source.unsplash.com/random/402x402" width="400px" height="400px" />
</div>


// css
.img-wrapper {  
  width: 400px;
  height: 400px;
  overflow: hidden; 
}

.inner-img {
  transition: 0.3s;
}

.inner-img:hover {
  transform: scale(1.1);
}

查看演示

3. 即时夜间模式

如果你正在寻找一个快速的方法来应用“夜间模式”皮肤到你的网站,可以使用 inverthue-rotate 过滤器。

filter: invert() 的范围是从 0 到 1,其中 1 从白色变为黑色。

filter: hue-rotate() 改变元素的颜色内容,使它们或多或少保持相同的分离水平, 其值范围为 0deg360deg

通过将这些效果组合在 body 标签上,可以快速试用网站的夜间模式(注意,为了影响背景,你必须给它一个颜色。)

使用这些设置,我们可以给谷歌的主页一个即时改造:

图片描述

4.自定义的要点

clipboard.png

要为无序列表创建自定义项目符号,可以使用 content 属性和 ::before 伪元素。

在下面的 CSS 中,我使用 .complete.incomplete 两个类来区分两种不同类型的项目符号。

ul {
  list-style: none;
}
ul.complete li::before {
  content: '🗹 ';
}
ul.incomplete li::before {
  content: '☐ ';
}

查看演示

额外用途:面包屑导航

clipboard.png

利用 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 src="https://unsplash.it/1920/1920/?image=1005" data-speed="-1" class="img-parallax">
  <h2>Parallax Speed -1</h2>
</div>
<div class="block">
  <img src="https://unsplash.it/1920/1920/?image=1067" data-speed="1" class="img-parallax">
  <h2>Parallax Speed 1</h2>
</div>
<div class="block">
  <img src="https://unsplash.it/1920/1920/?gravity=center" data-speed="-0.25" class="img-parallax">
  <h2>Parallax Speed -0.25</h2>
</div>
<div class="block">
  <img src="https://unsplash.it/1920/1920/?image=1080" data-speed="0.25" class="img-parallax">
  <h2>Parallax Speed 0.25</h2>
</div>
<div class="block">
  <img src="https://unsplash.it/1920/1920/?random" data-speed="-0.75" class="img-parallax">
  <h2>Parallax Speed -0.75</h2>
</div>
<div class="block">
  <img src="https://unsplash.it/1920/1920/?blur" data-speed="0.75" class="img-parallax">
  <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-fitobject-position,它们一起允许你更改图像的尺寸而不影响它的长宽比。

以前,总是可以在照片编辑器中裁剪图像,但是在浏览器中裁剪图像的一个很大的优势是可以将图像大小调整为动画的一部分。

为了尽可能简单地演示这种效果,下面的示例使用 <input type="checkbox"> 标记触发这种效果。这样,我们可以利用CSS的 :checked 伪类,我们不需要使用任何JavaScript:

// html
<input type="checkbox" />
<br />
<img src="https://source.unsplash.com/random/1920x1080" alt="Random" />


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-widthcolumn-gap 属性。

然后,为了防止任何元素被分割到两个列中,使用 column-break-inside:avoid 将其添加到单个元素中。

图片描述
// html
<div id="columns">
  <figure>
  <img src="//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 src="//s3-us-west-2.amazonaws.com/s.cdpn.io/4273/rapunzel.jpg">
    <figcaption>Rapunzel, clothed in 1820’s period fashion</figcaption>
    </figure>
    
  <figure>
    <img src="//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 src="//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 src="//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 src="//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 src="//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>
    <img src="//s3-us-west-2.amazonaws.com/s.cdpn.io/4273/ariel.jpg">
    <figcaption>Ariel wearing an evening gown of the 1890’s</figcaption>
    </figure>
  
    <figure>
    <img src="//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 &copy; <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的打印

设计原则

你的点赞是我持续分享好东西的动力,欢迎点赞!

交流

干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。

https://github.com/qq449245884/xiaozhi

我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复福利,即可看到福利,你懂的。

image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 选择qi:是表达式 标签选择器 类选择器 属性选择器 继承属性: color,font,text-align,li...
    love2013阅读 2,303评论 0 11
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,727评论 1 92
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,421评论 1 45
  • 2018年6月9日 星期日 大宝周记~家乡糍粑 在我的家乡-湖南。有一道独一无二的美食-糍粑,它味道极佳,...
    晴致生活馆阅读 365评论 0 1
  • 《如何有效阅读一本书》一书的作者是奥野宣之,他的另一个作品是《如何有效整理信息》。《如何有效阅读一本书》有许多可供...
    始闻阅读 535评论 0 0