├── .editorconfig ├── .gitignore ├── LICENSE.txt ├── README.md ├── package.json ├── screenshot.png ├── src ├── bg.jpg ├── index.html └── main.css └── test └── portfolio.spec.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 2 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Code School 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Semantic HTML Portfolio 2 | 3 | Welcome to the Semantic HTML Portfolio Project! For this project, we'll be converting a portfolio created using basic HTML tags (`div`, `span`, etc) to use HTML 5's more semantic tags. 4 | 5 | Please follow the instructions below to complete the project. Be sure to run tests to make sure your tests are passing before submitting your code. 6 | 7 | ## What You'll Build 8 | 9 | We'll be using the [Build a Portfolio Using HTML and CSS](https://www.codeschool.com/projects/build-a-portfolio-using-html-and-css) project as a starting point and converting it to use semantic HTML elements. The result won't look that different than before, but this will introduce a few new HTML elements into the mix to help make our HTML more clear. Here's a sample of what this could look like: 10 | 11 | ![Sample Portfolio](http://courseware.codeschool.com.s3.amazonaws.com/projects/semantic-html-portfolio-project.png) 12 | 13 | 14 | ## What You'll Learn 15 | 16 | We'll use a bunch of HTML 5 elements, including: 17 | 18 | - `header` 19 | - `footer` 20 | - `main` 21 | - `nav` 22 | - `section` 23 | 24 | If you've never used these elements, we recommend taking the [Front-End Formations](https://www.codeschool.com/courses/front-end-formations) course to get familiar with these elements before jumping in. 25 | 26 | ## Live Demo 27 | 28 | Wondering what this project will look like when you've completed it? [Follow this link](https://codeschool-project-demos.github.io/SemanticHTMLPortfolioProject/) to see a live version of this project. 29 | 30 | 31 | ## Getting Started 32 | 33 | To get started with this project, head over to the [Semantic HTML Portfolio](https://www.codeschool.com/projects/semantic-html-portfolio-project) project on Code School, and begin! 34 | 35 | To get setup locally, run the following commands: 36 | 37 | ``` 38 | npm install 39 | npm start 40 | ``` 41 | 42 | ## Tasks 43 | 44 | Complete the following tasks to complete this project. 45 | 46 | ### Convert the Header 47 | 48 | The element with a class of "header" isn't using the most semantic HTML tag it could be using. Switch it to use an element that most accurately wraps the header content for a page. 49 | 50 | ### Semantic Navigation 51 | 52 | Our `.nav` element in the header of the page isn't using the most semantic HTML tags it could be using. `ul` is the correct one for this list of navigation items, but we should wrap this element with a more semantic element to indicate it is a navigation. Go ahead and add this. 53 | 54 | ### Create Sections 55 | 56 | Each of the main content areas of our portfolio could be switched from using `div` tags to something that more accurately describes them as sections of our page. Update the `.tagline`, `.skills` and `.contact` sections to use a more semantic HTML tag. 57 | 58 | ### Main Content 59 | 60 | Our 3 main sections make up the focus of our page. Wrap these three sections (tagline, skills and contact) in an HTML element that gives it the correct focus. 61 | 62 | ### Footer 63 | 64 | Lastly, the element with a class of `footer` isn't the most semantic use of that area either. Luckily HTML 5 has a much better element we can use for footers. Update this element to use the semantically correct tag. 65 | 66 | ## Next Steps 67 | 68 | Now that your site is working, the next step would be to deploy it to production! 69 | 70 | Putting this site up on GitHub pages is a bit different than some other projects because the code is all in the `/src` directory. There’s a nifty way to push this directory to a GitHub branch, which allows you to use GitHub pages with it! Try running this Git command for this project: 71 | 72 | ``` 73 | git subtree push --prefix src origin gh-pages 74 | ``` 75 | 76 | This will push the `src` folder up to GitHub on the `gh-pages` branch. After that, you should be able to open up `http://username.github.io/SemanticHTMLPortfolioProject`, where `username` is your GitHub username. 77 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "semantic-html-portfolio-project", 3 | "version": "1.0.0", 4 | "description": "Convert a document to use semantic HTML.", 5 | "private": true, 6 | "scripts": { 7 | "start": "browser-sync start --server ./src --files ./src", 8 | "test": "mocha --colors --compilers js:babel-register test/*.spec.js", 9 | "test:watch": "watch-run -p 'src/index.html,test/portfolio.spec.js' npm run test", 10 | "deploy:github-pages": "git subtree push --prefix src origin gh-pages" 11 | }, 12 | "author": "Adam Fortuna ", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "babel-preset-es2015": "^6.18.0", 16 | "babel-register": "^6.18.0", 17 | "browser-sync": "^2.14.0", 18 | "chai": "^3.5.0", 19 | "jsdom": "^9.4.1", 20 | "mocha": "^3.0.1", 21 | "watch-run": "^1.2.4" 22 | }, 23 | "engines": { 24 | "node": ">=4.6", 25 | "npm": ">=2.15" 26 | }, 27 | "babel": { 28 | "presets": ["es2015"] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeschool-projects/SemanticHTMLPortfolioProject/4cc53c89efd3a4d97bb93940df1958d12f022ed8/screenshot.png -------------------------------------------------------------------------------- /src/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeschool-projects/SemanticHTMLPortfolioProject/4cc53c89efd3a4d97bb93940df1958d12f022ed8/src/bg.jpg -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | HTML Portfolio 9 | 10 | 11 | 12 | 13 |
14 |

Sergio Cruz

15 |

Application Developer

16 | 17 | 21 |
22 | 23 |
24 |
25 |

A bit more about me

26 |

Hey I am Sergio, I work for Code School and I love writing JavaScript!

27 |
28 |
29 | 30 | 31 |
32 |
33 |

Skills

34 |

Here are some of the technologies I enjoy writing day-to-day:

35 |
    36 |
  • HTML & CSS
  • 37 |
  • Node.js
  • 38 |
  • React
  • 39 |
  • Angular 2
  • 40 |
  • Webpack
  • 41 |
42 |
43 |
44 | 45 |
46 |
47 |

How to contact me

48 |

The easiest way to contact me is via twitter: @hashtagserg

49 |
50 |
51 | 52 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/main.css: -------------------------------------------------------------------------------- 1 | *, *:before, *:after { 2 | box-sizing: border-box; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | body { 8 | background: #F5F5F5; 9 | color: #444; 10 | font-family: "Helvetica Neue", Arial, serif; 11 | font-size: 22px; 12 | margin: 0; 13 | padding: 0; 14 | font-weight: 200; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale; 17 | } 18 | 19 | h1, h2, h3, h4 { 20 | margin: 10px 0 15px; 21 | } 22 | 23 | .nav, nav { 24 | display: inline; 25 | list-style: none; 26 | margin: 1em 0; 27 | padding: 0; 28 | } 29 | .nav li, nav li { 30 | display: inline; 31 | margin-right: 1em; 32 | } 33 | 34 | p, ul { 35 | margin: 10px 0; 36 | } 37 | 38 | .skills ul li { 39 | margin-left: 30px;; 40 | } 41 | 42 | a { 43 | color: #00b8d4; 44 | font-weight: 600; 45 | text-decoration: none; 46 | border-bottom: 3px solid #00b8d4; 47 | padding: 3px; 48 | } 49 | 50 | a:hover { 51 | background-color: #00b8d4; 52 | color: white; 53 | } 54 | 55 | a:active { 56 | position: relative; 57 | top: 1px; 58 | } 59 | 60 | a.active { 61 | border-bottom: none; 62 | } 63 | 64 | .content-wrapper { 65 | line-height: 1.4; 66 | margin: 0 auto; 67 | max-width: 900px; 68 | padding: 30px 25px; 69 | } 70 | 71 | /* 72 | * HEADER 73 | */ 74 | 75 | .header, header { 76 | align-items: center; 77 | background-color: #EFEFEF; 78 | background-image: url('bg.jpg'); 79 | background-position: cover; 80 | background-repeat: no-repeat; 81 | background-size: 100% auto; 82 | border-top: 4px solid #e91e63; 83 | color: #FFFFFF; 84 | display: flex; 85 | flex-direction: column; 86 | height: 40vh; 87 | justify-content: center; 88 | min-height: 250px; 89 | padding: 0 20px; 90 | position: relative; 91 | text-align: center; 92 | } 93 | 94 | @media only screen and (max-device-width: 420px) { 95 | .header, header { 96 | background-size: auto 100%; 97 | } 98 | } 99 | 100 | .header:before, header:before { 101 | background: rgba(0, 0, 0, .7); 102 | bottom: 0; 103 | content: ' '; 104 | display: block; 105 | left: 0; 106 | position: absolute; 107 | right: 0; 108 | top: 0; 109 | z-index: 1; 110 | } 111 | 112 | .header *, header * { 113 | position: relative; 114 | z-index: 2; 115 | text-shadow: 1px 1px 10px black; 116 | } 117 | 118 | .header h1, header h1 { 119 | font-size: 4rem; 120 | font-weight: 100; 121 | } 122 | 123 | .header h2, header h2 { 124 | font-size: 2.1rem; 125 | font-weight: 100; 126 | margin: 5px 0; 127 | } 128 | 129 | /* 130 | * SKILLS 131 | */ 132 | 133 | .skills { 134 | background: #e91e63; 135 | color: white; 136 | } 137 | 138 | .footer, footer { 139 | margin-top: 2em; 140 | background-color: #444; 141 | color: #eee; 142 | } 143 | .footer h1, footer h1 { 144 | font-size: 16px; 145 | } 146 | .footer p, footer p { 147 | font-size: 14px; 148 | -------------------------------------------------------------------------------- /test/portfolio.spec.js: -------------------------------------------------------------------------------- 1 | // Libraries 2 | const fs = require('fs'); 3 | const jsdom = require('jsdom'); 4 | const { assert } = require('chai'); 5 | 6 | // HTML 7 | const srcHtml = fs.readFileSync('./src/index.html'); 8 | const doc = jsdom.jsdom(srcHtml); 9 | 10 | // Tests 11 | describe('The webpage', () => { 12 | 13 | /** 14 | * HEADER 15 | */ 16 | describe('header', () => { 17 | it('should exist @header', () => { 18 | const header = doc.querySelector('header'); 19 | assert.isOk(header, 'We need a `header` element.'); 20 | }); 21 | 22 | it('should not exist @header', () => { 23 | const header = doc.querySelector('.header'); 24 | assert.isOk(!header, 'Make sure to remove the `.header` class -- we no longer need it.'); 25 | }); 26 | }); 27 | 28 | 29 | /** 30 | * NAV 31 | */ 32 | describe('nav', () => { 33 | it('should exist @nav', () => { 34 | const nav = doc.querySelector('header nav'); 35 | assert.isOk(nav, 'We need a `nav` element inside `header`.'); 36 | }); 37 | 38 | it('should remove the existing class @nav', () => { 39 | const nav = doc.querySelector('.nav'); 40 | assert.isOk(!nav, 'We no longer need an element with a class of `.nav`. Go ahead and remove it.'); 41 | }); 42 | 43 | it('should still contain a ul @nav', () => { 44 | const nav = doc.querySelector('nav ul'); 45 | assert.isOk(nav, 'We still need a `ul` element within our `nav`.'); 46 | }); 47 | }); 48 | 49 | 50 | /** 51 | * SECTION 52 | */ 53 | describe('section', () => { 54 | it('should convert the tagline @section', () => { 55 | const el = doc.querySelector('.tagline'); 56 | assert.isOk(el, 'Looks like you removed the element with a class of `.tagline`. You will still need that, but will need to change it\'s element.'); 57 | assert.equal(el.tagName.toLowerCase(), 'section', 'Make sure to change the element with a class of `tagline` to a `section` element.'); 58 | }); 59 | 60 | it('should convert the skills @section', () => { 61 | const el = doc.querySelector('.skills'); 62 | assert.isOk(el, 'Looks like you removed the element with a class of `.skills`. You will still need that, but will need to change it\'s element.'); 63 | assert.equal(el.tagName.toLowerCase(), 'section', 'Make sure to change the element with a class of `skills` to a `section` element.'); 64 | }); 65 | 66 | it('should convert the contact @section', () => { 67 | const el = doc.querySelector('.contact'); 68 | assert.isOk(el, 'Looks like you removed the element with a class of `.contact`. You will still need that, but will need to change it\'s element.'); 69 | assert.equal(el.tagName.toLowerCase(), 'section', 'Make sure to change the element with a class of `contact` to a `section` element.'); 70 | }); 71 | }); 72 | 73 | 74 | /** 75 | * MAIN 76 | */ 77 | describe('main', () => { 78 | it('should exist @main', () => { 79 | const header = doc.querySelector('main'); 80 | assert.isOk(header, 'We need a `main` element.'); 81 | }); 82 | 83 | it('should not exist @main', () => { 84 | const sections = doc.querySelectorAll('main section'); 85 | assert.isOk(sections.length >= 3, 'Make sure to move all of the `section` elements into our new `main` element.'); 86 | }); 87 | }); 88 | 89 | /** 90 | * FOOTER 91 | */ 92 | describe('footer', () => { 93 | it('should exist @footer', () => { 94 | const footer = doc.querySelector('footer'); 95 | assert.isOk(footer, 'We need a `footer` element.'); 96 | }); 97 | 98 | it('should not exist @footer', () => { 99 | const footer = doc.querySelector('.footer'); 100 | assert.isOk(!footer, 'Remove the `footer` class. Since we\'re using semantic HTML, we no longer need that one.'); 101 | }); 102 | }); 103 | 104 | }); 105 | --------------------------------------------------------------------------------