Tutorial: How to Create a Responsive Website with AngularJS
in today’s tutorial, i’m going to show you the process of creating nearly an entire website with a new library – angularjs. however, i would like to introduce to you to angularjs first. angularjs is a magnificent framework by google for creating web applications. this framework lets you extend html’s syntax to express your application’s components clearly and succinctly, and lets you use standard html as your main template language. plus, it automatically synchronizes data from your ui with your js objects through 2-way data binding. if you’ve ever worked with jquery, the first thing to understand about angular is that this is a completely different instrument. jquery is a library, but angularjs is framework. when your code works with the library, it decides when to call a particular function or operator. in the case of the framework, you implement event handlers, and the framework decides at what moment it needs to invoke them. using this framework allows us to clearly distinguish between templates (dom), models, and functionality (in controllers). let’s come back to our template, take a look at our result: live demo download in package description this template is perfect for business sites. it consists of several static pages: projects, privacy, and about pages. each product has its own page. there is also a contact form for communication. that is all that is necessary for any small website. moreover, it is also a responsive template, thus it looks good on any device. i hope you liked the demo, so if you’re ready – let’s start making this application. please prepare a new folder for our project, and then create new folders in this directory: css – for stylesheet files images – for image files js – for javascript files (libraries, models, and controllers) pages – for internal pages stage 1. html the main layout consists of four main sections: a header with navigation, a hidden ‘contact us’ form, a main content section, and a footer. first we have to prepare a proper header: index.html as you can see, it’s an ordinary header. now – the header with the navigation: our projectsprivacy & termsaboutcontact us it's an ordinary logo, and the menu is the usual ul-li menu. the next section is more interesting – the ‘contact us’ form: contact us send message your message has been sent, thank you. finally, the last key element is the main content section: have you noticed the numerous ‘ng-’ directives? all these directives allow us to do various actions directly in the dom, for example: ng-class – the ngclass allows you to set css classes on an html element dynamically by databinding an expression that represents all classes to be added. ng-click – the ngclick allows you to specify custom behavior when element is clicked. ng-hide – the nghide directive shows and hides the given html element conditionally based on the expression provided to the nghide attribute. ng-include – fetches, compiles, and includes an external html fragment. ng-model – is a directive that tells angular to do two-way data binding. ng-show – the ngshow directive shows and hides the given html element conditionally based on the expression provided to the ngshow attribute. ng-submit – enables binding angular expressions to onsubmit events. stage 2. css in this rather large section, you can find all the styles used: css/style.css /* general settings */ html { min-height:100%; overflow-x:hidden; overflow-y:scroll; position:relative; width:100%; } body { background-color:#e6e6e6; color:#fff; font-weight:100; margin:0; min-height:100%; width:100%; } a { text-decoration:none; } a img { border:none; } h1 { font-size:3.5em; font-weight:100; } p { font-size:1.5em; } input,textarea { -webkit-appearance:none; background-color:#f7f7f7; border:none; border-radius:3px; font-size:1em; font-weight:100; } input:focus,textarea:focus { border:none; outline:2px solid #7ed7b9; } .left { float:left; } .right { float:right; } .btn { background-color:#fff; border-radius:24px; color:#595959; display:inline-block; font-size:1.4em; font-weight:400; margin:30px 0; padding:10px 30px; text-decoration:none; } .btn:hover { opacity:0.8; } .wrap { -moz-box-sizing:border-box; -webkit-box-sizing:border-box; box-sizing:border-box; margin:0 auto; max-width:1420px; overflow:hidden; padding:0 50px; position:relative; width:100%; } .wrap:before { content:''; display:inline-block; height:100%; margin-right:-0.25em; vertical-align:middle; } /* header section */ header { height:110px; } header .wrap { height:100%; } header .logo { margin-top:1px; } header nav { float:right; margin-top:17px; } header nav ul { margin:1em 0; padding:0; } header nav ul li { display:block; float:left; margin-right:20px; } header nav ul li a { border-radius:24px; color:#aaa; font-size:1.4em; font-weight:400; padding:10px 27px; text-decoration:none; } header nav ul li a.active { background-color:#c33c3a; color:#fff; } header nav ul li a.active:hover { background-color:#d2413f; color:#fff; } header nav ul li a:hover,header nav ul li a.activesmall { color:#c33c3a; } /* footer section */ footer .copyright { color:#adadad; margin-bottom:50px; margin-top:50px; text-align:center; } /* other objects */ .projectobj { color:#fff; display:block; } .projectobj .name { float:left; font-size:4em; font-weight:100; position:absolute; width:42%; } .projectobj .img { float:right; margin-bottom:5%; margin-top:5%; width:30%; } .paddrow { background-color:#dadada; color:#818181; display:none; padding-bottom:40px; } .paddrow.aboutrow { background-color:#78c2d4; color:#fff !important; display:block; } .paddrow .head { font-size:4em; font-weight:100; margin:40px 0; } .paddrow .close { cursor:pointer; position:absolute; right:50px; top:80px; width:38px; } .about { color:#818181; } .about section { margin:0 0 10%; } .about .head { font-size:4em; font-weight:100; margin:3% 0; } .about .subhead { font-size:2.5em; font-weight:100; margin:0 0 3%; } .about .txt { width:60%; } .about .image { width:26%; } .about .flleft { float:left; } .about .flright { float:right; } .projecthead.product { background-color:#87b822; } .projecthead .picture { margin-bottom:6%; margin-top:6%; } .projecthead .picture.right { margin-right:-3.5%; } .projecthead .text { position:absolute; width:49%; } .projecthead .centertext { margin:0 auto; padding-bottom:24%; padding-top:6%; text-align:center; width:55%; } .image { text-align:center; } .image img { vertical-align:top; width:100%; } .contactform { width:50%; } .input { -moz-box-sizing:border-box; -webkit-box-sizing:border-box; box-sizing:border-box; margin:1% 0; padding:12px 14px; width:47%; } .input.email { float:right; } button { border:none; cursor:pointer; } .textarea { -moz-box-sizing:border-box; -webkit-box-sizing:border-box; box-sizing:border-box; height:200px; margin:1% 0; overflow:auto; padding:12px 14px; resize:none; width:100%; } ::-webkit-input-placeholder { color:#a7a7a7; } :-moz-placeholder { color:#a7a7a7; } ::-moz-placeholder { /* ff18+ */ color:#a7a7a7; } :-ms-input-placeholder { color:#a7a7a7; } .loader { -moz-animation:loader_rot 1.3s linear infinite; -o-animation:loader_rot 1.3s linear infinite; -webkit-animation:loader_rot 1.3s linear infinite; animation:loader_rot 1.3s linear infinite; height:80px; width:80px; } @-moz-keyframes loader_rot { from { -moz-transform:rotate(0deg); } to { -moz-transform:rotate(360deg); } } @-webkit-keyframes loader_rot { from { -webkit-transform:rotate(0deg); } to { -webkit-transform:rotate(360deg); } } @keyframes loader_rot { from { transform:rotate(0deg); } to { transform:rotate(360deg); } } .view-enter,.view-leave { -moz-transition:all .5s; -o-transition:all .5s; -webkit-transition:all .5s; transition:all .5s; } .view-enter { left:20px; opacity:0; position:absolute; top:0; } .view-enter.view-enter-active { left:0; opacity:1; } .view-leave { left:0; opacity:1; position:absolute; top:0; } .view-leave.view-leave-active { left:-20px; opacity:0; } please note that css3 transitions are used, which means that our demonstration will only work modern browsers (ff, chrome, ie10+ etc) stage 3. javascript as i mentioned before, our main controller and the model are separated. the navigation menu can be handled here, and we also can operate with the contact form. js/app.js 'use strict'; // angular.js main app initialization var app = angular.module('example359', []). config(['$routeprovider', function ($routeprovider) { $routeprovider. when('/', { templateurl: 'pages/index.html', activetab: 'projects', controller: homectrl }). when('/project/:projectid', { templateurl: function (params) { return 'pages/' + params.projectid + '.html'; }, controller: projectctrl, activetab: 'projects' }). when('/privacy', { templateurl: 'pages/privacy.html', controller: privacyctrl, activetab: 'privacy' }). when('/about', { templateurl: 'pages/about.html', controller: aboutctrl, activetab: 'about' }). otherwise({ redirectto: '/' }); }]).run(['$rootscope', '$http', '$browser', '$timeout', "$route", function ($scope, $http, $browser, $timeout, $route) { $scope.$on("$routechangesuccess", function (scope, next, current) { $scope.part = $route.current.activetab; }); // onclick event handlers $scope.showform = function () { $('.contactrow').slidetoggle(); }; $scope.closeform = function () { $('.contactrow').slideup(); }; // save the 'contact us' form $scope.save = function () { $scope.loaded = true; $scope.process = true; $http.post('sendemail.php', $scope.message).success(function () { $scope.success = true; $scope.process = false; }); }; }]); app.config(['$locationprovider', function($location) { $location.hashprefix('!'); }]); pay attention here. when we request a page, it loads an appropriate page from the ‘pages’ folder: about.html, privacy.html, index.html. depending on the selected product, it opens one of the product pages: product1.html, product2.html, product3.html or product4.html in the second half, there are functions to slide the contact form and to handle its submit process (to the sendemail.php page). next is the controller file: js/controllers.js 'use strict'; // optional controllers function homectrl($scope, $http) { } function projectctrl($scope, $http) { } function privacyctrl($scope, $http, $timeout) { } function aboutctrl($scope, $http, $timeout) { } it is empty, because we have nothing to use here at the moment. stage 4. additional pages angularjs loads pages asynchronously, thereby increasing the speed. here are templates of all additional pages used in our project: pages/about.html about us script tutorials is one of the largest web development communities. we provide high quality content (articles and tutorials) which covers all the web development technologies including html5, css3, javascript (and jquery), php and so on. our audience are web designers and web developers who work with web technologies. additional information promo 1 lorem ipsum dolor sit amet, consectetur adipiscing elit. nunc et ligula accumsan, pharetra nibh nec, facilisis nulla. in pretium semper venenatis. in adipiscing augue elit, at venenatis enim suscipit a. fusce vitae justo tristique, ultrices mi metus. ..... pages/privacy.html privacy & terms by accessing this web site, you are agreeing to be bound by these web site terms and conditions of use, all applicable laws and regulations, and agree that you are responsible for compliance with any applicable local laws. if you do not agree with any of these terms, you are prohibited from using or accessing this site. the materials contained in this web site are protected by applicable copyright and trade mark law. other information header 1 lorem ipsum dolor sit amet, consectetur adipiscing elit. nunc et ligula accumsan, pharetra nibh nec, facilisis nulla. in pretium semper venenatis. in adipiscing augue elit, at venenatis enim suscipit a. fusce vitae justo tristique, ultrices mi metus. ..... pages/footer.html copyright © 2013 script tutorials pages/index.html product #1 product #2 product #3 product #4 finally, the product pages. all of them are prototypes, so i decided to publish only one of them. pages/index.html product 1 page lorem ipsum dolor sit amet, consectetur adipiscing elit. nunc et ligula accumsan, pharetra nibh nec, facilisis nulla. in pretium semper venenatis. in adipiscing augue elit, at venenatis enim suscipit a. fusce vitae justo tristique, ultrices mi metus. lorem ipsum dolor sit amet, consectetur adipiscing elit. nunc et ligula accumsan, pharetra nibh nec, facilisis nulla. in pretium semper venenatis. in adipiscing augue elit, at venenatis enim suscipit a. fusce vitae justo tristique, ultrices mi metus. download the app finishing touches – responsive styles all of these styles are needed to make our results look equally good on all possible mobile devices and monitors: @media (max-width: 1200px) { body { font-size:90%; } h1 { font-size:4.3em; } p { font-size:1.3em; } header { height:80px; } header .logo { margin-top:12px; width:200px; } header nav { margin-top:11px; } header nav ul li { margin-right:12px; } header nav ul li a { border-radius:23px; font-size: 1.3em; padding:10px 12px; } .wrap { padding:0 30px; } .paddrow .close { right:30px; } } @media (max-width: 900px) { .contactform { width:100%; } } @media (max-width: 768px) { body { font-size:80%; margin:0; } h1 { font-size:4em; } header { height:70px; } header .logo { margin-top:20px; width:70px; } header nav { margin-top:8px; } header nav ul li { margin-right:5px; } header nav ul li a { border-radius:20px; font-size:1.1em; padding:8px; } .wrap { padding:0 15px; } .projectobj .name { font-size:3em; } .paddrow { padding-bottom:30px; } .paddrow .head { font-size:3em; margin:30px 0; } .paddrow .close { right:20px; top:60px; width:30px; } .projecthead .picture { width:67%; } .projecthead .picture.right { margin-right:16.5%; } .projecthead .text { position:static; width:100%; } .projecthead .centertext { width:70%; } .view-enter,.view-leave { -webkit-transform:translate3d(0,0,0); transform:translate3d(0,0,0); } } @media (max-width: 480px) { body { font-size:70%; margin:0; } header { height:50px; } header .logo { display:none; } header nav { margin-top:3px; } header nav ul li { margin-right:3px; } header nav ul li a { border-radius:20px; font-size:1.3em; padding:5px 14px; } #contactbtn { display:none; } .wrap { padding:0 10px; } .paddrow { padding-bottom:20px; } .paddrow .head { margin:20px 0; } .paddrow .close { right:10px; top:45px; width:20px; } .about .image { margin:10% auto; width:60%; } .about .abicon { display:inline; } .projecthead .centertext { width:90%; } .about .txt,.input { width:100%; } .about .flleft,.about .flright,.input.email { float:none; } } live demo download in package conclusion that’s all for today. thanks for your patient attention, and if you really like what we did today, share it with all your friends in your social networks.
October 10, 2013
by Andrey Prikaznov
·
312,284 Views
·
10 Likes