如果您最近看过YouTube,则可能会注意到其网站布局中有一个明显的遗漏。 他们的设计缺乏在调整浏览器窗口大小时进行响应折叠的能力。 奇怪的是,布局甚至没有缩小为更小的宽度。 目前,YouTube是使用固定宽度的网页设计的。
我想引入一些现代的网页设计技巧,并为YouTube主页重新设计。 在本教程中,我将说明我们如何从头开始构建自定义的,响应移动设备的YouTube克隆布局。
我将使用一些较新HTML5和CSS3技术,大多数现代浏览器都支持这些技术。
创建结构
为了让我们开始,我们应该创建一个具有典型HTML5文档类型的index.html页面。 由于这是一种移动响应式布局,因此我们还需要包括一些特定的元标记。
在这个项目中,我将把我们JavaScript和CSS代码分成不同的文件,您可以在下面的代码中看到类似的内容:
<!doctype html>
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Demo sliding menu test</title>
<meta name="author" content="Jake Rocheleau">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<link rel="shortcut icon" href="favicon.ico">
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" type="text/css" href="css/styles.css">
<link rel="stylesheet" type="text/css" href="css/responsive.css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/jquery-ui.min.js"></script>
<script type="text/javascript" src="js/retina.js"></script>
<script type="text/javascript" src="js/scripts.js"></script>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
因此,除了视口元标记外,我还包含了一系列外部文档。 样式表styles.css和响应 .css包含用于典型布局和响应媒体查询的设计规则。
另外,我包括来自Google CDN托管的两个JS库: jQuery和jQuery UI 。 随着布局的缩小,两者都将派上用场,我们使用滑动动画来显示导航菜单。
该动画与scripts.js文件绑定在一起,我将保留所有自定义jQuery代码。 另外,我还有另一个名为retina.js的第三方脚本,这是迄今为止解决视网膜显示图像的最简单方法。
如果您访问retina.js网站 ,则会找到其缩小库的下载链接。 只需将其包含在您的文档中,脚本就会自动扫描图像中@ 2x的变化(在视网膜设备上)。
更敏感的倾向
对于本特定教程,我采用了一种非典型的网站设计技术方法。
当我们的布局以950像素全屏显示时,您会看到两个侧边栏以及中心视频内容。 但是,当您浏览到最小帧(大约320像素)时,您只会看到中间的列和顶部的工具栏区域。
该工具栏将具有一个菜单切换按钮,您可以点击它来回滑动。 在我的演示中,没有任何菜单链接可用,因为我们现在没有任何包含内容的页面。 但是您可以使用新的HREF值更新这些锚链接,以使它们在真实的网站上运行。
让我仅复制文档正文中的顶部标题和导航代码。
<body>
<div id="w" class="clearfix">
<header id="fulltop">
<span id="logomini"><a href="index.html"><img src="design-responsive-youtube/logo-mini.png" alt="YouTube - Broadcast Yourself"></a></span>
<span id="userlogin">
<img src="design-responsive-youtube/avatar-sm.png" alt="default user pic" class="defaultphoto">
<a href="javascript:void(0)">Log In</a>
</span>
<div id="searchbox">
<form id="searchform" name="searchform" action="#" method="get">
<input type="text" name="s" id="s" class="searchbar" placeholder="" tabindex="1">
<input type="submit" name="sbtn" id="sbtn" value="" tabindex="2">
</form>
<ul id="topsidelinks">
<li><a href="javascript:void(0)">Browse</a></li>
<li><a href="javascript:void(0)">Featured</a></li>
<li><a href="javascript:void(0)">Upload</a></li>
</ul>
</div>
</header>
<nav>
<ul id="sidenav">
<li class="heading">User Account</li>
<li><a href="#login" class="signin"><i></i>Sign In</a></li>
<li><a href="#register" class="register"><i></i>Register</a></li>
<li class="heading">Video Categories</li>
<li><a href="#popular" class="popular"><i></i>Popular</a></li>
<li><a href="#recent" class="recent"><i></i>Recently Uploaded</a></li>
<li><a href="#comedy" class="comedy"><i></i>Comedy</a></li>
<li><a href="#entertainment" class="entertainment"><i></i>Entertainment</a></li>
<li><a href="#film" class="film"><i></i>Film & Animation</a></li>
<li><a href="#gaming" class="gaming"><i></i>Gaming</a></li>
<li><a href="#people" class="people"><i></i>People & Blogs</a></li>
</ul>
</nav><!-- end navigation menu -->
因此,包装在我们体内的所有内容都在另一个包装ID为#w
包装div内。 这样我们可以将页面内容固定在中心位置,并将最大宽度限制在950像素左右。 但是在标题标签中,您会注意到许多功能未在较小的屏幕上显示。 我们在CSS内使用@media
查询来限制何时显示搜索栏和顶部链接。
此外,滑动导航菜单将始终隐藏在较小的屏幕上。 一旦您的浏览器宽度超过600像素,侧面导航就会自然显示为正文容器中的左列。 这就是无论响应情况如何,这些链接都应始终正常工作的原因。
常用网页样式
我想跳入讨论CSS代码的一些重要块。 首先,我们需要了解核心主体如何居中以及为什么在调整窗口大小时两列布局会下降。
现在,如您先前所见,这些规则被分为两个文档,因此最容易理解的方法是直接下载我的源代码。
/* page structure */
#w {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
max-width: 950px;
min-width: 300px;
height: 100%;
margin: 0 auto;
overflow: hidden;
position: relative;
display: block;
-webkit-box-shadow: 0px 0px 9px rgba(0,0,0,0.65);
-moz-box-shadow: 0px 0px 9px rgba(0,0,0,0.65);
box-shadow: 0px 0px 9px rgba(0,0,0,0.65);
}
#pageWrapper { display: block; width: 100%; }
#page {
display: block;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
min-height: 650px;
position: relative;
top: 0;
background: #fff;
z-index: 999;
padding: 0;
-webkit-box-shadow: -4px 0px 9px -4px rgba(0,0,0,0.65);
-moz-box-shadow: -4px 0px 9px -4px rgba(0,0,0,0.65);
box-shadow: -4px 0px 9px -4px rgba(0,0,0,0.65);
}
#content { display: block; padding: 10px 14px; }
#fulltop { display: none; visibility: hidden; }
#secondary { display: none; visibility: hidden; }
最初,我们从视图中隐藏了顶部标题部分和辅助侧边栏。 所有HTML仍在我们的文档中,但是在宽度超过600像素之前,这些都不会显示。
辅助侧边栏实际上一直隐藏到800px,因为布局中根本没有足够的空间。
/* header */
#topbar {
display: block;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
height: 60px;
padding: 0px 6px;
padding-top: 10px;
text-align: center;
border-bottom: 1px solid #677282;
background-color: #6279a3;
background-image: -webkit-gradient(linear, left top, left bottom, from(#8da1c2), to(#6279a3));
background-image: -webkit-linear-gradient(top, #8da1c2, #6279a3);
background-image: -moz-linear-gradient(top, #8da1c2, #6279a3);
background-image: -ms-linear-gradient(top, #8da1c2, #6279a3);
background-image: -o-linear-gradient(top, #8da1c2, #6279a3);
background-image: linear-gradient(top, #8da1c2, #6279a3);
-webkit-box-shadow: 0px 1px 0px rgba(255,255,255,0.5) inset;
-moz-box-shadow: 0px 1px 0px rgba(255,255,255,0.5) inset;
box-shadow: 0px 1px 0px rgba(255,255,255,0.5) inset;
}
#logo { position: relative; top: -5px; }
#slidelink {
display: block;
font-size: 0.01em;
line-height: 1.8em;
width: 50px;
height: 35px;
position: relative;
top: 2px;
left: 10px;
background: url('../design-responsive-youtube/menu.png') top left no-repeat;
float: left;
z-index: 999;
}
所有标题代码都与带有蓝色渐变背景的响应式移动顶部导航工具栏有关。 除了通过滑动按钮使用背景图片之外,我们都通过CSS3创建了所有这些内容。
对于视网膜设备,我包括了菜单图标的@ 2x副本以及所有来自Glyphish图标包的侧边栏图标。
使用CSS背景图片时,我们不能依赖retina.js脚本。 这样只会解析使用HTML5 <img>
标记加载到页面中的<img>
。 取而代之的是,我们需要在样式表中创建新的响应规则,名为响应 .css 。
我已经复制了下面的代码块:
/* retina display devices only */
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
#slidelink { background: url('../design-responsive-youtube/menu@2x.png') top left no-repeat; background-size: 50px 35px; }
#sbtn { background: url('../design-responsive-youtube/search@2x.png'); background-size: 24px 24px; }
#sidenav li a.signin i { background-image: url('../design-responsive-youtube/user@2x.png'); background-size: 24px 21px; }
#sidenav li a.register i { background-image: url('../design-responsive-youtube/gear@2x.png'); background-size: 26px 26px; }
#sidenav li a.popular i { background-image: url('../design-responsive-youtube/star@2x.png'); background-size: 26px 26px; }
#sidenav li a.recent i { background-image: url('../design-responsive-youtube/coffee@2x.png'); background-size: 24px 26px; }
#sidenav li a.comedy i { background-image: url('../design-responsive-youtube/mic@2x.png'); background-size: 12px 24px; }
#sidenav li a.entertainment i { background-image: url('../design-responsive-youtube/tv@2x.png'); background-size: 24px 24px; }
#sidenav li a.film i { background-image: url('../design-responsive-youtube/film@2x.png'); background-size: 20px 25px; }
#sidenav li a.gaming i { background-image: url('../design-responsive-youtube/joystick@2x.png'); background-size: 22px 20px; }
#sidenav li a.people i { background-image: url('../design-responsive-youtube/pencil@2x.png'); background-size: 23px 23px; }
}
background-size
属性和@ 2x副本是执行所有魔术的地方。 我们需要将图像压缩两倍于典型的大小限制。
在视网膜设备上,相比自然图像看起来模糊和放大,这看起来要好得多。
重要的响应式CSS块
对于熟悉使用该语法的Web开发人员而言,许多响应代码应该很简单。 但是,我将从响应.css文档中复制其他部分,并说明布局效果。
/* first responsive changes between mobile and desktop layout */
@media only screen and (min-width: 600px) {
#sidenav { z-index: 999; width: 250px; }
#page { z-index: 1; padding-left: 250px; }
#topbar { display: none; visibility: hidden; }
#fulltop { display: block; visibility: visible; height: 45px; padding: 8px 14px; border-bottom: 1px solid #d8d8d8; }
#logomini { display: block; float: left; margin-right: 40px; }
#searchform { display: block; float: left; }
#s {
width: 310px;
border: 1px solid #ccc;
padding: 8px 7px;
color: #999;
background: #f7f7f7;
font-size: 1.45em;
text-shadow: 0px 1px 0px #fff;
outline: none;
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.5) inset;
-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.5) inset;
box-shadow: 0 1px 3px rgba(0,0,0,0.5) inset;
-webkit-transition: all .4s linear;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
-moz-transition: all .4s linear;
transition: all .4s linear;
}
#s:focus { color: #666; background: #fff; border-color: #b8b8b8; }
#sbtn { cursor: pointer; width: 24px; height: 24px; border: 0; background: none; background-image: url('../design-responsive-youtube/search.png'); position: relative; top: -4px; left: -35px; opacity: 0.7; }
#sbtn:hover { cursor: pointer; }
当您的浏览器视口达到600像素时,整个布局应立即更改。 我们不再使用切换菜单,现在希望将其公开显示为左侧边栏。
我们还需要更改旧的响应式工具栏的可见性,并显示#fulltop
标头div。
另外,您可能会从搜索字段中使用CSS3过渡和框阴影效果中受益匪浅。 这些效果在大多数浏览器(包括Firefox,Opera,Safari和IE9-10)中应具有完全相同的效果。
这是一个很好的附加功能,使该YouTube布局具有现代美感。
/* as the layout widens display a secondary sidebar and top user links */
@media only screen and (min-width: 810px) {
#userlogin { display: block; float: right; margin-right: 35px; margin-top: 4px; height: 30px; line-height: 30px; }
#userlogin .defaultphoto { display: block; float: left; border: 1px solid #ddd; margin-right: 3px; }
#userlogin a { line-height: 35px; }
#secondary { display: block; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; visibility: visible; width: 240px; padding: 10px 14px; z-index: 999; position: absolute; right: 0; }
#secondary h2 { font-size: 1.3em; font-weight: bold; font-style: italic; line-height: 1.45em; color: #66666d; margin-bottom: 7px; }
.videoblock { display: block; visibility: visible; width: 100%; }
.videoblock a .vidimg { display: block; visibility: visible; }
.videoblock a { display: block; width: 100%; margin-bottom: 7px; padding: 5px 0px; text-decoration: none; border-bottom: 1px solid #fff; }
.videoblock a:hover { border-bottom: 1px solid #ebebeb; background: #f6f6f6; }
.videoblock a .vidimg img { display: inline-block; visibility: visible; border: 1px solid #cdcdcd; }
.videoblock a h4 { font-weight: bold; font-size: 1.3em; color: #333; margin-bottom: 1px; }
.videoblock a:hover h4 { color: #5a7aaa; }
.videoblock a .uploader { display: block; font-size: 1.1em; color: #666669; }
.videoblock a .views { display: block; font-size: 1.1em; color: #666669; }
.videoblock a:hover .uploader, .videoblock a:hover .views { color: #525252; }
#page { padding-right: 240px; }
}
现在,一旦浏览器窗口略大于800px,此响应代码的最后一部分即会生效。 除了其他类似的代码块之外,我还包括了一个支持“功能视频”的辅助侧栏区域。
由于本教程的重点是响应式代码的工作,因此我没有包含太多虚拟内容。 但是,此新的辅助侧边栏非常适合无法放置在较小布局中的额外页面内容。
您可能还会注意到,这些样式在完整的顶部标题显示中添加了一小组链接。 当用户登录时,这是呈现更多与个人资料相关的链接的绝佳机会。 这些可能与用户帐户设置,收藏的视频,频道订阅或最近上传的内容有关。
用jQuery开发JS
我已经在scripts.js资产文件中构建了两个核心功能:每当用户点击我们的移动响应菜单时,它就会相应地打开/关闭面板,如果用户打开菜单然后调整浏览器大小,则所有内容被推到右边。
在这种情况下,我们需要处理菜单是否已打开并且浏览器的大小是否足以隐藏菜单,然后重新放置主要内容区域。 我将把这些代码片段分为两个部分。
var page = $("#page");
// show and hide navigation menu
$("a#slidelink").on("click", function(e){
e.preventDefault();
var position = page.position();
var winwidth = $(window).width();
if(position.left == 0) {
$(page).animate(
{ left: '+=240px' },
250,
'easeOutBack',
function() {
// callback
});
} else {
$(page).animate(
{ left: '-=240px' },
400,
'easeOutCirc',
function() {
// callback
});
}
});
#slidelink
指的是显示在顶部移动工具栏区域中的菜单按钮。 每当用户单击此链接时,我们就会找到页面内容的当前位置。 如果左侧位置返回的值为0,则表明菜单仍处于关闭状态,我们需要将其打开。
如果该值是除0以外的任何值,那么我们可以假定菜单已经打开,并且正在考虑将其关闭。
这两种效果都使用jquery .animate()方法,这就是为什么我们还包括jQuery UI库副本的原因。 没有一个回调函数处于活动状态,但是很容易添加您自己的代码。
这些动画完成后,您可以在内部放置要执行的任何内容。
// check content position on browser resize
var resizeTimer;
$(window).resize(function() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(resetPagePosition, 150);
});
function resetPagePosition() {
var position = page.position();
var winwidth = $(window).width();
if(winwidth >= 600 && position.left != 0) {
// if the window is above 600px and the menu is open we need to reset back into position
$(page).animate({left: "0px"}, 110);
}
};
每当菜单打开并且浏览器窗口的大小调整到足以隐藏它时,第二个功能将处理页面内容的重新定位。 附加到窗口对象的此事件处理程序侦听jQuery的.resize()方法。 我已将计时器设置为150毫秒,因此该功能在调整大小后不会立即触发。
可以在我的自定义函数resetPagePosition()
找到所有交互式代码。 在函数内部,我创建了另一个position变量来确定页面的位置。
如果左值不为0,则表明菜单已打开,并且现在已通过600px阈值。 这是清除此烦人的bug的较简单解决方案,如果您使用任何类型的滑动移动菜单技术,则可能会遇到该bug。
演示与下载
随时体验实时演示版,看看是否可以在台式机,笔记本电脑,平板电脑或智能手机上获得有效的解决方案。
最后的想法
我希望本教程展示了构建响应式网站的一些关键特征。 如果移动设备直接支持该网站,则YouTube的开发人员可能会吸引更多对该网站的关注。 YouTube确实有自己的移动子域,但体验却不尽相同。
如果您对本教程有任何疑问或意见,可以在下面的帖子讨论区与我们分享。
翻译自: https://www.hongkiat.com/blog/design-responsive-youtube/