一個超炫酷帶陰影的CSS/Sass 3D進度條

2017-10-06    分類:WEB開發、程式設計開發、首頁精華0人評論發表於2017-10-06

本文由碼農網 – 小峰原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃

今天我們想向大家展示如何建立一些具有特殊3D外觀的純CSS進度條。不妨將本教程當作是一個高階的CSS練習,以更深入地瞭解更多有趣的3D屬性和著色技術。僅使用CSS建立UI元件將訓練你的創造性思維,並且在本教程中,我們將通過製作進度條並動畫化來向大家展示一些如何建立更復雜形狀的技巧。

注意:某些CSS屬性僅在現代瀏覽器中受支援。IE仍然不支援transform-style:preserve-3d,這是一個用於建立巢狀3D結構的關鍵屬性;所以進度條在IE瀏覽器中將是扁平/無效的。

瀏覽器支援:Chrome Firefox Internet Explorer Safari Opera

線上演示原始碼下載

我們將在本教程中使用Sass(與Compass一起使用),因此請確保設定並瞭解其基礎知識:

如果你想對動畫進度條使用完整的解決方案,那麼你應該檢視Kimmo Brunfeldt的ProgressBar.js或HubSpot的PACE,以獲得出色的頁面載入進度條。

為了生成所有必要的字首,你可以使用像Autoprefixer或用於Sublime Text的外掛

我們將使用許多有趣的CSS屬性,如transform,perspective和box-shadow。我們還將大量使用SASS,以節省生成進度條的位置和外觀所需的很多時間。通過使用相對大小(em,百分比),我們可以確保進度條的大小易於調整。

構建面

我們先從構建一個包含所有六個面的框開始。這個框將作為我們的主要容器,用來設定進度條的尺寸及其視點。我們還將使用一個包裝器用於透檢視,並且這個包裝器的font-size屬性將允許使用某些em單位魔法的幫助來擴充套件進度條。

為了確保所有的面都是我們3D空間的一部分,我們需要將transform-style: preserve-3d應用於框。

所以讓我們從初始化一些顏色變數開始來編寫樣式吧:

$light-gray: #e0e0e0;
$magenta: #ec0071;
$white: #f5f5f5;

.perspective {
	font-size: 5em; // sets the main scale size
	perspective: 12em; // sets the perspective
	perspective-origin: 50% 50%;
	text-align: center;
}

.bar {
	display: inline-block;
	width: 1em;
	height: 1em;
	margin-top: 1em;
	position: relative;
	transform: rotateX(60deg); // sets the view point
	transform-style: preserve-3d; // perspective for the children
}

現在,我們來看看這些面。如果我們想要能夠毫無困難地重新調整我們的主框,裡面包含的面必須得像液體一樣具有流動行為以及具備絕對位置。

.bar {
	// -> The SCSS written before
	.bar-face {
		display: inline-block;
		width: 100%;
		height: 100%;
		position: absolute;
		bottom: 0;
		left: 0;
		background-color: rgba($light-gray, .6); // just to see what is happening
	}
}

寫標記並且確保它是可以訪問的:

<div class="perspective">
	<div class="bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
		<div class="bar-face"></div>
		<div class="bar-face"></div>
		<div class="bar-face"></div>
		<div class="bar-face"></div>
		<div class="bar-face"></div>
		<div class="bar-face"></div>
	</div>
</div>

如果你有興趣瞭解更多有關可訪問性的資訊,這篇文章(由Gez Lemon撰寫)幫助我了很多: ‘Introduction to WAI ARIA’

設定面

這是非常重要的一部分。進度條的面必須準確定向,這樣當我們開始新增百分比填充時,就不會陷入困境。

.bar {
	// -> The SCSS from before
	.bar-face {
		// -> The SCSS from before
		transform-origin: 50% 100%;
		&.roof {
			transform: translateZ(1em);
		}
		&.front {
			transform: rotateX(-90deg);
		}
		&.right {
			left: auto;
			right: -.5em;
			width: 1em;
			transform: rotateX(-90deg) rotateY(90deg) translateX(.5em);
		}
		&.back {
			transform: rotateX(-90deg) rotateY(0deg) translateZ(-1em);
		}
		&.left {
			width: 1em;
			transform: rotateX(-90deg)rotateY(-90deg) translateX(-.5em) translateZ(.5em);
		}
	}
}
<div class="perspective">
	<div class="bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
		<div class="bar-face roof"></div>
		<div class="bar-face front"></div>
		<div class="bar-face left"></div>
		<div class="bar-face right"></div>
		<div class="bar-face back"></div>
		<div class="bar-face floor"></div>
	</div>
</div>

好的,這是一個很棒的立方體,但是我們要為進度條建立一個矩形。如果你還記得的話,我們已經用一種液體化的方法構建了面,所以如果我們只是增加.bar類的width,那麼這樣就可以。在這個例子中,我們使用了4em的寬度。

構建百分比填充

百分比填充將包含在面內,並且,為了保持HTML程式碼的最小化,我們將使用偽類:before。這樣生成的:before元素將顯示相對於面寬度的百分比。

.bar {
	// -> The SCSS from before
	.bar-face {
		// -> The SCSS from before
		&.percentage:before {
			content: '';
			display: block;
			position: absolute;
			bottom: 0;
			width: 0;
			height: 100%;
			margin: 0;
			background-color: rgba($magenta, .8);
			transition: width .6s ease-in-out;
		}
	}
}
<div class="perspective">
	<div class="bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
		<div class="bar-face roof percentage"></div>
		<div class="bar-face front percentage"></div>
		<div class="bar-face left"></div>
		<div class="bar-face right"></div>
		<div class="bar-face back percentage"></div>
		<div class="bar-face floor percentage"></div>
	</div>
</div>

現在我們需要編寫百分比填充樣式。手動編寫一百個類將會非常繁瑣,所以讓我們寫一些可靠的迴圈來從HTML中獲取aria-valuenow屬性的所有值。

.bar {
	// -> The SCSS from before
	.bar-face {
		// -> The SCSS from before
	}

	@for $i from 0 to 101 {
		&[aria-valuenow='#{$i}'] {
			.percentage:before {
                width: $i * 1%;
			}
		}
	}
}

如果你想立竿見影地看到成果,那麼只需將HTML中的aria-valuenow屬性從0更改至100。

構建皮膚

為了構建皮膚,我們將使用Sass mixins。為了得到一個現實化的外觀,我們將使用box-shadow屬性。這個屬性支援一個陣列的值,並且這個陣列將允許我們模擬照明。我們將在這個屬性中包含地面陰影和麵的採光。

@mixin build-skin($color, $name) {
	&.#{$name} {
		.floor {
			box-shadow:
				0 -0.2em 1em rgba(0,0,0,.15),
				0 0.2em 0.1em -5px rgba(0,0,0,.3),
				0 -0.75em 1.75em rgba($white,.6);
		}
		.left {
			background-color: rgba($color, .5);
		}
		.percentage:before {
			background-color: rgba($color, .5);
			box-shadow: 0 1.6em 3em rgba($color,.25);
		}

	}
}
.bar {
	// -> The SCSS from before
	@include build-skin(#57caf4, 'cyan');
}
<div class="perspective">
	<div class="bar cyan" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100">
		<div class="bar-face roof percentage"></div>
		<div class="bar-face front percentage"></div>
		<div class="bar-face left"></div>
		<div class="bar-face right"></div>
		<div class="bar-face back percentage"></div>
		<div class="bar-face floor percentage"></div>
	</div>
</div>

此外,我們需要一個照亮面的技巧。如果我們以正確的順序輸入面的DOM節點,我們將看到奇蹟:

<div class="perspective">
	<div class="bar cyan" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100">
		<div class="bar-face roof percentage"></div>
		<div class="bar-face back percentage"></div>
		<div class="bar-face floor percentage"></div>
		<div class="bar-face left"></div>
		<div class="bar-face right"></div>
		<div class="bar-face front percentage"></div>
	</div>
</div>

這裡發生了什麼?很簡單:當瀏覽器渲染一個絕對元素時,預設情況下它會新增一個自動遞增的z-index(如果我們不編輯此屬性的話)。所以,如果我們通過先放置底部的面來改變渲染順序,那麼它的陰影就會覆蓋在背面的所有面上。這就是我們實現現實化陰影的原理。

關於如何實現進度條就都在這裡了!現在,請檢視所有DEMO演示和原始碼檔案,然後開始構建皮膚來訓練自己此技能吧。

感謝各位的閱讀,希望本教程能對你有所幫助!

譯文連結:http://www.codeceo.com/article/css3-sass-3d-progress-bar.html
英文原文:Shaded Progress Bars: A CSS/Sass Exercise
翻譯作者:碼農網 – 小峰
轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]

相關文章