流体式布局与响应式布局_响应式水平布局

流体式布局与响应式布局

流体式布局与响应式布局

Responsive Horizontal Layout

Today we want to show you how to create a horizontal layout with several content panels. The idea is to make each panel individually scrollable and animate a content panel to the left of the viewport once it’s clicked or selected from the menu. The challenge is to deal with different viewport sizes meaning that we will change the layout if the screen is not wide enough in order to be stacked vertically instead of horizontally.

今天,我们想向您展示如何使用多个内容面板创建水平布局。 其想法是使每个面板可单独滚动,并在从菜单中单击或选择视口左侧的内容面板后为其设置动画。 挑战在于处理不同的视口大小,这意味着如果屏幕不够宽以便垂直堆叠而不是水平堆叠,我们将更改布局。

We will be using a couple of useful jQuery plugins:

我们将使用几个有用的jQuery插件:

In the demo we are using Charles Darwin’s The Origin of Species by means of Natural Selection, 6th Edition which you can find as an e-book on Project Gutenberg.

在演示中,我们使用的是查尔斯·达尔文(Charles Darwin)的《自然起源的物种起源》第六版,您可以将其作为古腾堡计划的电子书找到。

标记 (The Markup)

The HTML will be built up of a menu that will be fixed at the left side and a container with all the individual panels inside. All will be wrapped by a main container:

HTML将由一个固定在左侧的菜单和一个内部装有所有单独面板的容器组成。 全部将由主容器包装:


<div id="hs-container" class="hs-container">

	<!-- ... -->
	
</div>

The menu will have the following structure:

菜单将具有以下结构:


<aside class="hs-menu" id="hs-menu">

	<div class="hs-headline">
		<h1>
			<small>The</small> 
			Origin <small>of</small> 
			Species
		</h1>
		<small>6<sup>th</sup> Edition</small>
		<span class="author">by Charles Darwin</span>
	</div>
	
	<nav>
		<a href="#introduction">
			<span>Introduction</span>
		</a>
		<a href="#chapter1">
			<span>Chapter I.</span>
			<span>Variation under Domestication</span>
		</a>
		<a href="#chapter2">
			<span>Chapter II.</span>
			<span>Variation Under Nature </span>
		</a>
		<!-- ... -->
	</nav>
	
</aside>

<a href="#hs-menu" class="hs-totop-link">Go to the top</a>

We’ll have a headline and a navigation. We’ve also added a loose helper link that we’ll need to show for smaller screens where we will stack the content vertically.

我们将提供标题和导航。 我们还添加了一个松散的帮助程序链接,该链接需要显示在较小的屏幕上,在该屏幕上我们将垂直堆叠内容。

The content will have the following structure:

内容将具有以下结构:


<div class="hs-content-scroller">

	<div class="hs-content-wrapper">
	
		<article class="hs-content" id="introduction">
			<div class="hs-inner">
				<h2>Introduction</h2>
				<p>...</p>
			</div>
		</article>
		
		<article class="hs-content" id="chapter1">
			<div class="hs-inner">
				<h2>Chapter I.</h2>
				<h3>Variation Under Domestication</h3>
				<h4>Causes of Variability</h4>
				<p>...</p>
			</div>
		</article>
		
		<!-- ... -->
		
	</div>
	
</div>

The first wrapper with the class hs-content-scroller will act like a mask, having the width and height that is visible in the viewport. This will be the division that we’ll scroll horizontally because the second wrapper with the class hs-content-wrapper will be as wide as the sum of all article widths.

具有hs-content-scroller类的第一个包装将充当蒙版,其宽度和高度在视口中可见。 这将是我们将水平滚动的分区,因为带有hs-content-wrapper类的第二个包装器的宽度将等于所有文章宽度的总和。

As you can see, each article will get an ID which we link to in our navigation.

如您所见,每篇文章都将获得一个ID,我们可以在导航中链接到该ID。

Let’s style this thing.

让我们设计这个东西。

CSS (The CSS)

So, our main aim is to fix the sidebar at the left side of the screen and place the content as a horizontal stack. Let’s first style the body and some headings. We’ll set both, overflow-x and overflow-y to hidden. We use the separate properties instead of the single “overflow” because we want to adjust something in a media query later, but we’ll get back to that.

因此,我们的主要目的是将侧栏固定在屏幕的左侧,并将内容作为水平堆栈放置。 首先让我们设计一下身体和一些标题。 我们将溢出x和溢出y都设置为隐藏。 我们使用单独的属性而不是单个的“溢出”,因为我们想稍后在媒体查询中进行调整,但我们将继续讨论。

We’ll first import the normalize.css, a really nice and sensible alternative to the common resets:

我们将首先导入normalize.css ,这是普通重置的一种非常不错且明智的选择:


@import url('normalize.css');

body{
	font-family: Baskerville, "Hoefler Text", Garamond, "Times New Roman", serif;
	background: #e9f0f5 url(../images/pattern.png) repeat top left;
	font-weight: 400;
	font-size: 12px;
	color: #333;
	overflow-y: hidden;
	overflow-x: hidden;
}

Next, let’s define some general text styles:

接下来,让我们定义一些常规的文本样式:


h1, h3, h4{
	font-weight: 400;
}
h1{
	font-style: italic;
	border-bottom: 1px solid rgba(126, 126, 126, 0.3);
	padding: 35px 15px 15px 15px;
	margin: 0px 20px 20px 20px;
	position: relative;
	font-size: 38px;
}
h2{
	font-size: 40px;
	padding-bottom: 15px;
	border-bottom: 5px solid rgba(190, 211, 226, 0.2);
	color: #a9becd;
	text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.4);
	box-shadow: 0px 1px 0px 0px rgba(255, 255, 255, 0.4);
	font-weight: 700;
}
h3{
	font-style: italic;
	font-size: 26px;
	color: #585959;
	text-shadow: 1px 0px 1px rgba(255, 255, 255, 0.4);
}
h4{
	text-transform: uppercase;
	letter-spacing: 5px;
	line-height: 20px;
	padding: 10px 0px;
	color: #626a6f;
	border-bottom: 1px solid rgba(126, 126, 126, 0.1);
	box-shadow: 0px 1px 0px 0px rgba(255, 255, 255, 0.4);
}
a{
	color: #308fd9;
	text-decoration: none;
	text-transform: uppercase;
	letter-spacing: 2px;
}
a:hover{
	color: #87b6da;
}
.hs-headline{
	text-align: center;
}
.hs-author{
	text-transform: uppercase;
	display: block;
	letter-spacing: 2px;
	font-weight: 700;
	padding: 20px 10px;
}

Now, let’s position the menu:

现在,让我们放置菜单:


.hs-menu{
	position: fixed;
	z-index: 100;
	color: #f8f8f8;
	background: #131313;
	width: 200px;
	left: 0px;
	top: 0px;
	height: 100%;
}

Setting its position to fixed, we’ll stick the sidebar to the left side of the screen. The navigation will have the following style:

将其位置设置为固定,我们将侧栏粘贴到屏幕的左侧。 导航将具有以下样式:


.hs-menu nav{
	position: absolute;
	top: 250px;
	left: 0px;
	right: 0px;
	bottom: 50px;
}

The position of the navigation will be absolute and by setting a top and bottom value, we have a flexible height. Later, we will add custom scrolling to the navigation so that we don’t have to worry about the menu items fitting into the area.

导航的位置将是绝对的,并且通过设置最高和最低值,我们可以灵活调整高度。 稍后,我们将自定义滚动添加到导航中,这样我们就不必担心适合该区域的菜单项。

The anchors will have the following style:

锚点将具有以下样式:


.hs-menu nav a{
	display: block;
	padding: 10px 20px;
	text-align: center;
	outline: none;
	border-bottom: 1px dashed rgba(126, 126, 126, 0.2);
}
.hs-menu nav a:active{
	box-shadow: 7px 0px 17px #000 inset;
}
.hs-menu nav a:first-child{
	border-top: 1px dashed rgba(126, 126, 126, 0.2);
}

The second span in a navigation anchor will be styled differently:

导航锚中的第二个跨度将具有不同的样式:


.hs-menu nav a span:nth-child(2){
	display: block;
	color: #fff;
	font-style: italic;
	font-weight: 400;
	text-transform: none;
	padding-top: 3px;
}

Now, let’s style the content part. As mentioned before, the division with the class .hs-content-scroller will be acting as a mask where any overflow won’t be visible. This is basically the same principle as in sliders. The left will be set to 200 pixel because of the sidebar:

现在,让我们对内容部分进行样式设置。 如前所述,使用类.hs-content-scroller进行的划分将充当掩码,其中任何溢出都将不可见。 这基本上与滑块相同。 由于侧边栏,左侧将设置为200像素:


.hs-content-scroller{
	position: absolute;
	left: 200px;
	right: 0px;
	overflow: hidden;
	height: 100%;
}

The next wrapper will have a width which allows all the inner content panels to fit inside of it if stacked horizontally. We’ll set the overflow to hidden, because each of our content panels will have a custom scroll bar.

下一个包装纸的宽度将允许所有内部内容面板在水平堆叠的情况下都适合其内部。 我们将溢出设置为隐藏,因为我们的每个内容面板都有一个自定义滚动条。


.hs-content-wrapper{
	width: 7950px;
	position: absolute;
	height: 100%;
	overflow: hidden;
}

Each content panel is going to have a width of 500 pixel and float left. We’ll add a transition for the background when we hover and when we add a active class:

每个内容面板的宽度为500像素,并向左浮动。 当我们悬停并添加活动类时,我们将为背景添加一个过渡:


.hs-content{
	width: 500px;
	overflow-y: scroll;
	height: 100%;
	float: left;
	border-right: 1px dashed rgba(126, 126, 126, 0.2);
	border-left: 1px dashed rgba(255, 255, 255, 0.5);
	background: transparent;
	transition: background 0.3s linear;
}
.hs-content:hover, .hs-content-active{
	background: #f1f5f8;
}

When we add the custom scrolling to the content panels, we only want them to be visible when we hover over them:

在将自定义滚动添加到内容面板时,我们只希望将鼠标悬停在它们上方时可见它们:


.hs-content:hover .jspVerticalBar,
.hs-menu nav:hover .jspVerticalBar{
	opacity: 1;
}

The first content panel will be a bit narrower:

第一个内容面板将缩小一点:


.hs-content:first-child{
	width: 400px;
}

Let’s add some padding and style the text elements:

让我们添加一些填充并设置文本元素的样式:


.hs-inner{
	padding: 30px 20px 10px 30px;
}
.hs-inner p{
	font-size: 18px;
	line-height: 24px;
	text-align: justify;
	position: relative;
	padding: 10px 0px;
	text-shadow: 1px 0px 1px rgba(255, 255, 255, 0.8);
}
.hs-inner p:first-letter{
	font-size: 28px;
}
#introduction .hs-inner p:first-of-type{
	font-size: 24px;
	text-align: left;
	line-height: 36px;
	font-style: italic;
	color: #75838D;
	letter-spacing: 0px;
}

Remember that little anchor right after the sidebar? When clicking that anchor, the page will scroll up. We’ll only need this anchor when our screen is not big enough to stack the content panels horizontally but only vertically, so we’ll set it to display: none initially. In a media query we’ll then show it.

还记得侧边栏之后的那个小锚点吗? 单击该锚点后,页面将向上滚动。 我们仅在屏幕不够大时才需要该锚点,以至于不能水平堆叠内容面板,而只能垂直堆叠内容面板,因此我们将其设置为显示:最初没有显示。 在媒体查询中,我们将显示它。


a.hs-totop-link{
	display: none;
	position: fixed;
	z-index: 10000;
	bottom: 0px;
	width: 100%;
	height: 40px;
	line-height: 40px;
	font-size: 14px;
	color: #aaa;
	text-shadow: 1px 1px 1px #fff;
	font-weight: 700;
	cursor: pointer;
	text-transform: uppercase;
	text-align: center;
	background: linear-gradient(top, #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%);
	border-top: 1px solid #cacaca;
}

When we reach the size of the iPad, we want to get rid of the hover behavior and show the horizontal scrollbar. This will allow us to “swipe” the content on the iPad:

当我们达到iPad的大小时,我们想要摆脱悬停行为并显示水平滚动条。 这将使我们能够“擦除” iPad上的内容:


/* Media Queries */
@media screen and (max-width: 1024px) {
	.jspVerticalBar{
		opacity: 1;
	}
	.hs-content-scroller{
		overflow-x: scroll;
	}
	.hs-content:hover{
		background: transparent;
	}
	.hs-content-active:hover {
		background: #f1f5f8;
	}
}

At this point, we’ll change the layout in order to be stacked vertically. We have to “reset” all the properties that forced the content to be stacked horizontally. We’ll also show the anchor that will bring us back to the top:

此时,我们将更改布局以便垂直堆叠。 我们必须“重置”所有迫使内容水平堆叠的属性。 我们还将显示将使我们回到顶部的锚点:


@media screen and (max-width: 715px) {
	body{
		overflow-x: auto;
		overflow-y: auto;
	}
	a.hs-totop-link{
		display: block;
	}
	.hs-menu{
		position: relative;
		width: 100%;
		height: 460px;
	}
	.hs-menu nav{
		top: 230px;
		bottom: 20px;
	}
	.hs-content-scroller{
		position: relative;
		height: auto;
		left: 0;
	}
	.hs-content-wrapper{
		height: auto;
		width: auto;
		margin-left: 0px;
	}
	.hs-content{
		border: none;
	}
	.hs-content, .hs-content:first-child{
		width: auto;
		float: none;
		overflow-y: auto;
	}
}

And that’s all the style! Now, let’s take a look at the JavaScript!

这就是所有样式! 现在,让我们看一下JavaScript!

JavaScript (The JavaScript)

First, we will set some variables and cache some elements:

首先,我们将设置一些变量并缓存一些元素:



var $container			= $( '#hs-container' ),
	// the scroll container that wraps the articles
	$scroller			= $container.find( 'div.hs-content-scroller' ),
	$menu				= $container.find( 'aside' ),
	// menu links
	$links				= $menu.find( 'nav > a' ),
	$articles			= $container.find( 'div.hs-content-wrapper > article' ),
	// button to scroll to the top of the page
	// only shown when screen size < 715
	$toTop				= $container.find( 'a.hs-totop-link' ),
	// the browser nhistory object
	History 			= window.History,
	// animation options
	animation			= { speed : 800, easing : 'easeInOutExpo' },
	// jScrollPane options
	scrollOptions		= { verticalGutter : 0, hideFocus : true },


The init function will be the first one to execute:

初始化函数将是第一个执行的函数:



init				= function() {
				
	// initialize the jScrollPane on both the menu and articles
	_initCustomScroll();
	// initialize some events
	_initEvents();
	// sets some css properties 
	_layout();
	// jumps to the respective chapter
	// according to the url
	_goto();
	
},


The first step is to create / initialize the jScrollPane (the custom scrollbars) on both the menu and the articles. However, for the articles, we will not do this in case the screen size is smaller than 715px:

第一步是在菜单和文章上创建/初始化jScrollPane(自定义滚动条)。 但是,对于文章,如果屏幕尺寸小于715像素,我们将不这样做:



_initCustomScroll	= function() {
	
	// Only add custom scrolling to articles if screen size > 715.
	// If not, the articles will be expanded (vertical layout)
	if( $(window).width() > 715 ) {
	
		$articles.jScrollPane( scrollOptions );
	
	}
	// add custom scrolling to menu
	$menu.children( 'nav' ).jScrollPane( scrollOptions );

},


We will load the events for the window, the menu links and the articles.

我们将加载窗口,菜单链接和文章的事件。

On window resize, we will need to reinitialize the jScrollPane custom scrollbars, or destroy them in case the screen's size gets smaller than 715px.

在调整窗口大小时,我们将需要重新初始化jScrollPane自定义滚动条,或者在屏幕尺寸小于715px的情况下销毁它们。

On window statechange, we will jump to the respective state / chapter. We are using History.js by Benjamin Lupton to control the history states when the user navigates through the page:

在窗口状态更改时,我们将跳至相应的状态/章节。 当用户浏览页面时,我们使用Benjamin Lupton的History.js来控制历史记录状态:



$(window).on({
	// when resizing the window we need to reinitialize or destroy the jScrollPanes
	// depending on the screen size
	'smartresize' : function( event ) {
		
		_layout();
		
		$('article.hs-content').each( function() {
			
			var $article 	= $(this),
				aJSP		= $article.data( 'jsp' );
			
			if( $(window).width() > 715 ) {
				
				( aJSP === undefined ) ? $article.jScrollPane( scrollOptions ) : aJSP.reinitialise();
				
				_initArticleEvents();
				
			}	
			else {
				
				// destroy article's custom scroll if screen size <= 715px
				if( aJSP !== undefined )
					aJSP.destroy();
				
				$container.off( 'click', 'article.hs-content' );
				
			}
			
		});
		
		var nJSP = $menu.children( 'nav' ).data( 'jsp' );
		nJSP.reinitialise();
		
		// jumps to the current chapter
		_goto();
	
	},
	// triggered when the history state changes - jumps to the respective chapter
	'statechange' : function( event ) {
		
		_goto();
	
	}
});


When we click on an article or menu link, we will check to which chapter it refers to, and we will change the state of the browser history object. This will trigger the statechange event which in turn will make the page / scrolling division jump to the respective area.

当单击文章或菜单链接时,我们将检查它所指向的章节,并更改浏览器历史记录对象的状态。 这将触发状态更改事件,从而使页面/滚动部分跳转到相应区域。



$links.on( 'click', function( event ) {
					
	var href		= $(this).attr('href'),
		chapter		= ( href.search(/chapter/) !== -1 ) ? href.substring(8) : 0;
	
	_saveState( chapter );
	
	return false;

});

$container.on( 'click', 'article.hs-content', function( event ) {
					
	var id			= $(this).attr('id'),
		chapter		= ( id.search(/chapter/) !== -1 ) ? id.substring(7) : 0;
	
	_saveState( chapter );
	
	return false;

});

_saveState			= function( chapter ) {
				
	// adds a new state to the history object
	// this will trigger the statechange on the window
	if( History.getState().url.queryStringToJSON().chapter !== chapter ) {
			
		History.pushState( null, null, '?chapter=' + chapter );
	
	}

},


We will also control the overflow property of the "scroller" (divison with class "hs-content-scroller") according to the screen size.

我们还将根据屏幕尺寸控制“ scroller”的溢出属性(类为“ hs-content-scroller”)。



_layout				= function() {

	var windowWidth	= $(window).width();
	switch( true ) {
	
		case ( windowWidth <= 715 ) : $scroller.scrollLeft( 0 ).css( 'overflow', 'visible' ); break;
		case ( windowWidth <= 1024 ): $scroller.css( 'overflow-x', 'scroll' ); break;
		case ( windowWidth > 1024 ) : $scroller.css( 'overflow', 'hidden' ); break;
	
	};
	
},

The _goto function triggers the animation for changing the area / chapter on the page. We get the current chapter from the history state URL, and given the respective article we either scroll to the left or top depending on the screen size. Also, if we are in landscape mode, the element scrolling is the div "hs-content-scroller", otherwise it's the BODY element.

_goto函数触发动画以更改页面上的区域/章节。 我们从历史记录状态URL中获取当前章节,并根据屏幕尺寸将相应的文章滚动到左侧或顶部。 另外,如果我们处于横向模式,则元素滚动为div“ hs-content-scroller”,否则为BODY元素。



_goto				= function( chapter ) {
				
	// get the url from history state (e.g. chapter=3) and extract the chapter number
var chapter 	= chapter || History.getState().url.queryStringToJSON().chapter,
	isHome		= ( chapter === undefined ),
	// we will jump to the introduction chapter if theres no chapter
	$article 	= $( chapter ? '#' + 'chapter' + chapter : '#' + 'introduction' );

	if( $article.length ) {

			// left / top of the element
		var left		= $article.position().left,
			top			= $article.position().top,
			// check if we are scrolling down or left
			// is_v will be true when the screen size < 715
			is_v		= ( $(document).height() - $(window).height() > 0 ),
			// animation parameters:
			// if vertically scrolling then the body will animate the scrollTop,
			// otherwise the scroller (div.hs-content-scroller) will animate the scrollLeft
			param		= ( is_v ) ? { scrollTop : (isHome) ? top : top + $menu.outerHeight( true ) } : { scrollLeft : left },
			$elScroller	= ( is_v ) ? $( 'html, body' ) : $scroller;
		
		$elScroller.stop().animate( param, animation.speed, animation.easing, function() {
			
			// active class for selected chapter
			$articles.removeClass( 'hs-content-active' );
			$article.addClass( 'hs-content-active' );
			
		} );

	}

},


And that's it! I hope you enjoyed this tutorial and find it useful!

就是这样! 我希望您喜欢本教程并发现它有用!

翻译自: https://tympanus.net/codrops/2012/04/02/responsive-horizontal-layout/

流体式布局与响应式布局

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值