In the first part of this series, we learned how to design a modern agency portfolio in Photoshop.
Now it’s time to convert the Photoshop design to a working HTML5/CSS3 website. We are also going to use a little bit of javascript to filter the portfolio items and add additional functionality to our site. To filter the portfolio, we’ll use the techniques discussed in this article.
To increase our speed and productivity, we’re going to use the LESS pre-processor. LESS is an extension of the CSS language that allows us to use variables, functions and will help us structure our code better.
To compile the LESS files you can use Prepros, Koala, Gulp, Grunt or CodeKit and many others. I’m currently using Prepros, it’s free, runs on Windows, Mac and Linux and has a nice user interface so that we won’t have to use the terminal to compile the files.
Final Result:
Resources used
- Bootstrap 3
- Shuffle.JS
- jQuery throttle / debounce
- pictures from Lorempixel
- pictures from Lorempicsum
- Pictures from PlaceKitten
- Pictures from Picjumbo
- Pictures from Unsplash
- Geometric background from Onextrapixel
- Roboto font from Google Fonts
- Open Sans font from Google Fonts
- Icon fonts from Font Awesome
1. Setting up the project
Step 1 – Project structure
Create a main project folder and name it The Agency. Inside this folder create a new HTML file – index.html and a folder to store our images – img.
Step 2 – Download Bootstrap 3
Grab a copy of Bootstrap 3 from the site.Download and extract the archive in the folder project.
You’ll now have 3 folders: css, fonts, js.
In the CSS folder create a new folder named LESS and copy the bootstrap.css file inside and rename it to bootstrap.less.
The js folder will contain our javascripts. The only file that we need right now it’s the bootstrap.min file.
Step 3 – Download Shuffle.JS and jQuery throttle / debounce
To add the portfolio filter functionality, we have to download the Shuffle.js plugin. After you extract the archive, go to the dist folder and copy the jquery.shuffle.modernizr.min to our project js folder.
Now we have to download the jQuery throttle / debounce plugin. This plugin allows us to add a short delay between our filtered items, ensuring that our script runs properly.
Grab the minified file and paste it in our project’s js folder.
If you want, you can combine the minified jQuery throttle / debounce with the minfied shuffle.js and only use one file.
Step 4 – Image slicing
The next stop is slicing the images that we will use in our design.
Let’s start with the logo. Open the PSD Template in Photoshop. Select the logo icon, right click it and select Duplicate layer
Select a New Destination:
Now we simply have to remove the space around the layer:
To save the file, go to File > Save for web and save the file as a PNG to preserve the transparency. To optimize the file size even further, you can use an image optimizer service like TinyPNG.
To slice the needed elements, simply repeat the previous steps. Since we’re using icon fonts and images provided from placeholder images providers, you only have to slice the hero background, CTA background and testimonials background. After you finish slicing the rest of the images, copy them to the img folder.
After following all the steps, our folder structure should look like this:
Step 5 – Folder watching
The last step that we have to follow to set-up our project is to watch our project folder for changes. Our “watcher” will check for any changes in the LESS and will automatically convert the LESS files to CSS.
To watch a folder, simply drag and drop the folder in your favorite compiler and instruct the compiler what files and folders to watch.
If you’re using a compiler without a GUI, you have to use the terminal and manually set-up the folders and files.
2. The basic structure
Step 1 – Basic Boostrap template
In the index.html file copy & paste the content from Bootstrap’s Basic Template. In the CSS -> LESS folder create a style.less file and in the js folder add a custom.js file.
Now we have to link the css and the js to the index.html file. The css is linked in the header
and the js in the footer
To link the FontAwesome stylesheet paste in the head
the following code:
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
.
Go to Google Fonts and add the Open Sans and Roboto fonts. Add this code in the head
:
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,400,400italic,600,700|Roboto:400,700,400italic' rel='stylesheet' type='text/css'>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> <title>The Agency portfolio</title> <link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet"> <link href='http://fonts.googleapis.com/css?family=Open+Sans:300,400,400italic,600,700|Roboto:400,700,400italic' rel='stylesheet' type='text/css'> <link href="css/styles.css" rel="stylesheet"> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <!-- Include all compiled plugins (below), or include individual files as needed --> <script src="js/bootstrap.min.js"></script> <script src="js/jquery.shuffle.min.js"></script> <script src="js/custom.js"></script> </body> </html> |
Step 2 – Basic CSS Rules
We can finally start our custom CSS and establish some site rules:
- headings and buttons are using the Roboto font
- text content uses the Open Sans Light font with a size of 16px and a color of
#808080
and the line height of 24pt - The site’s color is
#2980b9
and is used for the links, primary buttons and headings - To break the monotony, some sections have a very light blue color:
#f1f5f8
- The elements border color is
#c7cad1
- The spacing and padding between the elements are based on the baseline grid:
half a baseline (12px), 1 baseline (24px), 2 baseline (48px).
One of the reasons I use a CSS pre – processor is the ability to set up variables for colors, fonts, margins and general rules and then to easily use them in our style sheet without having to remember hex values for colors, font-families or margins. Basically, you have to create the rules once and then use them everywhere. Variables also come in handy if you want to change site’s color or create a template variation: you can go to variables, change the color, fonts, etc and the settings will propagate immediately since we are using the variable name, not the value.
Another advantage of using a pre-processor is that our code will be faster to write and it will look better. For example, instead of writing:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.header-top { background-color: #2980b9; color: #ffffff; padding: 0.75rem 0; } .header-top ul { margin-bottom: 0; } .header-top .contact .fa { margin-right: 0.75rem; } .header-top .contact li { margin-right: 2.25rem; } |
you can write the code like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
.header-top { background-color: @color-accent; color: @color-text-light; padding: @margin/2 0; ul { margin-bottom: 0; } .contact { .fa { margin-right: @margin/2; } li { margin-right: 2.25rem; } } } |
Create a file named variables.less. We’ll define the colors, basic font rules and a small less mixin. Since we have LESS variables, we can easily use them in our style sheet to increase our speed and productivity. I picked the color values, fonts, margins directly from our PSD document.
The transition
mixin is used to speed our development, so that we can directly call this mixin without having to specify the transition properties if we only need to transition an element’s color and we are ok with the parameters that we set.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/*============================================= = LESS VARIABLES = =============================================*/ /*========== COLORS ==========*/ @color-text: #808080; //regular text @color-text-light: #FFF; //light text @color-accent: #2980b9; //blue color @color-alternate: #f1f5f8; //very light blue @color-dark: #34495e; //dark blue @color-border: #c7cad1; //light grey @color-light-bg: #f5f5f5; //very light grey /*========== TYPOGRAPHY ==========*/ @font-size: 1em; //16px @baseline: (@font-size * 1.5); //@font-size*1.5 @margin: 1.5rem; @font-body: "Open Sans", Helvetica, Arial, sans-serif; @font-header: "Roboto", Helvetica, Arial, sans-serif; /*========== MIXINS ==========*/ .transition (@property: color, @duration: .3s, @effect: ease-in) { transition: @property @duration @effect; } |
We can now establish the typography rules. Create a typography.less file. Now we can use the variables defined in variables.less.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
/*============================================= = TYPOGRAPHY = =============================================*/ html { font-size: @font-size; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } body { font: @font-size ~"/" @baseline @font-body; color: @color-text; -webkit-font-smoothing: antialiased; } a, a:hover, a:focus { text-decoration: none; outline: none; .transition(); } p { margin: 0 0 @margin 0; font-weight: 300; a { color: @color-accent; &:hover { color: @color-text; } } } h1, h2, h3, h4, h5 { font-family: @font-header; color: @color-text; line-height: 1.2; margin-bottom: @margin; } h1 { font-size: 3rem; } h2 { font-size: 2.25rem; } h3 { font-size: 1.5rem; text-transform: uppercase; } h4 { font-size: 1.125rem; text-transform: uppercase; } h5 { font-size: 1rem; text-transform: uppercase; font-weight: 500; } h6 { font-size: 1rem; text-transform: uppercase; font-family: @font-body; font-weight: 600; margin-bottom: @margin; } .heading { h2 { color: @color-accent; text-transform: uppercase; font-weight: 600; margin: 0; } margin-bottom: @margin*2; } .subheading { font-family: @font-header; font-size: 1rem; font-style: italic; text-transform: lowercase; } |
Step 3 – Styles.less
The styles.less will be the file that will link all our less files together.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/********************************************************************************** Project Name: The Agency Project Description: A tutorial for AcasA Programming File Name: styles.css Author: Gabi Neagu Author URI: acasaprogramming.ro Version: 1.0.0 **********************************************************************************/ @import 'bootstrap.less'; @import 'variables.less'; @import 'typography.less'; |
3. The Header
We’ll base our HTML on the Bootstrap 3 examples.
Step 1 – HTML
Place the following code right bellow the head
element:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<body data-spy="scroll" data-target=".collapse" data-offset="96"> <header> <div class="header-top" id="home"> <div class="container clearfix"> <ul class="contact list-inline pull-left"> <li><i class="fa fa-envelope"></i>office@theagency.com</li> <li><i class="fa fa-phone"></i>555-123-456</li> </ul> <ul class="social-icons list-inline pull-right"> <li><a href="#"><i class="fa fa-google"></i></a></li> <li><a href="#"><i class="fa fa fa-facebook"></i></a></li> <li><a href="#"><i class="fa fa-twitter"></i></a></li> <li><a href="#"><i class="fa fa-dribbble"></i></a></li> <li><a href="#"><i class="fa fa-github"></i></a></li> </ul> </div><!--end container top--> </div><!--end header-top --> <nav class="navbar clearfix" role="navigation" id="navigation"> <div class="container"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed button button-full" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#"><img class="logo" src="img/logo.png" alt="The Agency Logo"><h1>The Agency</h1></a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav navbar-right"> <li class="active"> <a href="#home">Home <span class="sr-only">(current)</span></a> </li> <li><a href="#services">Services</a></li> <li><a href="#portfolio">Portfolio</a></li> <li><a href="#about">About Us</a></li> <li><a href="#testimonials">Testimonials</a></li> <li><a href="#blog">Blog</a></li> <li><a href="#contact">Contact</a></li> </ul> </div> <!-- /.navbar-collapse --> </div> <!-- /.container-fluid --> </nav> </header> |
The body
HTML element has some attributes that allows Bootstrap’s JavaScript to change the active menu item when the user scrolls the page. The data-target
attribute must point to a div that contains the navigation items. data-offset
is used to offset the scroll by the amount of site’s header height, in our case 96 pixels.
header-top
is a divider used to display the contact information and social icons in the top header. list-inline
, pull-left
and pull-right
are Bootstrap utilities classes used to remove the list styling and display the list items inline, to float elements to left and right, respectively. To display the contact and social icons I used font icons from FontAwesome. Find the icon you need, click and copy the HTML code provided.
To keep our HTML as semantically correct as possible, we used a nav
HTML tag to store our logo and navigation. clearfix
is a Bootstrap class that clears the floats. The button in the header is only displayed on smaller resolutions and toggles the navigation. Note the data-target
points to the menu items div
.
Step 2 – CSS
To keep our CSS organized and maintainable, inside the less folder create a new file named header.less If you ever want to change the header style, you can now easily find the CSS in one small file responsible just with that. Don’t forget to add an import rule in our styles.less: @import 'header.less';
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
/*========== TOP HEADER STYLE ==========*/ .header-top { background-color: @color-accent; color: @color-text-light; padding: @margin/2 0; ul { margin-bottom: 0; } .contact { .fa { margin-right: @margin/2; } li { margin-right: 2.25rem; } } .social-icons { li { margin-right: @margin/2; &:last-child { margin-right: 0; } } } a { color: @color-text-light; &:hover { color: darken(@color-text-light, 15%); } } } /*========== HEADER STYLE ==========*/ .navbar-fixed-top { top:0; .navbar-right { margin-right: 0; } } .navbar { background-color: #fff; border-radius: 0; border: none; margin-bottom: 0; box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.15); .logo { display: inline-block; margin-right: @margin/2; } h1 { color: @color-accent; display: inline-block; font-size: 1.125rem; text-transform: uppercase; line-height: 1.1; } } .navbar-toggle { padding: @margin/2; .icon-bar { background-color: @color-text-light; } } .navbar-nav > li { margin-top: 1.3125rem; margin-right: @margin; &:last-child { margin-right: 0; } } .navbar-nav > li > a { font-family: @font-header; font-size: 0.875rem; font-weight: 700; text-transform: uppercase; color: @color-text; } .navbar-nav > .open > a, .navbar-nav > .open > a:hover, .navbar-nav > .open > a:focus, .navbar-nav > .active > a, .navbar-nav > .active > a:hover, .navbar-nav > .active > a:focus, .navbar-nav > li > a:hover { color: @color-accent; border-bottom: 3px solid @color-accent; padding-bottom: 2.0625rem; background: none; } body { position: relative; //for scrollspy } |
Now it’s time to put the variables defined in the variables.less to good use.
For readability, I commented the code and split in the top part of the header and header style. This is a good practice and you should always comment your code.
First, we established the look of our header by defining the color, padding and margins. The fa
is a FontAwesome class and we added a right margin, so that the icons won’t clash with our contact information.
For our social icons I added a margin right between the elements and removed the last item’s margin by using the CSS pseudo-class last-child
. To style our social icons hover state, I used another CSS pseudo-class – :hover
and darken the color by 15% using the darken
function.
navbar-fixed-top
is a classed added to our header only when the user scrolls down the page. It makes the header “sticky” by fixing it to the top of the browser and removing the blue top header. I added a soft shadow to our white header by using the CSS property box-shadow
. The other styles overwrite Bootstrap’s default styles. To know which class to overwrite, in your browser, simply right click an element and select Inspect element and copy the Bootstrap class that adds default style to your element.
Open the index.html in your browser:
4. Hero section
Now that we finished the header, we can start working on our hero area. This section features a large background image, a heading and a subheading and 2 call – to – action buttons.
Step 1 – The HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!-- section hero --> <div class="container-fluid text-center"> <div class="row"> <section class="hero hero-front-bg"> <div class="overlay"> <h2 class="hero-header">Welcome to <span>The Agency<span></h2> <div class="hero-subheading">We create <span>high-quality</span> websites</div> <p class="hero-buttons"> <a href="#" class="button button-lg button-ghost">View our portfolio</a> <a href="#" class="button button-lg button-full">Let's work together!</a> </p> </div> </section> <!--end hero section --> </div> <!--end row --> </div><!-- end container-fluid --> |
container-fluid
is a Bootstrap class that will always have the same width as the browser. Our hero section has a class of hero
and hero-front-bg
. The hero
class is a reusable class that we will use throughout our design and has some general rules regarding the background image settings and font settings. The hero-front-bg
is responsible with the background image location.
The overlay
class will darken our image so that our text will be easily visible. hero-header
and hero-subheading
are 2 previously defined classes in the typography.less file. We used span
tags in our heading and subheading to apply our site color to the text.
Our links have 3 button classes. The button
class defines the general style of the button, button-lg
indicates a large button and button-ghost
has the necessary styles to create a ghost button.
Step 2 – The UI CSS
Our button and form styles are defined in a file named ui.less. Import it in our styles.less: @import 'ui.less';
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
/*================================= = UI STYLES = =================================*/ /*========== BUTTONS ==========*/ .button-lg { padding: @margin/2 @margin; } .button-md { padding: @margin/4 @margin/2; } .button { border-radius: 5px; border: 2px solid @color-accent; font-family: @font-header; font-size: 0.875rem; font-weight: 700; text-transform: uppercase; .transition(all); } .button-ghost { color: @color-accent; &:hover { color: #fff; background-color: @color-accent; } } .button-secondary { border: 1px solid @color-border; color: @color-text; font-weight: 400; background: transparent; &:hover { color: #fff; background-color: @color-accent; border: 1px solid @color-accent; font-weight: 700; } } .button-ghost-inverse { color: @color-text-light; border-color: @color-text-light; background: transparent; &:hover { color: #fff; background-color: darken(@color-accent, 15%); border-color: darken(@color-accent, 20%); .transition(all); } } .button-full { color: @color-text-light; background-color: @color-accent; &:hover { color: #fff; background-color: darken(@color-accent, 15%); .transition(all); } } |
In this file we defined all the button styles that will use in our design. Since our code is modular, to crate additional styles we only have to modify some paddings and colors.
In our button
class we defined the border and border radius, used font variable to specify the font family and we added a transition effect using our mixin. Then we created additional styles for the ghost and full buttons and secondary buttons.
Step 3 – The header CSS
With button styles defined in the ui.less file, we can start designing our hero section.
Create a new less file – main.less and import it in our styles.less file: @import 'main.less';
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
/*================================ = MAIN CSS = ================================*/ /*========== HERO SECTION ==========*/ .hero { background-size: cover; background-attachment: fixed; background-position: center center; background-color: @color-text; text-transform: uppercase; color: @color-text-light; } .hero-front-bg { background-image: url("../img/hero-bg.png"); height: (@margin * 23); } .overlay { background-color: rgba(0, 0, 0, 0.7); height: 100%; } .hero-header { color: @color-text-light; font-size: 3rem; margin-top: 0; span { color: @color-accent; } padding-top: 10rem; } .hero-subheading { font-size: 1.5rem; font-family: @font-body; font-weight: 600; span { color: @color-accent; } background-color: rgba(0, 0, 0, 0.3); display: inline-block; padding: @margin/2 @margin; margin-bottom: @margin*3; } .hero-buttons { a { margin-right: @margin/2; } } |
To scale our background with respect to the browser size, I used the CSS property background-size: cover;
. If you want to create a parallax effect, you can use background-attachment: fixed;
. This will create the parallax effect without using JavaScript. Since our code is modular, we’re going to reuse this class when we’ll build the testimonials section.
To create an overlay effect, I set the alpha-transparency to 70%: background-color: rgba(0, 0, 0, 0.7);
in our overlay class.
In the hero-subheading class I used the display: inline-block;
to make sure that on lower resolutions the text will be displayed on its own line.
Result:
5. Services section
Let’s move on and proceed to create the services section. This section features 3 columns that display some basic information about our fictional agency. To create the 3 columns we’re going to take full advantage of Bootstrap 3 grid system and use the built-in classes: col-md-4
and col-sm-4
. Col-sm-4 targets small devices, like tablets. Read more about Bootstrap 3 grid here.
Step 1 – Services Section HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<!--section services --> <section class="section-services add-padding" id="services"> <div class="container"> <div class="row"> <div class="heading text-center"> <h2>Services</h2> <p class="subheading">read about our high quality services</p> </div> <div class="col-md-4 col-sm-4"> <div class="service-box text-center"> <span class="icon"> <i class="fa fa-paint-brush"></i> </span> <h4>Web Design</h4> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam distinctio dolorem sed aspernatur, odit, ex blanditiis corporis atque officia dignissimos molestias</p> </div><!--end service box--> </div><!--end col-md-4--> <div class="col-md-4 col-sm-4"> <div class="service-box text-center"> <span class="icon"> <i class="fa fa-cog"></i> </span> <h4>Web Development</h4> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam distinctio dolorem sed aspernatur, odit, ex blanditiis corporis atque officia dignissimos molestias</p> </div><!--end service box--> </div><!--end col-md-4--> <div class="col-md-4 col-sm-4"> <div class="service-box text-center"> <span class="icon"> <i class="fa fa-life-ring"></i> </span> <h4>24/7 support</h4> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam distinctio dolorem sed aspernatur, odit, ex blanditiis corporis atque officia dignissimos molestias</p> </div><!--end service box--> </div><!--end col-md-4--> </div> <!-- end row --> </div><!-- end container --> </section><!--end section services--> |
Step 2 – Utilities.less
All site’s section have padding, so we need to create an add-padding class. Some sections have a very light blue background and we can create a class called alternate-bg
.
Add the following code in a new fie named utilities.less:
1 2 3 4 5 6 7 8 9 10 11 |
/*========== UNIVERSAL STYLING UTILITIES ==========*/ .add-padding { padding: @margin*2 0; } .alternate-bg { background-color: @color-alternate; } |
Step 3 – Services Section CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
/*========== SERVICES SECTION ==========*/ .service-box { .icon { .fa { font-size: 2.25rem; border: 2px solid @color-accent; border-radius: 50%; width: 7.5rem; height: 7.5rem; padding-top: 2.5rem; color: @color-accent; margin-bottom: @margin; } } h4 { text-transform: none; margin-top: 0; font-size: 1.5rem; } &:hover { .fa { color: @color-text-light; background-color: @color-accent; .transition(); } h4 { color: @color-accent; .transition(); } } p { margin-bottom: 0; } } |
Since our main css styles are already defined by Bootstrap or by our previous rules, we just have to create the icon circle and add some hover effects.
To create a rounded border, we have to set the border radius to 50%: border-radius: 50%;
The width and height of the circle is set to 5 margins or 7.5rem.
Our services section should look like this now:
6. Portfolio section
The portfolio is a very important section for agencies and freelancers. It’s the place to showcase your best work and engage potential clients.
To build our portfolio we’ll use the techniques covered in our previous tutorial.
Step 1 – Portfolio Section HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
<!--section portfolio --> <section class="section-portfolio add-padding alternate-bg" id="portfolio"> <div class="container"> <div class="row"> <div class="heading text-center"> <h2>Portfolio</h2> <p class="subheading">our best works</p> </div> <ul class="text-center list-inline portfolio-sorting"> <li><a href="#" class="active" data-group="all">All</a></li> <li><a href="#" data-group="web">Web Design</a></li> <li><a href="#" data-group="app">App Design</a></li> <li><a href="#" data-group="photo">Photography</a></li> </ul> <ul class="portfolio-items clearfix" id="grid"> <li class="col-md-4 col-sm-4 col-xs-6 " data-groups='["web"]'> <figure class="portfolio-item"> <a href="#"> <img src="http://placekitten.com/700/400" alt="" class="img-responsive"> </a> <figcaption class="item-caption"> <div class="item-description"> <h5>Cool website</h5> <p class="description hidden-xs hidden-sm">Cool website description</p> </div> </figcaption> </figure> </li> <li class="col-md-4 col-sm-4 col-xs-6 " data-groups='["app", "photo"]'> <figure class="portfolio-item"> <a href="#"> <img src="http://lorempixel.com/700/400/people?h" alt="" class="img-responsive"> </a> <figcaption class="item-caption"> <div class="item-description"> <h5>Cool website</h5> <p class="description hidden-xs hidden-sm">Cool website description</p> </div> </figcaption> </figure> </li> <li class="col-md-4 col-sm-4 col-xs-6 " data-groups='["app"]'> <figure class="portfolio-item"> <a href="#"> <img src="http://lorempicsum.com/futurama/700/400/1" alt="" class="img-responsive"> </a> <figcaption class="item-caption"> <div class="item-description"> <h5>Cool website</h5> <p class="description hidden-xs hidden-sm">Cool website description</p> </div> </figcaption> </figure> </li> <li class="col-md-4 col-sm-4 col-xs-6 " data-groups='["photo"]'> <figure class="portfolio-item"> <a href="#"> <img src="http://lorempicsum.com/futurama/700/400/3" alt="" class="img-responsive"> </a> <figcaption class="item-caption"> <div class="item-description"> <h5>Cool website</h5> <p class="description hidden-xs hidden-sm">Cool website description</p> </div> </figcaption> </figure> </li> <li class="col-md-4 col-sm-4 col-xs-6 " data-groups='["photo"]'> <figure class="portfolio-item"> <a href="#"> <img src="http://lorempicsum.com/futurama/700/400/2" alt="" class="img-responsive"> </a> <figcaption class="item-caption"> <div class="item-description"> <h5>Cool website</h5> <p class="description hidden-xs hidden-sm">Cool website description Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p> </div> </figcaption> </figure> </li> <li class="col-md-4 col-sm-4 col-xs-6 " data-groups='["web"]'> <figure class="portfolio-item"> <a href="#"> <img src="http://lorempicsum.com/futurama/700/400/5" alt="" class="img-responsive"> </a> <figcaption class="item-caption"> <div class="item-description"> <h5>Cool website</h5> <p class="description hidden-xs hidden-sm">Cool website description</p> </div> </figcaption> </figure> </li> <!-- sizer --> <li class="col-md-4 col-sm-4 col-xs-6 shuffle_sizer"></li> </ul> <p class="text-center"> <a href="#" class="button button-md button-ghost">View our portfolio</a> </p> </div><!--end row--> </div><!--end container--> </section><!--end section portfolio--> |
We’ll add padding and an alternate background to our section using the classes defined in our utilities.less file and we’ll center the text, display the list items inline and clear the floats using Bootstrap’s classes: text-center
, list-inline
, clearfix
.
On tablets and computers we will display 3 items per row and on smaller devices we’ll show 2 items using Bootstrap’s class col-xs-6
.
The portfolio pictures are placed inside a figure
element and the item name and description are place inside a figcaption
HTML element. To make sure that our images are responsive, we must use another Bootstrap class: img-responsive
.
Step 2 – Portfolio section CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
/*========== PORTFOLIO SECTION ==========*/ .section-portfolio { p:last-child { margin-bottom: 0; } } .portfolio-sorting { li a { font-family: @font-header; font-size: 0.875rem; color: @color-text; text-transform: uppercase; padding: @margin/4 @margin/2; border-radius: 5px; border: 1px solid @color-border; } li a.active, li a:hover { font-weight: 700; color: @color-text-light; background-color: @color-accent; border: 1px solid @color-accent; .transition(); } margin-bottom: @margin*2; } .shuffle_sizer { position: absolute; opacity: 0; visibility: hidden; } .portfolio-items { list-style: none; margin-bottom: @margin; margin-top: -6px; width: 100% !important; overflow: hidden; } .portfolio-item { display: block; position: relative; overflow: hidden; &:hover .item-caption { opacity: 0.8; } margin-bottom: 1.875rem; } .item-caption { opacity: 0; position: absolute; color: #fff; background-color: @color-accent; .transition(opacity); cursor: pointer; padding: @margin/2; top:0; width: 100%; height: 100%; h5, .description { text-align: center; color: #fff; margin-bottom: 0; } h5 { margin-bottom: @margin/2; } span { margin-left: @margin; margin-bottom: @margin; position: absolute; bottom: 0; } } .item-description { position: relative; top: 50%; transform: translateY(-50%); } |
The CSS seems complex, but that’s far from truth.
First, we remove the last paragraph margin bottom, since our section already has padding added with our add-padding class.
Next, we style the filter menu, using techniques similar to the ones used to build the buttons. The shuffle_sizer
class is hidden, since it’s only used by the JavaScript to get the grid size.
To create the item caption, we must set the portfolio-item position to relative, since this will be the “parent”. In the item-caption
class we can now add a position: absolute;
property and set the opacity to 0. We must set the top to 0, so that our item caption will start from the top of our parent container and we have to set the width and height to 100%, so that it will have the same size as the parent container. Afterwords, I added some styles to the heading and description.
To center align the text caption vertically, I used some modern CSS3 techniques. Set the top to 50% and then use transform: translateY(-50%);
. This will make sure that our content will always be in the center, regardless of the number of lines used in our description. Be aware that this technique will not work in older browsers, but I suppose that users that have older browsers are not your target audience anyway.
Our portfolio section should now look like this:
End of Part 1
This concludes the first part of our tutorial. We learned about LESS pre-processor and we built The Agency’s Header, Hero area, Services and the Portfolio section.
In Part 2 we’ll build the next sections of our site: CTA section, About us, Testimonials, Blog section, Contact area and Footer. We’ll also create the responsive media queries and our custom JavaScript.
Click here to read the next part in our design series or head back to our series index.