Зум слайдер

Простой слайдер контента с функцией зума в каждом слайде.

ZoomSlider
image-3065

Демо

Каждый слайд имеет предопределенный области масштабирования, который будет использоваться для расчета соответствующего значения масштаба для полноэкранной заливки. После того, как значок масштабирования нажат, область увеличения, а также страницы масштабируются, создавая иллюзию, что зритель приближается к контенту.

Мы используем CSS переходы и dymanic.js для перемещения элементов слайд. Dymanic.js Майкла Виллара является библиотекой JavaScript для создания физики на основе анимации.

Пожалуйста, обратите внимание, что мы используем пару современных свойств CSS, так что только современные браузеры поддерживают его.

HTML

<!-- Main container -->
<div class="container">
	<!-- Blueprint header -->
	<header class="bp-header cf">
		<!-- Page title etc. -->
	</header>
	<!-- Grid -->
	<section class="slider">
		<div class="slide slide--current" data-content="content-1">
			<div class="slide__mover">
				<div class="zoomer flex-center">
					<img class="zoomer__image" src="images/iphone.png" alt="iPhone" />
					<div class="preview">
						<img src="images/iphone-content-preview.png" alt="iPhone app preview" />
						<div class="zoomer__area zoomer__area--size-2"></div>
					</div>
				</div>
			</div>
			<h2 class="slide__title"><span>The Classy</span> iPhone 6</h2>
		</div>
		<div class="slide" data-content="content-2">
			<!-- ... -->
		</div>
		<!-- ... -->
		<nav class="slider__nav">
			<button class="button button--nav-prev">
				<i class="icon icon--arrow-left"></i>
				<span class="text-hidden">Previous product</span>
			</button>
			<button class="button button--zoom">
				<i class="icon icon--zoom"></i>
				<span class="text-hidden">View details</span>
			</button>
			<button class="button button--nav-next">
				<i class="icon icon--arrow-right"></i>
				<span class="text-hidden">Next product</span>
			</button>
		</nav>
	</section>
	<!-- /slider-->
	<!-- content -->
	<section class="content">
		<div class="content__item" id="content-1">
			<img class="content__item-img rounded-right" src="images/iphone-content.png" alt="Apple Watch Content" />
			<div class="content__item-inner">
				<h2>The iPhone 6</h2>
				<h3>Incredible performance for powerful apps</h3>
				<p>...</p>
			</div>
		</div>
		<div class="content__item" id="content-2">
			<!-- ... -->
		</div>
		<!-- ... -->
		<button class="button button--close">
			<i class="icon icon--circle-cross"></i>
			<span class="text-hidden">Close content</span>
		</button>
	</section>
	<!-- /content -->
</div>
<script src="js/classie.js"></script>
<script src="js/dynamics.min.js"></script>
<script src="js/main.js"></script>

CSS

/* Helper classes */
html,
body {
	overflow: hidden;
	height: 100%;
}
.container {
	position: relative;
	overflow: hidden;
	overflow-y: scroll;
	width: 100%;
	height: 100%;
	-webkit-overflow-scrolling: touch;
}
.noscroll .container {
	overflow-y: hidden;
}
.slider {
	position: relative;
	z-index: 200;
	width: 100%;
	margin: 0 auto;
	padding: 0 0 7em;
	text-align: center;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
	-webkit-touch-callout: none;
	-khtml-user-select: none;
}
.slide {
	position: absolute;
	top: 0;
	visibility: hidden;
	width: 100%;
	opacity: 0;
}
.slide--current {
	position: relative;
	z-index: 100;
	visibility: visible;
	opacity: 1;
}
.slide__mover {
	position: relative;
	z-index: 100;
}
.slide__title {
	font-size: 1.75em;
	font-weight: normal;
	margin: 0 auto;
	padding: 1em 0 0 0;
}
.slide__title span {
	font-size: 55%;
	font-weight: bold;
	display: block;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: #35303d;
}
.slider__nav {
	position: absolute;
	bottom: 2em;
	width: 100%;
	text-align: center;
}
.button {
	font-size: 1.31em;
	position: relative;
	display: inline-block;
	overflow: hidden;
	margin: 0 25px;
	padding: 0;
	cursor: pointer;
	color: #5c5edc;
	border: none;
	background: none;
}
.button:focus {
	outline: none;
}
.button:hover {
	color: #fff;
}
.text-hidden {
	position: absolute;
	top: 200%;
}
.button--close {
	font-size: 1.55em;
	position: absolute;
	top: 30px;
	right: 30px;
	margin: 0;
	opacity: 0;
	color: #50505a;
	-webkit-transition: opacity 0.3s;
	transition: opacity 0.3s;
}
.content--open .button--close {
	opacity: 1;
}
/* Zoomer */
.zoomer {
	position: relative;
	height: 360px; /* this is needed for IE10 so that vertical flexbox centering works */
}
.flex-center {
	display: -webkit-flex;
	display: -ms-flexbox;
	display: flex;
	-webkit-align-items: center;
	-ms-flex-align: center;
	align-items: center;
	-webkit-justify-content: center;
	-ms-flex-pack: center;
	justify-content: center;
}
.zoomer__image {
	display: block;
	margin: 0;
	-webkit-flex: none;
	-ms-flex: none;
	flex: none;
}
.zoomer__area,
.preview {
	position: absolute;
	top: 50%;
	left: 50%;
	-webkit-transform: translate3d(-50%,-50%,0);
	transform: translate3d(-50%,-50%,0);
}
.zoomer__area:focus {
	outline: none;
}
.zoomer__area--size-1 {
	/* Apple Watch */
	width: 96px;
	height: 118px;
}
.zoomer__area--size-2 {
	/* iPhone */
	width: 112px;
	height: 198px;
}
.zoomer__area--size-3 {
	/* MacBook */
	width: 315px;
	height: 200px;
}
.zoomer__area--size-4 {
	/* iPad */
	width: 150px;
	height: 200px;
}
.zoomer__area--size-5 {
	/* iMac */
	width: 315px;
	height: 189px;
}
.preview {
	overflow: hidden;
	background: #18191b;
}
.preview img {
	display: block;
	border-radius: inherit;
	-webkit-transform: translate3d(0,0,0);
	transform: translate3d(0,0,0);
}
.zoomer--active .preview img {
	-webkit-transform: translate3d(100%,0,0);
	transform: translate3d(100%,0,0);
}
.rounded {
	border-radius: 15px;
}
.rounded-right {
	border-radius: 0 15px 15px 0;
}
.preview__content {
	position: absolute;
	top: 0;
	left: 100%;
	width: 100%;
	height: 100%;
	border-radius: inherit;
}
/* Content */
.content {
	position: fixed;
	z-index: 1000;
	top: 0;
	left: -100%;
	overflow: hidden;
	overflow-y: scroll;
	width: 100%;
	height: 100vh;
	background: #18191b;
	-webkit-overflow-scrolling: touch;
}
.content--open {
	left: 0;
}
.content__item {
	position: absolute;
	top: 0;
	display: -webkit-flex;
	display: -ms-flexbox;
	display: flex;
	overflow: hidden;
	height: 0;
	min-height: 100%;
	margin: 0 auto;
	padding: 2em 0;
	pointer-events: none;
	opacity: 0;
	color: #fff;
	-webkit-align-items: center;
	-ms-flex-align: center;
	align-items: center;
}
.content__item--current {
	pointer-events: auto;
	opacity: 1;
}
.content__item--reset {
	height: auto;
}
.content h2 {
	font-size: 3.5em;
	font-weight: normal;
	margin: 0;
}
.content h3 {
	font-size: 1.95em;
	font-weight: normal;
	margin: 0.25em 0 0.5em;
	color: #685884;
}
.content p {
	font-size: 1.25em;
	line-height: 1.5;
}
.content__item-img {
	display: block;
	max-width: 40vw;
	max-height: 80vh;
	-webkit-transform: translate3d(-120%,0,0);
	transform: translate3d(-120%,0,0);
	-webkit-flex: none;
	-ms-flex: none;
	flex: none;
}
.content__item--current .content__item-img {
	-webkit-transform: translate3d(-10px,0,0);
	transform: translate3d(-10px,0,0);
}
.content__item-inner {
	padding: 0 10vw 0;
	opacity: 0;
	-webkit-transform: translate3d(0,50px,0);
	transform: translate3d(0,50px,0);
}
.content__item--current .content__item-inner {
	opacity: 1;
	-webkit-transform: translate3d(0,0,0);
	transform: translate3d(0,0,0);
}
/**************************/
/* All synced transitions */
/**************************/
.zoomer {
	-webkit-transition: -webkit-transform 0.5s;
	transition: transform 0.5s;
	-webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1);
	transition-timing-function: cubic-bezier(0.7,0,0.3,1);
}
.zoomer.zoomer--notrans {
	-webkit-transition: none;
	transition: none;
}
.zoomer__image {
	-webkit-transition: opacity 0.3s 0.3s;
	transition: opacity 0.3s 0.3s;
}
.zoomer--active .zoomer__image {
	opacity: 0;
	-webkit-transition-delay: 0s;
	transition-delay: 0s;
}
.preview img {
	-webkit-transition: -webkit-transform 0.6s 0.3s;
	transition: transform 0.6s 0.3s;
	-webkit-transition-timing-function: cubic-bezier(0.2,1,0.3,1);
	transition-timing-function: cubic-bezier(0.2,1,0.3,1);
}
.zoomer--active .preview img {
	-webkit-transition: -webkit-transform 0.3s;
	transition: transform 0.3s;
}
.content {
	-webkit-transition: left 0s;
	transition: left 0s;
}
.content__item {
	-webkit-transition: opacity 0s;
	transition: opacity 0s;
}
.content,
.content__item {
	/* delay for content to disappear and zoomer to start transitioning back to 0 */
	-webkit-transition-delay: 0.3s;
	transition-delay: 0.3s;
}
.content--open,
.content__item--current {
	-webkit-transition: none;
	transition: none;
}
.content__item-img {
	-webkit-transition: -webkit-transform 0.4s;
	transition: transform 0.4s;
	-webkit-transition-timing-function: cubic-bezier(0.7,1,0.8,1);
	transition-timing-function: cubic-bezier(0.7,1,0.8,1);
}
.content__item--current .content__item-img {
	-webkit-transition-timing-function: cubic-bezier(0.2,1,0.3,1);
	transition-timing-function: cubic-bezier(0.2,1,0.3,1);
	-webkit-transition-duration: 1s;
	transition-duration: 1s;
}
.content__item-inner {
	-webkit-transition: -webkit-transform 0.6s, opacity 0.3s;
	transition: transform 0.6s, opacity 0.3s;
	-webkit-transition-timing-function: cubic-bezier(0.7,1,0.8,1), ease;
	transition-timing-function: cubic-bezier(0.7,1,0.8,1), ease;
}
.content__item--current .content__item-inner {
	-webkit-transition-timing-function: cubic-bezier(0.2,1,0.3,1), ease;
	transition-timing-function: cubic-bezier(0.2,1,0.3,1), ease;
	-webkit-transition-duration: 1.7s;
	transition-duration: 1.7s;
}
/* Media Queries */
@media screen and (max-width: 50em) {
	.content__item {
		display: block;
	}
	.content__item-img {
		max-width: calc(100% - 80px);
		max-height: 70vh;
	}
	.content h2 {
		font-size: 3em;
	}
	.content__item-inner {
		font-size: 82%;
		padding: 4em 3em 2em;
	}
}

JavaScript

/**
 * main.js
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright 2015, Codrops
 * http://www.codrops.com
 */
;(function(window) {
	'use strict';
	var bodyEl = document.body,
		docElem = window.document.documentElement,
		support = { transitions: Modernizr.csstransitions },
		// transition end event name
		transEndEventNames = { 'WebkitTransition': 'webkitTransitionEnd', 'MozTransition': 'transitionend', 'OTransition': 'oTransitionEnd', 'msTransition': 'MSTransitionEnd', 'transition': 'transitionend' },
		transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ],
		onEndTransition = function( el, callback ) {
			var onEndCallbackFn = function( ev ) {
				if( support.transitions ) {
					if( ev.target != this ) return;
					this.removeEventListener( transEndEventName, onEndCallbackFn );
				}
				if( callback && typeof callback === 'function' ) { callback.call(this); }
			};
			if( support.transitions ) {
				el.addEventListener( transEndEventName, onEndCallbackFn );
			}
			else {
				onEndCallbackFn();
			}
		},
		// window sizes
		win = {width: window.innerWidth, height: window.innerHeight},
		// some helper vars to disallow scrolling
		lockScroll = false, xscroll, yscroll,
		scrollContainer = document.querySelector('.container'),
		// the main slider and its items
		sliderEl = document.querySelector('.slider'),
		items = [].slice.call(sliderEl.querySelectorAll('.slide')),
		// total number of items
		itemsTotal = items.length,
		// navigation controls/arrows
		navRightCtrl = sliderEl.querySelector('.button--nav-next'),
		navLeftCtrl = sliderEl.querySelector('.button--nav-prev'),
		zoomCtrl = sliderEl.querySelector('.button--zoom'),
		// the main content element
		contentEl = document.querySelector('.content'),
		// close content control
		closeContentCtrl = contentEl.querySelector('button.button--close'),
		// index of current item
		current = 0,
		// check if an item is "open"
		isOpen = false,
		isFirefox = typeof InstallTrigger !== 'undefined',
		// scale body when zooming into the items, if not Firefox (the performance in Firefox is not very good)
		bodyScale = isFirefox ? false : 3;
	// some helper functions:
	function scrollX() { return window.pageXOffset || docElem.scrollLeft; }
	function scrollY() { return window.pageYOffset || docElem.scrollTop; }
	// from http://www.sberry.me/articles/javascript-event-throttling-debouncing
	function throttle(fn, delay) {
		var allowSample = true;
		return function(e) {
			if (allowSample) {
				allowSample = false;
				setTimeout(function() { allowSample = true; }, delay);
				fn(e);
			}
		};
	}
	function init() {
		initEvents();
	}
	// event binding
	function initEvents() {
		// open items
		zoomCtrl.addEventListener('click', function() {
			openItem(items[current]);
		});
		// close content
		closeContentCtrl.addEventListener('click', closeContent);
		// navigation
		navRightCtrl.addEventListener('click', function() { navigate('right'); });
		navLeftCtrl.addEventListener('click', function() { navigate('left'); });
		// window resize
		window.addEventListener('resize', throttle(function(ev) {
			// reset window sizes
			win = {width: window.innerWidth, height: window.innerHeight};
			// reset transforms for the items (slider items)
			items.forEach(function(item, pos) {
				if( pos === current ) return;
				var el = item.querySelector('.slide__mover');
				dynamics.css(el, { translateX: el.offsetWidth });
			});
		}, 10));
		// keyboard navigation events
		document.addEventListener( 'keydown', function( ev ) {
			if( isOpen ) return;
			var keyCode = ev.keyCode || ev.which;
			switch (keyCode) {
				case 37:
					navigate('left');
					break;
				case 39:
					navigate('right');
					break;
			}
		} );
	}
	// opens one item
	function openItem(item) {
		if( isOpen ) return;
		isOpen = true;
		// the element that will be transformed
		var zoomer = item.querySelector('.zoomer');
		// slide screen preview
		classie.add(zoomer, 'zoomer--active');
		// disallow scroll
		scrollContainer.addEventListener('scroll', noscroll);
		// apply transforms
		applyTransforms(zoomer);
		// also scale the body so it looks the camera moves to the item.
		if( bodyScale ) {
			dynamics.animate(bodyEl, { scale: bodyScale }, { type: dynamics.easeInOut, duration: 500 });
		}
		// after the transition is finished:
		onEndTransition(zoomer, function() {
			// reset body transform
			if( bodyScale ) {
				dynamics.stop(bodyEl);
				dynamics.css(bodyEl, { scale: 1 });
				// fix for safari (allowing fixed children to keep position)
				bodyEl.style.WebkitTransform = 'none';
				bodyEl.style.transform = 'none';
			}
			// no scrolling
			classie.add(bodyEl, 'noscroll');
			classie.add(contentEl, 'content--open');
			var contentItem = document.getElementById(item.getAttribute('data-content'))
			classie.add(contentItem, 'content__item--current');
			classie.add(contentItem, 'content__item--reset');
			// reset zoomer transform - back to its original position/transform without a transition
			classie.add(zoomer, 'zoomer--notrans');
			zoomer.style.WebkitTransform = 'translate3d(0,0,0) scale3d(1,1,1)';
			zoomer.style.transform = 'translate3d(0,0,0) scale3d(1,1,1)';
		});
	}
	// closes the item/content
	function closeContent() {
		var contentItem = contentEl.querySelector('.content__item--current'),
			zoomer = items[current].querySelector('.zoomer');
		classie.remove(contentEl, 'content--open');
		classie.remove(contentItem, 'content__item--current');
		classie.remove(bodyEl, 'noscroll');
		if( bodyScale ) {
			// reset fix for safari (allowing fixed children to keep position)
			bodyEl.style.WebkitTransform = '';
			bodyEl.style.transform = '';
		}
		/* fix for safari flickering */
		var nobodyscale = true;
		applyTransforms(zoomer, nobodyscale);
		/* fix for safari flickering */
		// wait for the inner content to finish the transition
		onEndTransition(contentItem, function(ev) {
			classie.remove(this, 'content__item--reset');
			// reset scrolling permission
			lockScroll = false;
			scrollContainer.removeEventListener('scroll', noscroll);
			/* fix for safari flickering */
			zoomer.style.WebkitTransform = 'translate3d(0,0,0) scale3d(1,1,1)';
			zoomer.style.transform = 'translate3d(0,0,0) scale3d(1,1,1)';
			/* fix for safari flickering */
			// scale up - behind the scenes - the item again (without transition)
			applyTransforms(zoomer);
			// animate/scale down the item
			setTimeout(function() {
				classie.remove(zoomer, 'zoomer--notrans');
				classie.remove(zoomer, 'zoomer--active');
				zoomer.style.WebkitTransform = 'translate3d(0,0,0) scale3d(1,1,1)';
				zoomer.style.transform = 'translate3d(0,0,0) scale3d(1,1,1)';
			}, 25);
			if( bodyScale ) {
				dynamics.css(bodyEl, { scale: bodyScale });
				dynamics.animate(bodyEl, { scale: 1 }, {
					type: dynamics.easeInOut,
					duration: 500
				});
			}
			isOpen = false;
		});
	}
	// applies the necessary transform value to scale the item up
	function applyTransforms(el, nobodyscale) {
		// zoomer area and scale value
		var zoomerArea = el.querySelector('.zoomer__area'),
			zoomerAreaSize = {width: zoomerArea.offsetWidth, height: zoomerArea.offsetHeight},
			zoomerOffset = zoomerArea.getBoundingClientRect(),
			scaleVal = zoomerAreaSize.width/zoomerAreaSize.height < win.width/win.height ? win.width/zoomerAreaSize.width : win.height/zoomerAreaSize.height;
		if( bodyScale && !nobodyscale ) {
			scaleVal /= bodyScale;
		}
		// apply transform
		el.style.WebkitTransform = 'translate3d(' + Number(win.width/2 - (zoomerOffset.left+zoomerAreaSize.width/2)) + 'px,' + Number(win.height/2 - (zoomerOffset.top+zoomerAreaSize.height/2)) + 'px,0) scale3d(' + scaleVal + ',' + scaleVal + ',1)';
		el.style.transform = 'translate3d(' + Number(win.width/2 - (zoomerOffset.left+zoomerAreaSize.width/2)) + 'px,' + Number(win.height/2 - (zoomerOffset.top+zoomerAreaSize.height/2)) + 'px,0) scale3d(' + scaleVal + ',' + scaleVal + ',1)';
	}
	// navigate the slider
	function navigate(dir) {
		var itemCurrent = items[current],
			currentEl = itemCurrent.querySelector('.slide__mover'),
			currentTitleEl = itemCurrent.querySelector('.slide__title');
		// update new current value
		if( dir === 'right' ) {
			current = current < itemsTotal-1 ? current + 1 : 0;
		}
		else {
			current = current > 0 ? current - 1 : itemsTotal-1;
		}
		var itemNext = items[current],
			nextEl = itemNext.querySelector('.slide__mover'),
			nextTitleEl = itemNext.querySelector('.slide__title');
		// animate the current element out
		dynamics.animate(currentEl, { opacity: 0, translateX: dir === 'right' ? -1*currentEl.offsetWidth/2 : currentEl.offsetWidth/2, rotateZ: dir === 'right' ? -10 : 10 }, {
			type: dynamics.spring,
			duration: 2000,
			friction: 600,
			complete: function() {
				dynamics.css(itemCurrent, { opacity: 0, visibility: 'hidden' });
			}
		});
		// animate the current title out
		dynamics.animate(currentTitleEl, { translateX: dir === 'right' ? -250 : 250, opacity: 0 }, {
			type: dynamics.bezier,
			points: [{"x":0,"y":0,"cp":[{"x":0.2,"y":1}]},{"x":1,"y":1,"cp":[{"x":0.3,"y":1}]}],
			duration: 450
		});
		// set the right properties for the next element to come in
		dynamics.css(itemNext, { opacity: 1, visibility: 'visible' });
		dynamics.css(nextEl, { opacity: 0, translateX: dir === 'right' ? nextEl.offsetWidth/2 : -1*nextEl.offsetWidth/2, rotateZ: dir === 'right' ? 10 : -10 });
		// animate the next element in
		dynamics.animate(nextEl, { opacity: 1, translateX: 0 }, {
			type: dynamics.spring,
			duration: 2000,
			friction: 600,
			complete: function() {
				items.forEach(function(item) { classie.remove(item, 'slide--current'); });
				classie.add(itemNext, 'slide--current');
			}
		});
		// set the right properties for the next title to come in
		dynamics.css(nextTitleEl, { translateX: dir === 'right' ? 250 : -250, opacity: 0 });
		// animate the next title in
		dynamics.animate(nextTitleEl, { translateX: 0, opacity: 1 }, {
			type: dynamics.bezier,
			points: [{"x":0,"y":0,"cp":[{"x":0.2,"y":1}]},{"x":1,"y":1,"cp":[{"x":0.3,"y":1}]}],
			duration: 650
		});
	}
	// disallow scrolling (on the scrollContainer)
	function noscroll() {
		if(!lockScroll) {
			lockScroll = true;
			xscroll = scrollContainer.scrollLeft;
			yscroll = scrollContainer.scrollTop;
		}
		scrollContainer.scrollTop = yscroll;
		scrollContainer.scrollLeft = xscroll;
	}
	init();
})(window);

Демо

11 классных шрифтов иконок для ваших проектов

Шрифты иконок является хорошим инструментом для создания приложений и веб-сайтов в настоящее время. Они имеют очень много преимуществ по сравнению с фиксированными иконками:

  • масштабируемость
  • стилизация с помощью CSS (изменить размер, цвет и т.д.)
  • добавление границы и теней с помощью CSS
  • нет http запросов для изображений иконок

Это очень важные и ключевые преимущества.

Как использовать иконки шрифтов

Все, что вам нужно сделать, это загрузить CSS файл, и все уже готово!

Например, для того, чтобы использовать FontAwesome шрифт, мы просто должны загрузить файл CSS и применять соответствующие классы для тегов или .

<!-- подключаем css файл -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<!-- используем шрифт иконок с помощью классов -->
<i class="ti-fire"></i>
<span class="ti-user"></span>

Давайте посмотрим лучшие шрифты, которые вы можете использовать для ваших проектов.

FontAwesome

fontawesoek-905x500[1]
image-934

Themify Icons

themifyicons-905x500[1]
image-935

Foundation Icons

foundation-iconfonts-905x500[1]
image-936

Ionicons

ionicons-905x500[1]
image-937

Octicons

octicons-905x500[1]
image-938

Linecons

linecons-905x500[1]
image-939

Open Iconic

openiconic-905x500[1]
image-940

Entypo

entypo-905x500[1]
image-941

JustVector

justvectoricons-905x500[1]
image-942

SVG Icons

svgfonts-905x500[1]
image-943

Payment Icons

paymentfonticons-905x500[1]
image-944

Вывод.

Все эти наборы иконок уникальны по-своему. Комбинируйте их, для создания своих собственные приложения или веб-сайт.

CSS эффекты нажатия

Набор эффектов нажатия мыши, или сенсорных взаимодействий. Эффекты сделано с CSS-анимацией в основном на псевдо-элементах.

Демо / Исходники

ClickEffect[1]
image-925

Один из наиболее эффективных эффектов в последнее время это появляющиеся круги после нажатия мыши. В то время как эти эффекты основаны на месте щелчка или прикосновения, сама идея обеспечения эффекта обратной связи действительно интересна. Как правило, тонкие эффекты, используются в приложение демонстрируя визуализацию нажатия на экран. Но такого рода эффект может быть полезен и на сайтах.

Сегодня мы хотели бы изучить некоторые из этих эффектов, используя различные анимации.

Пожалуйста, обратите внимание, что некоторые из эффектов являются экспериментальными и, следовательно, работать только в современных браузерах.

IE10, похоже, не поддерживает animationend на псевдо-элементах.

Для демонстрации мы используем значки шрифта Awesome и вызываем эффект на кнопке:

<button class="cbutton cbutton--effect-boris">
	<i class="cbutton__icon fa fa-fw fa-play"></i>
	<span class="cbutton__text">Play</span>
</button>

Кнопки имеют следующий общий стиль:

.cbutton {
	position: relative;
	display: inline-block;
	margin: 1em;
	padding: 0;
	border: none;
	background: none;
	color: #286aab;
	font-size: 1.4em;
	transition: color 0.7s;
}
.cbutton.cbutton--click,
.cbutton:focus {
	outline: none;
	color: #3c8ddc;
}
.cbutton__icon {
	display: block;
}
.cbutton__text {
	position: absolute;
	opacity: 0;
	pointer-events: none;
}
.cbutton::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	margin: -35px 0 0 -35px;
	width: 70px;
	height: 70px;
	border-radius: 50%;
	opacity: 0;
	pointer-events: none;
}

При добавлении класса с помощью JavaScript мы вызываем анимацию:

/* Effect Boris */
.cbutton--effect-boris::after {
	background: rgba(111,148,182,0.1);
}
.cbutton--effect-boris.cbutton--click::after {
	animation: anim-effect-boris 0.3s forwards;
}
@keyframes anim-effect-boris {
	0% {
		transform: scale3d(0.3, 0.3, 1);
	}
	25%, 50% {
		opacity: 1;
	}
	100% {
		opacity: 0;
		transform: scale3d(1.2, 1.2, 1);
	}
}

Вот один из эффектов:

ClickEffect[1]
image-926

Для эффекта «Stana», мы используем переход на SVG clipPath, так что работает он только в Chrome на данный момент.

ClickEffect2[1]
image-927

Надеемся, вам понравится эти эффекты.

Демо / Исходники

Skeleton — быстрый старт

skeleton
image-818

В начале декабря Skeleton выпустила новую обновленную версию. На самом деле, это было его первое обновление для почти двух с половиной лет. Это хорошая новость для тех из нас, кто использовал его в прошлом и полюбили его простоту!

В этой статье я познакомлю вас с этим легким фреймворком.

Что такое Skeleton?

Как уже упоминалось выше, Skeleton  легкий CSS фреймворк, созданный Дейвом Гамашом. В частности, это два CSS файла: normalize.css и skeleton.css. Последний файл содержит стили фреймворка, это около 400 строк несжатого кода.

Наиболее важной частью скелета является грид система, которую я буду анализировать ниже. Кроме того, фреймворк обеспечивает основные стили для общих компонентов HTML таких как кнопки, списки, таблицы и формы.

Чтобы скачать последнюю версию Skeleton, вы можете перейти на официальный веб-сайт. Альтернативный вариант сделать форк с репозитория GitHub.

После загрузки и извлечения сжатую папку, ваша структура файла будет выглядеть следующим образом:

Skeleton/
├── css/
│     ├── normalize.css
│     └── skeleton.css
├── images/
│     └── favicon.png
└── index.html

Аналогично фреймворкам Bootstrap и Foundation, Skeleton также использует мобильный подход. Тем не менее, он не включает в себя большое количество компонентов; он содержит только некоторые основные правила CSS, которые помогут вам начать процесс разработки.

Стоит отметить, что Skeleton является полностью функциональным во всех последних браузерах, включая IE9 +. И наконец, вы также можете выбрать Sass или Less расширения Skeleton.

Изменения по сравнению с последней версией

Есть много различий между текущей версией и предшествующей ее. В таблице ниже приведены наиболее важные различия:

Особенности V2.0.2 (Current Version) V1.2 (Previous Version)
CSS файлов 2 3
Мобильный вид Да Нет
Grid 12 адаптивных столбцов 16 адаптивных столбцов
Типографские единицы rem px

Grid

Последняя версия Skeleton определяет сетку из 12 столбцов.

1421719099grid-example[1]
image-819

Строки должны быть размещены внутри обертки, которая может иметь максимум ширины 960px. Чтобы создать обертку вы должны определяете div элемент и применить container класс к нему. Если вы знакомы с сеткой Bootstrap, вы знаете, что Bootstrap использует то же имя класса, чтобы определить его обертку.

Ширина элемента обертки в Skeleton варьируется в зависимости от размера экрана. В любом случае, как уже упоминалось, он не может превышать 960px.

Колонны вложены в ряды. Они масштабируются до 12 для каждой строки. Чтобы настроить колону вы должны определить div элемент и назначить ему два класса. Во-первых, вы добавляете класс, который отвечает за определение ширины столбца. Чтобы добиться этого, вы можете использовать классы one до eleven (от одного до двенадцати) или one-third, two-thirds, и one-half.

7661

Второй класс отвечает за настройки полей столбцов. Возможные классы columns и column. Если вы определите ширину столбцов с первым вариантом (например, с помощью two класса), вы должны использовать columns класс (вместо column) в качестве второго класса. Исключением является при использовании one класса, который может быть в равной степени в сочетании с columns и column.

В то время как другие механизмы поддерживает вложенные строки, Skeleton рекомендует не использовать вложенные строки в столбцах. Кроме того, grid система Skeleton обеспечивает дополнительные классы для отступов столбцов. Смещение (например, offset-by-two) позволяют увеличить пространство между колоннами, добавив свойство margin-left.

Кнопки

Как уже упоминалось, фреймворк содержит дополнительные стили. Например, есть класс button, который позволяет обернуть ссылку(a) в виде кнопки. Также возможно сделать кнопку светло-голубого цвета с помощью класса button-primary.

7661

Формы

Формы это частая проблема для проекта, но здесь есть большое количество классов для облегчения работы с ними.

7661

Вывод

Skeleton отличный легкий CSS фреймворк, он подходит когда необходимо создать адаптивный дизайн но нет надобности в тяжелых фреймворках. Skeleton отлично подойдет для создания лэндингов.

Основы less

2
image-384

Less это препроцессор CSS, расширяющий его следующими плюшками:

  • Переменные
  • Примеси
  • Вложенные правила
  • Функции и операции
  • и др. возможности

 

Установка

Для установки понадобится node.js, а точнее его менеджер пакетов npm.

Запускаем командную строку:

npm install -g less

Установка завершена.

 

Использование

Есть два способа использовать less. Первый я использую в процессе разработки:

Подключаем наш файл less

<link rel="stylesheet/less" type="text/css" href="styles.less" />

Затем подключаем less.js для компиляции, он доступен здесь

<script src="less.js" type="text/javascript"></script>

Этот способ удобен тем что не надо каждый раз компилировать отдельно less файл в css, все работу делает компилятор автоматически при перезагрузке. Но когда проект завершен это не очень удобно, по этому компилируем less в css в командной строке:

lessc styles.less > styles.css

И подключаем css файл к нашему проекту.

Основные возможности less

less так как расширяет css то в нем само собой доступен весь его функционал. Но важнее то что мы получаем когда начинаtм использовать less

Переменные

Переменные в less — это константы которые задаются один раз.

@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;
#header {
  color: @light-blue;
}

После компиляции:

#header {
  color: #6c94be;
}

Примеси

Очень важнее и полезное свойство. Оно позволяет смешать(включить) один класс с другим.

Допустим у нас есть класс:

.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

И мы хотим использовать эти свойства в другом классе:

#menu a {
  color: #111;
  .bordered;
}
.post a {
  color: red;
  .bordered;
}

Это значительно сокращает наш код и облегчает его изменение и доработку.

Вложенные правил

Вложенные правила дают нам возможность использовать вложения вместо или в сочетании с каскадными таблицами. Скажем у нас есть CSS:

#header {
  color: black;
}
#header .navigation {
  font-size: 12px;
}
#header .logo {
  width: 300px;
}

В less он выглядел бы следующим образом:

#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}

Полученный код является более кратким, и он лучше показывает структуру вашего html файла.

Операции

Любое количество цвета или переменных может быть прооперировано. Вот несколько примеров:

@base: 5%;
@filler: @base * 2;
@other: @base + @filler;
color: #888 / 4;
background-color: @base-color + #111;
height: 100% / 2 + @filler;

Функции

У less есть много функций, которые трансформируют цвета, работают со строками и числами.

Работать с ними очень просто. Следующий пример использует процент, чтобы преобразовать от 0,5 до 50%, повышает насыщенность базового цвета на 5%, а затем устанавливает цвет фона на тот, который освещается на 25% и развернулся на 8 градусов:

@base: #f04615;
@width: 0.5;
.class {
  width: percentage(@width); // returns `50%`
  color: saturate(@base, 5%);
  background-color: spin(lighten(@base, 25%), 8);
}

Заключение

Здесь только часть возможностей которые доступны в less. Полный список и все обновления можно посмотреть на официальном сайте less. В начале кому то может показаться это сложным или абсолютно не нужным, но на самом деле потратив совсем немного времени даже на не его изучение, он не так сложен что бы долго его учить, а на привыкание работать с ним, вы значительно ускорите и облегчите свою работу.

Введение в Emmet — основные команды.

Как веб-разработчик, я всегда искали инструменты для увеличения скорости разработки и её производительность. Эта статья для веб-разработчиков, которые часто работают с HTML и CSS но еще не используют Emmet.

Установка

Emmet это плагин который помогает писать код на много быстрее. На оф.сайте Emmet можно скачать плагин для редактора который вы используете. Если вы используете Sublime Text, как я, Эммет может быть легко установлена ​​через Package Control.

install-emmet
image-166

HTML аббревиатуры

Инициализация

С emmet на создание html документа уходят считанные секунды. Стоит ввести всего лишь ! или html:5 и клавишу Tab.

initializers
image-167

  • html:5 или ! для HTML5
  • html:xt для XHTML
  • html:4s для HTML4

Добавление классов, id и других атрибутов

Поскольку синтаксис Emmet похож на описание селекторов в CSS, пользоваться им очень просто.

classes-ids
image-168

Кроме того, вы можете комбинировать классы и идентификаторы. Например команда p.bar#foo выведет:

<p class="bar" id="foo"></p>

Для содержания тегов используются фигурные скобки h1{foo}:

<h1>foo</h1>

А для атрибутов используются квадратные скобки a[href=#]:

<a href="#"></a>

texts-attrs
image-169

Вложенности

Селекторы > и + создают, соответственно, дочерние и соседние элементы, а селектор ^ позволяет подниматься в иерархии на один уровень.

nesting
image-170

Группировка

Чтобы эффективно использовать вложения, не включая их в беспорядочное месиво операторов, вам необходимо группировать некоторые куски кода. Это как математика — нужно просто использовать скобки вокруг определенных частей. Например, (.foo> h1) + (. Бар> h2) получится:

<div class="foo">
  <h1></h1>
</div>
<div class="bar">
  <h2></h2>
</div>

grouping
image-171

Скрытие имен тегов

Набрав код .item вы получите:

<div class="item"></div>

Но теперь emmet умнее, если вы объявите .item внутри , он сгенерирует:

<li class="item"></li>

implicit-tags
image-172

Вот список всех неявных имен тегов:

  • li для ul и ol
  • tr для table, tbody, thead и tfoot
  • td для tr
  • option для select и optgroup

Умножение

Вы можете определить, сколько раз элемент должен повторится с помощью операции *. Например ul>li*3 будет:

<ul>
  <li></li>
  <li></li>
  <li></li>
</ul>

multiplication
image-173

Нумерация

Для изменения названия класса или идентификатара с каждым следующим элементом необходимо просто добавить знак $, ul>li.item$*3, получим:

<ul>
  <li class="item1"></li>
  <li class="item2"></li>
  <li class="item3"></li>
</ul>

numbering
image-174

CSS аббревиатуры

Значение

В Emmet вы можете использовать для CSS сокращений. Допустим, вы хотите определить ширину. Введите w100, и получите:

width: 100px;

values
image-175

А команда h10p+m5e выведет:

height: 10%;
margin: 5em;

Вот список некоторых команд:

  • p → %
  • e → em
  • x → ex

Дополнительные параметры

Используя команды @f получим:

@font-face {
  font-family:;
  src:url();
}

Но некоторые свойства, такие как background-image, border-radius, font, @font-face, text-outline, text-shadow, имеют дополнительные параметры, которые можно активировать используя +. Используя @f+ мы получим:

@font-face {
  font-family: 'FontName';
  src: url('FileName.eot');
  src: url('FileName.eot?#iefix') format('embedded-opentype'),
     url('FileName.woff') format('woff'),
     url('FileName.ttf') format('truetype'),
     url('FileName.svg#FontName') format('svg');
  font-style: normal;
  font-weight: normal;
}

extra
image-176

Нестрогий поиск

Модуль CSS использует нестрогий поиск, чтобы найти неизвестную аббревиатуру. Так, каждый раз, когда вы вводите неизвестныю аббревиатуру, Emmet ищет ближайшее определение сниппета. Например: ov:h и ov-h и ovh и oh будет генерировать одно и то же:

overflow: hidden;

fuzzy-search
image-177

Префиксы

CSS3 отличная штука, но его префиксы очень сложные. Для них в Emmet есть тоже аббревиатуры. Например, аббревиатура trs даст нам:

-webkit-transform: ;
-moz-transform: ;
-ms-transform: ;
-o-transform: ;
transform: ;

vendor-prefixes
image-178

Вы также можете добавить префиксы к любому виду элемента. Вам просто нужно использовать — префикс. Так,-super-foo получим:

-webkit-super-foo: ;
-moz-super-foo: ;
-ms-super-foo: ;
-o-super-foo: ;
super-foo: ;

Что делать, если вы не хотите, чтобы выводились все атрибуты? Нет проблем. Вы можете точно определить, какие браузеры необходимо поддерживать. Например, -wm-trf выведет:

-webkit-transform: ;
-moz-transform: ;
transform: ;
  • w → -webkit-
  • m → -moz-
  • s → -ms-
  • o → -o-

Градиент

Говоря о раздражающих особенностей CSS3, мы не можем забыть градиенты. Эти длинные определения с различными обозначениями теперь могут быть легко заменены с краткой аббревиатурой. Пример lg(left, #fff 50%, #000):

background-image: -webkit-gradient(linear, 0 0, 100% 0, color-stop(0.5, #fff), to(#000));
background-image: -webkit-linear-gradient(left, #fff 50%, #000);
background-image: -moz-linear-gradient(left, #fff 50%, #000);
background-image: -o-linear-gradient(left, #fff 50%, #000);
background-image: linear-gradient(left, #fff 50%, #000);

gradient
image-179

На последок…

Это основы работы с замечательным плагином Emmet. Полный список команд вы можете посмотреть перейдя по ссылке на официальную документацию.

Равномерное распределение блоков на всю ширину

Часто при верстке необходимо равномерно распределить какие либо блоки или элементы на все ширину, при создании меню, галереи и тд. Вот небольшой пример как это можно сделать.

Сначала идет внешний блок .wrap

<div class="wrap">
</div>

Внешний элемент не обязательно должен быть div, он может быть и списком или тег-контейнером(main section header footer...)

Затем идут сами элементы. В данном случае это просто divы, но и тут могут быть почти любые элементы(a li img...)

<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>

Теперь CSS. Основное свойство для контейнера это text-align: justify

.wrap {
  text-align: justify;
}

А все элементы делаем inline-block

.wrap div{
  display: inline-block;
}

Если оставить так как есть сейчас, то у нас в одну строку элементы вообще работать не будет а в несколько строк будет работать все кроме последней строки. По этому добавляем следующий код:

.wrap:after {
  display: inline-block;
  content: "";
  width: 100%;
}

Демо пример:

See the Pen CydfI by roma (@romasport) on CodePen.

Выдвигающееся левое меню на чистом CSS

Все больше и больше сайтов используют значок с фиксированным положением, для раскрывающегося вывода меню. В то время как есть много JQuery плагинов, которые будут создавать этот эффект, это на самом деле довольно легко сделать не используя ни чего кроме CSS и HTML. Эта статья покажет вам, как сделать простой вариант бокового выдвигающегося меню с эффектом скольжения, используя только CSS.

Вот демо версия показывающая конечный результат:


See the Pen Awnjk7661


Начнем с HTML разметки

Это основная структура html разметки:

<ul class="navigation">
    <li class="nav-item"><a href="#">Home</a></li>
    <li class="nav-item"><a href="#">Portfolio</a></li>
    <li class="nav-item"><a href="#">About</a></li>
    <li class="nav-item"><a href="#">Blog</a></li>
    <li class="nav-item"><a href="#">Contact</a></li>
</ul>
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger"></label>
<div class="site-wrap">
    <!-- основная страница сайта -->
</div>

Вся разметка нашего сайта состоит из трех основных частей: меню навигации, чекбокса с label, и содержимое сайта.

    Основные моменты разметки:

  • Раздел навигации идет первым в разметке, потому что все остальные элементы находятся за меню. Вы можете использовать любые HTML теги какие вы хотите для построения меню. Здесь я использую неупорядоченный список.
  • Кнопка управления меню это чекбокс и label. Обычно label идет перед чекбоксом или обернут вокруг него. В нашем случае чекбокс должен идти непосредственно перед label. Мы увидим почему это так когда после добавления CSS.
  • Остальная часть нашего сайта должна быть заключена в уникальном div. Это объясняется тем, что, когда мы открываем меню, все остальное смещается немного правее, чтобы показать скрытые элементы навигации.

Теперь, когда мы получили структуру HTML, мы можем начать все красиво оформлять.

CSS для элементов меню

Давайте начнем с настройки меню и его элементов. Прежде всего, мы должны убедиться, что навигационное меню находится позади нашего контента и что оно остается на месте, даже если пользователь перемещается по странице:

.navigation {
   list-style: none;
   background: #111;
   width: 100%;
   height: 100%;
   position: fixed;
   top: 0;
   right: 0;
   bottom: 0;
   left: 0;
   z-index: 0;
}

Я добавил стили, чтобы настроить оформление нашего меню (фоновые цвета, границы, градиенты и т.д.). Я не буду повторять код здесь, но вы можете ознакомиться с ним в демо примере.

Теперь у нас есть красивые элементы меню, но все меню находится над страницей с контентом. Необходимо добавить стили, чтобы скрывать меню, пока же мы настроим страницу с контентом.

CSS для блока с контентом сайта

Для начала, давайте удостоверимся, что контент сайта полностью закрывает наше меню. Вы можете добавить несколько абзацев РыбаТекста в .site-wrap, если вы еще не добавили содержания.

.site-wrap {
   min-width: 100%;
   min-height: 100%;
   background-color: #fff;
   position: relative;
   top: 0;
   bottom: 100%;
   left: 0;
   z-index: 1;
}

Обратите внимание, что мы должны указать фон .site-wrap, иначе меню будет отображаться позади контента. Вы конечно можете использовать любой фоне который хотите. Я добавил следующие параметры:

.site-wrap {
   padding: 4em;
   background-image: linear-gradient(135deg,
   rgb(254,255,255) 0%,
   rgb(221,241,249) 35%,
   rgb(160,216,239) 100%);
   background-size: 200%;
}

CSS для кнопки меню

Теперь мы добавим стили, которые придадут нашим чекбоксу и label привычный всем вид, к которому все привыкли.

Прежде всего, давайте скроем чекбокс.

.nav-trigger {
   display: block;
   width: 0;
   height: 0;
}

Настройки displa: block важны. По умолчанию input элементы отображаться как inline-block, так что мы должны установить его как block, чтобы мы могли установить ширину и высоту до нуля. Если мы использовали бы display:none или visiblity: hidden то отключили бы взаимодействие клавиатуру с кнопкой меню, так что мы избежали этого.

Теперь давайте стилизуем элемент:

label[for="nav-trigger"] {
   position: fixed;
   top: 15px;
   left: 15px;
   z-index: 2;
}

Во-первых, мы установим position: fixed; теперь label будет на фиксированном месте во время прокрутки страницы. top и left свойства определяют, как далеко от края будет находится кнопка. Мы также установим z-index что бы кнопка была выше .site-wrap.

Далее, мы добавляем значок для кнопки.

label[for="nav-trigger"] {
   width: 30px;
   height: 30px;
   cursor: pointer;
   background-image: url("data:image/svg+xml;utf8,");
   background-size: contain;
}

Я использовал встроенный SVG в качестве фонового изображения, но вы можете использовать любой значок.

Обратите внимание, я также включил cursor: pointer; для визуального отображения интерактивности кнопки.

CSS для анимации

Теперь, когда наши стили меню и кнопки готовы, давайте добавим несколько строк CSS, которые анимируют все это.

.nav-trigger:checked + label {
   left: 215px;
}
.nav-trigger:checked ~ .site-wrap {
   left: 200px;
   box-shadow: 0 0 5px 5px rgba(0,0,0,0.5);
}

Второй блок гарантирует, что контент сайта сместится вправо на 200 пикселей. Я также добавил тень к блоку контента, чтобы придать ему дополнительный визуальный вид того, что она смешена.

Первый селектор (.nav-trigger:checked + label) контролирует положение триггера, когда меню открыто. Значение 215 получается из суммы значений 15 ( label[for="nav-trigger"] значение left) и 200 ( .nav-trigger:checked ~ .site-wrap значение left )

Это код где порядок элементов триггера становится важным. Второй селектор использует ~, селектор для .site-wrap, когда .nav-trigger отмечен.

.nav-trigger + label, .site-wrap {
   transition: left 0.2s;
}

И последнее, скрыть скрол по горизонтали.

body {
   overflow-x: hidden;
}

Готовый вариант

И вот оно! Мы успешно построил выдвигающееся меню навигации без JavaScript. Еще раз, демо версия:


See the Pen Awnjk7661


Теперь, когда вы знаете, как это делается, можно использовать разные вариации и настройка, пробуйте экспериментируйте.