Skip to content

Commit b26894b

Browse files
committed
Initial setup based on HTML Portfolio Project
0 parents  commit b26894b

8 files changed

Lines changed: 376 additions & 0 deletions

File tree

.editorconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
npm-debug.log

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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+
## Getting Started
8+
9+
To get started with this project, head over to the [Semantic HTML Portfolio](#) project on Code School, and begin!
10+
11+
To get setup locally, run the following commands:
12+
13+
```
14+
npm install
15+
npm start
16+
```
17+
18+
## Tasks
19+
20+
Complete the following tasks to complete this project.
21+
22+
### Convert the Header to semantic HTML.
23+
24+
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.

package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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 test/*.spec.js",
9+
"deploy:github-pages": "git subtree push --prefix src origin gh-pages"
10+
},
11+
"author": "Adam Fortuna <adam@codeschool.com>",
12+
"license": "MIT",
13+
"devDependencies": {
14+
"browser-sync": "^2.14.0",
15+
"chai": "^3.5.0",
16+
"jsdom": "^9.4.1",
17+
"mocha": "^3.0.1"
18+
}
19+
}

src/bg.jpg

44.5 KB
Loading

src/index.html

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;">
7+
<link rel="stylesheet" href="main.css">
8+
<title>HTML Portfolio</title>
9+
</head>
10+
11+
<body>
12+
13+
<div class="header">
14+
<h1>Sergio Cruz</h1>
15+
<h2>Application Developer</h2>
16+
</div>
17+
18+
<div class="tagline">
19+
<div class="content-wrapper">
20+
<h3>A bit more about me</h3>
21+
<p>Hey I am Sergio, I work for <a target="_blank" href="https://www.codeschool.com">Code School</a> and I love writing JavaScript!</p>
22+
</div>
23+
</div>
24+
25+
26+
<div class="skills">
27+
<div class="content-wrapper">
28+
<h3>Skills</h3>
29+
<p>Here are some of the technologies I enjoy writing day-to-day:</p>
30+
<ul>
31+
<li>HTML &amp; CSS</li>
32+
<li>Node.js</li>
33+
<li>React</li>
34+
<li>Angular 2</li>
35+
<li>Webpack</li>
36+
</ul>
37+
</div>
38+
</div>
39+
40+
<div class="contact">
41+
<div class="content-wrapper">
42+
<h3>How to contact me</h3>
43+
<p>The easiest way to contact me is via twitter: <a target="_blank" href="https://twitter.com/hashtagserg">@hashtagserg</a></p>
44+
</div>
45+
</div>
46+
47+
<div class="footer">
48+
<div class="content-wrapper">
49+
<h3>Credits</h3>
50+
<p>This portfolio was created using <a href='https://www.codeschool.com'>Code School's</a> <a href='https://github.com/codeschool/SemanticHTMLPortfolioProject'>Semantic HTML Portfolio Project</a> template.</p>
51+
</div>
52+
</div>
53+
54+
</body>
55+
56+
</html>

src/main.css

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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+
p, ul {
24+
margin: 10px 0;
25+
}
26+
27+
ul li {
28+
margin-left: 30px;;
29+
}
30+
31+
a {
32+
color: #00b8d4;
33+
font-weight: 600;
34+
text-decoration: none;
35+
border-bottom: 3px solid #00b8d4;
36+
padding: 3px;
37+
}
38+
39+
a:hover {
40+
background-color: #00b8d4;
41+
color: white;
42+
}
43+
44+
a:active {
45+
position: relative;
46+
top: 1px;
47+
}
48+
49+
.content-wrapper {
50+
line-height: 1.4;
51+
margin: 0 auto;
52+
max-width: 900px;
53+
padding: 30px 25px;
54+
}
55+
56+
/*
57+
* HEADER
58+
*/
59+
60+
.header, header {
61+
align-items: center;
62+
background-color: #EFEFEF;
63+
background-image: url('bg.jpg');
64+
background-position: cover;
65+
background-repeat: no-repeat;
66+
background-size: 100% auto;
67+
border-top: 4px solid #e91e63;
68+
color: #FFFFFF;
69+
display: flex;
70+
flex-direction: column;
71+
height: 40vh;
72+
justify-content: center;
73+
min-height: 250px;
74+
padding: 0 20px;
75+
position: relative;
76+
text-align: center;
77+
}
78+
79+
@media only screen and (max-device-width: 420px) {
80+
.header, header {
81+
background-size: auto 100%;
82+
}
83+
}
84+
85+
.header:before, header:before {
86+
background: rgba(0, 0, 0, .7);
87+
bottom: 0;
88+
content: ' ';
89+
display: block;
90+
left: 0;
91+
position: absolute;
92+
right: 0;
93+
top: 0;
94+
z-index: 1;
95+
}
96+
97+
.header *, header * {
98+
position: relative;
99+
z-index: 2;
100+
text-shadow: 1px 1px 10px black;
101+
}
102+
103+
.header h1, header h1 {
104+
font-size: 4rem;
105+
font-weight: 100;
106+
}
107+
108+
.header h2, header h2 {
109+
font-size: 2.1rem;
110+
font-weight: 100;
111+
margin: 5px 0;
112+
}
113+
114+
/*
115+
* SKILLS
116+
*/
117+
118+
.skills {
119+
background: #e91e63;
120+
color: white;
121+
}
122+
123+
.footer, footer {
124+
margin-top: 2em;
125+
background-color: #444;
126+
color: #eee;
127+
}
128+
.footer h1, footer h1 {
129+
font-size: 16px;
130+
}
131+
.footer p, footer p {
132+
font-size: 14px;

test/portfolio.spec.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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 have a non-empty title @h1', () => {
23+
const h1 = doc.querySelector('.header h1');
24+
assert.isOk(h1, 'We need an `h1` element inside `.header`.');
25+
assert.isOk(h1.textContent, 'Our header\'s `h1` element cannot be empty.');
26+
});
27+
28+
it('should have a non-empty description @h2', () => {
29+
const h2 = doc.querySelector('.header h2');
30+
assert.isOk(h2, 'We need an `h2` element inside `.header`.');
31+
assert.isOk(h2.textContent, 'Our header\'s `h2` element cannot be empty.');
32+
});
33+
});
34+
35+
36+
/**
37+
* TAGLINE
38+
*/
39+
describe('tagline', () => {
40+
it('should exist @tagline', () => {
41+
const tagline = doc.querySelector('.tagline');
42+
assert.isOk(tagline, 'We need a `.tagline` element.');
43+
});
44+
45+
it('should have a non-empty h3 tag @tagline-content', () => {
46+
const h3 = doc.querySelector('.tagline h3');
47+
assert.isOk(h3, 'We need an `h3` element inside `.tagline`.');
48+
assert.isOk(h3.textContent, 'Our tagline\'s `h3` element cannot be empty.');
49+
});
50+
51+
it('should have a descriptive paragraph @tagline-content', () => {
52+
const p = doc.querySelector('.tagline p');
53+
assert.isOk(p, 'We need a `p` element inside `.tagline`.');
54+
assert.isOk(p.textContent, 'Our tagline\'s `p` element cannot be empty.');
55+
});
56+
});
57+
58+
59+
/**
60+
* SKILLS
61+
*/
62+
describe('skills', () => {
63+
it('should exist @skills', () => {
64+
const skills = doc.querySelector('.skills');
65+
assert.isOk(skills, 'We need a `.skills` element.');
66+
});
67+
68+
it('should have a non-empty h3 tag @skills-content', () => {
69+
const h3 = doc.querySelector('.skills h3');
70+
assert.isOk(h3, 'We need an `h3` element inside `.skills`.');
71+
assert.isOk(h3.textContent, 'Our skills\' `h3` element cannot be empty.');
72+
});
73+
74+
it('should have a descriptive paragraph @skills-content', () => {
75+
const p = doc.querySelector('.skills p');
76+
assert.isOk(p, 'We need a `p` element inside `.skills`.');
77+
assert.isOk(p.textContent, 'Our skills\' `p` element cannot be empty.');
78+
});
79+
80+
it('should have an unordered list of your skills @skills-list', () => {
81+
const ul = doc.querySelector('.skills ul');
82+
assert.isOk(ul, 'We need a `ul` element inside `.skills`.');
83+
});
84+
85+
it('should have at least 3 skills @skills-list', () => {
86+
const skillItems = doc.querySelectorAll('.skills ul li');
87+
assert.isAtLeast(skillItems.length, 3, 'We need at least 3 `li` elements inside the skills\' `ul`.');
88+
});
89+
90+
it('should have one skill that contains HTML @skills-list', () => {
91+
const skillItems = Array.from(doc.querySelectorAll('.skills ul li'));
92+
const htmlRegex = /html/i;
93+
94+
const skillsWithHtml = skillItems
95+
.map(li => li.textContent)
96+
.filter(skill => htmlRegex.test(skill));
97+
98+
assert.equal(skillsWithHtml.length, 1, 'HTML needs be part of one of your skills.');
99+
});
100+
});
101+
102+
103+
/**
104+
* CONTACT
105+
*/
106+
describe('contact', () => {
107+
it('should exist @contact', () => {
108+
const contact = doc.querySelector('.contact');
109+
assert.isOk(contact, 'We need a `.contact` element.');
110+
});
111+
112+
it('should have a non-empty h3 tag @contact-content', () => {
113+
const h3 = doc.querySelector('.contact h3');
114+
assert.isOk(h3, 'We need an `h3` element inside `.contact`.');
115+
assert.isOk(h3.textContent, 'Our contact\'s `h3` element cannot be empty.');
116+
});
117+
118+
it('should have a descriptive paragraph @contact-content', () => {
119+
const p = doc.querySelector('.contact p');
120+
assert.isOk(p, 'We need a `p` element inside `.contact`.');
121+
assert.isOk(p.textContent, 'Our contact\'s `p` element cannot be empty.');
122+
});
123+
124+
it('should have a link with an href within the paragraph @contact-link', () => {
125+
const a = doc.querySelector('.contact p a');
126+
assert.isOk(a, 'We need a `a` element our inside contact\'s `p` element.');
127+
assert.isOk(a.textContent, 'Our contact\'s `a` element cannot be empty.');
128+
assert.isOk(a.getAttribute('href'), 'Our contact\'s `a` element needs a non-empty `href` attribute.');
129+
});
130+
});
131+
132+
});

0 commit comments

Comments
 (0)