From da1f0cc3571d6aa2b0f523f9dd47e365d67aa3f2 Mon Sep 17 00:00:00 2001 From: Tom <20648924+moT01@users.noreply.github.com> Date: Wed, 11 May 2022 04:08:21 -0500 Subject: [PATCH] fix: use new RWD cert projects for all i18n's (#45906) --- .../build-a-personal-portfolio-webpage.md | 270 ++++++++- .../build-a-product-landing-page.md | 417 +++++++++++++- .../build-a-survey-form.md | 509 ++++++++++++++++- .../build-a-technical-documentation-page.md | 518 +++++++++++++++++- .../build-a-tribute-page.md | 320 ++++++++++- .../build-a-personal-portfolio-webpage.md | 270 ++++++++- .../build-a-product-landing-page.md | 417 +++++++++++++- .../build-a-survey-form.md | 509 ++++++++++++++++- .../build-a-technical-documentation-page.md | 518 +++++++++++++++++- .../build-a-tribute-page.md | 320 ++++++++++- .../build-a-personal-portfolio-webpage.md | 270 ++++++++- .../build-a-product-landing-page.md | 417 +++++++++++++- .../build-a-survey-form.md | 509 ++++++++++++++++- .../build-a-technical-documentation-page.md | 518 +++++++++++++++++- .../build-a-tribute-page.md | 320 ++++++++++- .../build-a-personal-portfolio-webpage.md | 270 ++++++++- .../build-a-product-landing-page.md | 417 +++++++++++++- .../build-a-survey-form.md | 509 ++++++++++++++++- .../build-a-technical-documentation-page.md | 518 +++++++++++++++++- .../build-a-tribute-page.md | 320 ++++++++++- .../build-a-personal-portfolio-webpage.md | 270 ++++++++- .../build-a-product-landing-page.md | 417 +++++++++++++- .../build-a-survey-form.md | 509 ++++++++++++++++- .../build-a-technical-documentation-page.md | 518 +++++++++++++++++- .../build-a-tribute-page.md | 320 ++++++++++- .../build-a-personal-portfolio-webpage.md | 270 ++++++++- .../build-a-product-landing-page.md | 417 +++++++++++++- .../build-a-survey-form.md | 509 ++++++++++++++++- .../build-a-technical-documentation-page.md | 518 +++++++++++++++++- .../build-a-tribute-page.md | 320 ++++++++++- .../build-a-personal-portfolio-webpage.md | 47 -- .../build-a-product-landing-page.md | 55 -- .../build-a-survey-form.md | 57 -- .../build-a-technical-documentation-page.md | 55 -- .../build-a-tribute-page.md | 43 -- .../build-a-personal-portfolio-webpage.md | 270 ++++++++- .../build-a-product-landing-page.md | 417 +++++++++++++- .../build-a-survey-form.md | 509 ++++++++++++++++- .../build-a-technical-documentation-page.md | 518 +++++++++++++++++- .../build-a-tribute-page.md | 320 ++++++++++- 40 files changed, 13461 insertions(+), 1034 deletions(-) delete mode 100644 curriculum/challenges/japanese/14-responsive-web-design-22/build-a-personal-portfolio-webpage-project/build-a-personal-portfolio-webpage.md delete mode 100644 curriculum/challenges/japanese/14-responsive-web-design-22/build-a-product-landing-page-project/build-a-product-landing-page.md delete mode 100644 curriculum/challenges/japanese/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md delete mode 100644 curriculum/challenges/japanese/14-responsive-web-design-22/build-a-technical-documentation-page-project/build-a-technical-documentation-page.md delete mode 100644 curriculum/challenges/japanese/14-responsive-web-design-22/build-a-tribute-page-project/build-a-tribute-page.md diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md index 33ac93289c9..0226992eec9 100644 --- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md +++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md @@ -1,47 +1,277 @@ --- id: bd7158d8c242eddfaeb5bd13 -title: 製作一個個人作品集展示頁 -challengeType: 3 +title: Build a Personal Portfolio Webpage +challengeType: 14 forumTopicId: 301143 dashedName: build-a-personal-portfolio-webpage --- # --description-- -**目標:** 在 [CodePen.io](https://codepen.io) 上創建一個與這個功能類似的 app:。 +**Objective:** Build an app that is functionally similar to https://personal-portfolio.freecodecamp.rocks -在滿足以下[需求](https://en.wikipedia.org/wiki/User_story)並能通過所有測試的前提下, 你可以根據自己的喜好來美化你的 app。 +**User Stories:** -你可以使用 HTML、JavaScript 以及 CSS 來完成項目。 由於目前你只學到了 CSS 課程,所以我們建議你只使用 CSS 來完成這個項目,同時鞏固一下你之前所學的內容。 你也可以使用 Bootstrap 或者 SASS。 我們不推薦你在這個項目中使用其他技術(比如 jQuery、React、Angular 或 Vue)。 在後續的其他項目中,你將有機會使用像是 React 等其他技術棧。 我們會接受並嘗試修復你在使用推薦技術棧創建項目時報告的問題。 祝你編碼愉快! +1. Your portfolio should have a welcome section with an `id` of `welcome-section` +1. The welcome section should have an `h1` element that contains text +1. Your portfolio should have a projects section with an `id` of `projects` +1. The projects section should contain at least one element with a `class` of `project-tile` to hold a project +1. The projects section should contain at least one link to a project +1. Your portfolio should have a navbar with an id of `navbar` +1. The navbar should contain at least one link that you can click on to navigate to different sections of the page +1. Your portfolio should have a link with an id of `profile-link`, which opens your GitHub or freeCodeCamp profile in a new tab +1. Your portfolio should have at least one media query +1. The height of the welcome section should be equal to the height of the viewport +1. The navbar should always be at the top of the viewport -**需求 1:** 此 app 中應存在一個 id 爲 `welcome-section` 的歡迎區。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**需求 2:** 歡迎區內應存在一個包含標題文本的 `h1` 元素。 +# --hints-- -**需求 3:** 此 app 中應存在一個 id 爲 `projects` 的項目展示區。 +Your portfolio should have a "Welcome" section with an `id` of `welcome-section`. -**需求 4:** 項目展示區應至少包含一個 class 爲 `project-tile` 的元素來展示項目。 +```js +const el = document.getElementById('welcome-section') +assert(!!el); +``` -**需求 5:** 項目展示區應至少包含一個鏈接到項目的超鏈接元素。 +Your `#welcom-section` element should contain an `h1` element. -**需求 6:** 此 app 中應存在一個 id 爲 `navbar` 的導航欄。 +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1').length, + 0, + 'Welcome section should contain an h1 element ' +); +``` -**需求 7:** 導航欄中應包含一個可以滾動到本頁面不同區域的鏈接。 +You should not have any empty `h1` elements within `#welcome-section` element. -**需求 8:** 此 app 中應包含一個 id 爲 `profile-link` 的鏈接。 點擊這個鏈接時,它應在瀏覽器的新標籤頁內打開我的 GitHub 或者 FCC 作品集頁面。 +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1')?.[0]?.innerText?.length, + 0, + 'h1 element in welcome section should contain your name or camper ' + + 'name ' +); +``` -**需求 9:** 在此 app 中,應至少使用一次媒體查詢。 +You should have a "Projects" section with an `id` of `projects`. -**需求 10:** 歡迎區的高度應該與視口的高度保持一致。 +```js +const el = document.getElementById('projects') +assert(!!el); +``` -**需求 11:** 導航欄應始終保持在視口頂部。 +Your portfolio should contain at least one elment with a class of `project-tile`. -你可以使用這個 CodePen 模版創建你自己的項目,點擊 `Save` 即可創建你的新項目。 也可以使用此 CDN 鏈接在任何你喜歡的環境中運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`。 +```js +assert.isAbove( + document.querySelectorAll('#projects .project-tile').length, + 0 +); +``` -完成項目並通過所有測試後,請輸入你的項目在 CodePen 上的鏈接並提交。 +Your `#projects` element should contain at least one `a` element. -# --solutions-- +```js +assert.isAbove(document.querySelectorAll('#projects a').length, 0); +``` + +Your portfolio should have a navbar with an `id` of `navbar`. + +```js +const el = document.getElementById('navbar'); +assert(!!el); +``` + +Your `#navbar` element should contain at least one `a` element whose `href` attribute starts with `#`. + +```js +const links = [...document.querySelectorAll('#navbar a')].filter( + (nav) => (nav?.getAttribute('href') || '').substr(0, 1) === '#' +); + +assert.isAbove( + links.length, + 0, + 'Navbar should contain an anchor link ' +); +``` + +Your portfolio should have an `a` element with an `id` of `profile-link`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.tagName === 'A') +``` + +Your `#profile-link` element should have a `target` attribute of `_blank`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.target === '_blank') +``` + +Your portfolio should use at least one media query. + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your `#navbar` element should always be at the top of the viewport. + +```js +(async () => { + const timeout = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)); + + const navbar = document.getElementById('navbar'); + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + "Navbar's parent should be body and it should be at the top of " + + 'the viewport ' + ); + + window.scroll(0, 500); + + await timeout(1); + + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + 'Navbar should be at the top of the viewport even after ' + + 'scrolling ' + ); + window.scroll(0, 0); +})(); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Personal Portfolio + + + + + +
+
+
+

It's me!

+ +

Naomi Carrigan

+

Welcome to my portfolio page!

+

+
+

Projects

+

Here's what I've worked on!

+

+ + + + +


+
+

Contact me!

+

Use the links below to get in touch.

+

FreeCodeCamp.org | GitHub | Facebook | LinkedIn +

+ + + +``` + +```css +nav{ + position: fixed; + width: 100%; + text-align: right; + font-size: 24pt; + top: 0%; + right: 5px; + background-color: #000000; + color: #ffffff; +} +@media (max-width: 500px){ + nav{ + display: none; + } +} +a{ + color: #ffffff; +} +main{ + text-align: center; + background-color: black; + font-family:Pacifico +} +h1{ + font-size: 48pt; +} +h2{ + font-size: 24pt; +} +p{ + font-size: 12pt; +} +#welcome-section{ + background-color:#251a4a; + color: #FFFFFF; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#projects{ + background-color: #060a9c; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#contact{ + background-color: #03300b; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} ``` diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md index 1bd43439480..cdd62359751 100644 --- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md +++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md @@ -1,55 +1,424 @@ --- id: 587d78af367417b2b2512b04 -title: 製作一個產品登錄頁 -challengeType: 3 +title: Build a Product Landing Page +challengeType: 14 forumTopicId: 301144 dashedName: build-a-product-landing-page --- # --description-- -**目標:** 在 [CodePen.io](https://codepen.io) 上創建一個與這個功能類似的 app:。 +**Objective:** Build an app that is functionally similar to https://product-landing-page.freecodecamp.rocks -在滿足以下[需求](https://en.wikipedia.org/wiki/User_story)並能通過所有測試的前提下, 你可以根據自己的喜好來美化你的 app。 +**User Stories:** -你可以使用 HTML、JavaScript 以及 CSS 來完成項目。 由於目前你只學到了 CSS 課程,所以我們建議你只使用 CSS 來完成這個項目,同時鞏固一下你之前所學的內容。 你也可以使用 Bootstrap 或者 SASS。 我們不推薦你在這個項目中使用其他技術(比如 jQuery、React、Angular 或 Vue)。 在後續的其他項目中,你將有機會使用像是 React 等其他技術棧。 我們會接受並嘗試修復你在使用推薦技術棧創建項目時報告的問題。 祝你編碼愉快! +1. Your product landing page should have a `header` element with a corresponding `id="header"` +1. You can see an image within the `header` element with a corresponding `id="header-img"` (A logo would make a good image here) +1. Within the `#header` element, you can see a `nav` element with a corresponding `id="nav-bar"` +1. You can see at least three clickable elements inside the `nav` element, each with the class `nav-link` +1. When you click a `.nav-link` button in the `nav` element, you are taken to the corresponding section of the landing page +1. You can watch an embedded product video with `id="video"` +1. Your landing page has a `form` element with a corresponding `id="form"` +1. Within the form, there is an `input` field with `id="email"` where you can enter an email address +1. The `#email` input field should have placeholder text to let users know what the field is for +1. The `#email` input field uses HTML5 validation to confirm that the entered text is an email address +1. Within the form, there is a submit `input` with a corresponding `id="submit"` +1. When you click the `#submit` element, the email is submitted to a static page (use this mock URL: `https://www.freecodecamp.com/email-submit`) +1. The navbar should always be at the top of the viewport +1. Your product landing page should have at least one media query +1. Your product landing page should utilize CSS flexbox at least once -**需求 1:** 產品登錄頁應存在 `id="header"` 的 `header` 元素。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**需求 2:** 在 `header` 元素內應存在 `id="header-img"` 的圖像, 這裏通常用來放置公司的 logo。 +# --hints-- -**需求 3:** 在 `#header` 元素內,應存在一個 `id="nav-bar"` 的 `nav` 元素。 +You should have a `header` element with an `id` of `header` -**需求 4:** `nav` 元素中應至少包含三個 class 爲 `nav-link` 且可點擊的元素。 +```js +const el = document.getElementById('header') +assert(!!el && el.tagName === 'HEADER') +``` -**需求 5:** 當點擊 `nav` 內的 `.nav-link` 按鈕時,應滾動到產品主頁上相應的部分。 +You should have an `img` element with an `id` of `header-img` -**需求 6:** 頁面上應存在 `id="video"` 的嵌入式視頻播放區域。 +```js +const el = document.getElementById('header-img') +assert(!!el && el.tagName === 'IMG') +``` -**需求 7:** 產品登陸頁應存在一個 `id="form"` 的 `form` 元素。 +Your `#header-img` should be a descendant of the `#header` -**需求 8:** 在表單中,應存在一個 `id="email"` 的 `input` 輸入框供用戶填寫郵箱。 +```js +const els = document.querySelectorAll('#header #header-img') +assert(els.length > 0) +``` -**需求 9:** `#email` 輸入框內應存在描述該區域用途的佔位符文字。 +Your `#header-img` should have a `src` attribute -**需求 10:** `#email` 輸入框應使用 HTML5 驗證來確認輸入的內容是否爲郵箱。 +```js +const el = document.getElementById('header-img') +assert(!!el && !!el.src) +``` -**需求 11:** 在表單中,應存在一個 `id="submit"` 的 `input` 提交按鈕。 +Your `#header-img`’s `src` value should be a valid URL (starts with `http`) -**需求 12:** 當點擊 `#submit` 元素時,應將郵箱信息提交到一個靜態頁面(請使用這個模擬的 URL:)。 +```js +const el = document.getElementById('header-img') +assert(!!el && /^http/.test(el.src)) +``` -**需求 13:** navbar 應保持在視口(viewport)的頂部。 +You should have a `nav` element with an `id` of `nav-bar` -**需求 14:** 在此 app 中,應至少使用一次媒體查詢。 +```js +const el = document.getElementById('nav-bar') +assert(!!el && el.tagName === 'NAV') +``` -**需求 15:** 在此 app 中,應至少使用一次 CSS 的 flexbox 佈局。 +Your `#nav-bar` should be a descendant of the `#header` -你可以使用這個 CodePen 模版創建你自己的項目,點擊 `Save` 即可創建你的新項目。 也可以使用此 CDN 鏈接在任何你喜歡的環境中運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`。 +```js +const els = document.querySelectorAll('#header #nav-bar') +assert(els.length > 0) +``` -完成項目並通過所有測試後,請輸入你的項目在 CodePen 上的鏈接並提交。 +You should have at least 3 `.nav-link` elements within the `#nav-bar` -# --solutions-- +```js +const els = document.querySelectorAll('#nav-bar .nav-link') +assert(els.length >= 3) +``` + +Each `.nav-link` element should have an `href` attribute + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (!el.href) assert(false) +}) +assert(els.length > 0) +``` + +Each `.nav-link` element should link to a corresponding element on the landing page (has an `href` with a value of another element's id. e.g. `#footer`) + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + const linkDestination = el.getAttribute('href').slice(1) + if (!document.getElementById(linkDestination)) assert(false) +}) +assert(els.length > 0) +``` + +You should have a `video` or `iframe` element with an `id` of `video` + +```js +const el = document.getElementById('video') +assert(!!el && (el.tagName === 'VIDEO' || el.tagName === 'IFRAME')) +``` + +Your `#video` should have a `src` attribute + +```js +const el = document.getElementById('video') +assert(!!el && !!el.src) +``` + +You should have a `form` element with an `id` of `form` + +```js +const el = document.getElementById('form') +assert(!!el && el.tagName === 'FORM') +``` + +You should have an `input` element with an `id of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #email') +assert(els.length > 0) +``` + +Your `#email` should have the `placeholder` attribute with placeholder text + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should use HTML5 validation by setting its `type` to `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +You should have an `input` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#submit` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #submit') +assert(els.length > 0) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#form` should have an `action` attribute of `https://www.freecodecamp.com/email-submit` + +```js +const el = document.getElementById('form') +assert(!!el && el.action === 'https://www.freecodecamp.com/email-submit') +``` + +Your `#email` should have a `name` attribute of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.name === 'email') +``` + +Your `#nav-bar` should always be at the top of the viewport + +```js +const el = document.getElementById('nav-bar') +const top1 = el?.offsetTop +const top2 = el?.offsetTop +assert(!!el && top1 >= -15 && top1 <= 15 && top2 >= -15 && top2 <= 15) +``` + +Your Product Landing Page should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your Product Landing Page should use CSS Flexbox at least once + +```js +const stylesheet = new __helpers.CSSHelp(document).getStyleSheet() +const cssRules = new __helpers.CSSHelp(document).styleSheetToCssRulesArray(stylesheet) +const usesFlex = cssRules.find(rule => { + return rule.style?.display === 'flex' || rule.style?.display === 'inline-flex' +}) +assert(usesFlex) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Product Landing Page + + + +
+

+ Pokemon Daycare Service +

+
+

What we offer

+
+
+ +
+
Guaranteed friendly and loving staff!
+
+
+
+ +
+
+ Comfortable environment for Pokemon to explore and play! +
+
+
+
+ +
+
+ Multiple membership plans to fit your lifestyle! +
+
+
+
+

Check us out!

+ A sneak peek into our facility: +
+ +
+
+

Membership Plans

+
+
+ Basic Membership
+
    +
  • One Pokemon
  • +
  • Food and berries provided
  • +
+ $9.99/month +
+
+ Silver Membership
+
    +
  • Up to Three Pokemon
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
+ $19.99/month +
+
+ Gold Membership
+
    +
  • Up to six Pokemon!
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
  • Personal training for each Pokemon
  • +
  • Breeding and egg hatching
  • +
+ $29.99/month +
+
+
+
+

Sign up for our newsletter!

+ + +
+ +
+ + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + max-width: 750px; + margin: 50px auto; +} +input { + background-color: #92869c; +} +a:not(.nav-link) { + color: white; +} +#header-img { + max-height: 25px; +} +#nav-bar { + position: fixed; + width: 100%; + text-align: center; + top: 0%; + background-color: #92869c; +} +h1 { + text-align: center; +} +body { + text-align: center; +} +footer { + text-align: center; +} +#bullet { + max-height: 25px; +} +.flex-here { + display: flex; + justify-content: center; +} +.flex-left { + height: 25px; +} +.flex-mem { + display: flex; + justify-content: center; +} +.flex-mem-box { + background-color: #92869c; + border-color: black; + border-width: 5px; + border-style: solid; + margin: 10px; + padding: 10px; + color: black; +} +@media (max-width: 350px) { + #video { + width: 300; + height: 200; + } +} ``` diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md index aece4b77372..937c4482c93 100644 --- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md +++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md @@ -1,57 +1,516 @@ --- id: 587d78af367417b2b2512b03 -title: 製作一個調查表格 -challengeType: 3 +title: Build a Survey Form +challengeType: 14 forumTopicId: 301145 dashedName: build-a-survey-form --- # --description-- -**目標:** 在 [CodePen.io](https://codepen.io) 上創建一個與這個功能類似的 app:。 +**Objective:** Build an app that is functionally similar to https://survey-form.freecodecamp.rocks -在滿足以下 [需求](https://en.wikipedia.org/wiki/User_story) 並能通過所有測試的前提下, 你可以根據自己的喜好來美化你的 app。 +**User Stories:** -你可以使用 HTML、JavaScript 以及 CSS 來完成項目。 由於目前你只學到了 CSS 課程,所以我們建議你只使用 CSS 來完成這個項目,同時鞏固一下你之前所學的內容。 你也可以使用 Bootstrap 或者 SASS。 我們不推薦你在這個項目中使用其他技術(比如 jQuery、React、Angular 或 Vue)。 在後續的其他項目中,你將有機會使用像是 React 等其他技術棧。 我們會接受並嘗試修復你在使用推薦技術棧創建項目時報告的問題。 祝你編碼愉快! +1. You should have a page title in an `h1` element with an `id` of `title` +1. You should have a short explanation in a `p` element with an `id` of `description` +1. You should have a `form` element with an `id` of `survey-form` +1. Inside the form element, you are **required** to enter your name in an `input` field that has an `id` of `name` and a `type` of `text` +1. Inside the form element, you are **required** to enter your email in an `input` field that has an `id` of `email` +1. If you enter an email that is not formatted correctly, you will see an HTML5 validation error +1. Inside the form, you can enter a number in an `input` field that has an `id` of `number` +1. If you enter non-numbers in the number input, you will see an HTML5 validation error +1. If you enter numbers outside the range of the number input, which are defined by the `min` and `max` attributes, you will see an HTML5 validation error +1. For the name, email, and number input fields, you can see corresponding `label` elements in the form, that describe the purpose of each field with the following ids: `id="name-label"`, `id="email-label"`, and `id="number-label"` +1. For the name, email, and number input fields, you can see placeholder text that gives a description or instructions for each field +1. Inside the form element, you should have a `select` dropdown element with an `id` of `dropdown` and at least two options to choose from +1. Inside the form element, you can select an option from a group of at least two radio buttons that are grouped using the `name` attribute +1. Inside the form element, you can select several fields from a series of checkboxes, each of which must have a `value` attribute +1. Inside the form element, you are presented with a `textarea` for additional comments +1. Inside the form element, you are presented with a button with `id` of `submit` to submit all the inputs -**需求 1:** 此 app 中應存在一個 `id="title"` 的大小爲 H1 的標題。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**需求 2:** 此 app 中應存在一段 `id="description"` 的大小爲 P 的短小的描述。 +# --hints-- -**需求 3:** 此 app 中應存在一個 `id="survey-form"` 的 `form` 元素。 +You should have an `h1` element with an `id` of `title` -**需求 4:** 在表單元素內,應存在 `id="name"` 的輸入框(必填項),以便用戶輸入姓名。 +```js +const el = document.getElementById('title') +assert(!!el && el.tagName === 'H1') +``` -**需求 5:** 在表單元素內,應存在 `id="email"` 的輸入框(必填項),以便用戶輸入郵箱。 +Your `#title` should not be empty -**需求 6:** 如果用戶輸入了格式不正確的郵箱,則應出現來自 HTML5 表單數據校驗的錯誤信息。 +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) +``` -**需求 7:** 在表單內,用戶應可以在 `id="number"` 的輸入框中輸入數字。 +You should have a `p` element with an `id` of `description` -**需求 8:** 如果用戶在數字輸入框內輸入非數字內容,則應出現來自 HTML5 表單數據校驗的錯誤信息。 +```js +const el = document.getElementById('description') +assert(!!el && el.tagName === 'P') +``` -**需求 9:** 如果用戶輸入的數字超出了使用 `min` 和 `max` 屬性定義的範圍,則應出現來自 HTML5 表單數據校驗的錯誤信息。 +Your `#description` should not be empty -**需求 10:** 表單中的姓名、郵箱和數字輸入框需有對應的包含描述輸入框用途的標籤。這些標籤的 id 應分別爲 `id="name-label"`、`id="email-label"` 和 `id="number-label"`。 +```js +const el = document.getElementById('description') +assert(!!el && el.innerText.length > 0) +``` -**需求 11:** 表單中的姓名、郵箱和數字輸入框需有對應的描述文字作爲佔位符。 +You should have a `form` element with an `id` of `survey-form` -**需求 12:** 在表單元素內,應存在一個 `id="dropdown"` 的下拉列表,用戶可以從中選取一個選項。 +```js +const el = document.getElementById('survey-form') +assert(!!el && el.tagName === 'FORM') +``` -**需求 13:** 在表單元素內,應至少存在一組單選按鈕,用戶可以從中選取一個選項。 每組應使用 `name` 屬性進行分組。 +You should have an `input` element with an `id` of `name` -**需求 14:** 在表單元素內,應存在幾個複選框,且每個複選框都應有 `value` 屬性。 +```js +const el = document.getElementById('name') +assert(!!el && el.tagName === 'INPUT') +``` -**需求 15:** 在表單元素的最後,應存在一個 `textarea` 元素,以便用戶輸入額外的批註。 +Your `#name` should have a `type` of `text` -**需求 16:** 在表單元素內,應存在一個 `id="submit"` 的按鈕,以便用戶提交表單。 +```js +const el = document.getElementById('name') +assert(!!el && el.type === 'text') +``` -你可以使用這個 CodePen 模版創建你自己的項目,點擊 `Save` 即可創建你的新項目。 也可以使用此 CDN 鏈接在任何你喜歡的環境中運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`。 +Your `#name` should require input -完成項目並通過所有測試後,請輸入你的項目在 CodePen 上的鏈接並提交。 +```js +const el = document.getElementById('name') +assert(!!el && el.required) +``` -# --solutions-- +Your `#name` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name') +assert(!!el) +``` + +You should have an `input` element with an `id` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should have a `type` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +Your `#email` should require input + +```js +const el = document.getElementById('email') +assert(!!el && el.required) +``` + +Your `#email` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email') +assert(!!el) +``` + +You should have an `input` element with an `id` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#number` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number') +assert(!!el) +``` + +Your `#number` should have a `type` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.type === 'number') +``` + +Your `#number` should have a `min` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.min && isFinite(el.min)) +``` + +Your `#number` should have a `max` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.max && isFinite(el.max)) +``` + +You should have a `label` element with an `id` of `name-label` + +```js +const el = document.getElementById('name-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `email-label` + +```js +const el = document.getElementById('email-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `number-label` + +```js +const el = document.getElementById('number-label') +assert(!!el && el.tagName === 'LABEL') +``` + +Your `#name-label` should not be empty + +```js +const el = document.getElementById('name-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#email-label` should not be empty + +```js +const el = document.getElementById('email-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#number-label` should not be empty + +```js +const el = document.getElementById('number-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#name-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name-label') +assert(!!el) +``` + +Your `#email-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email-label') +assert(!!el) +``` + +Your `#number-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number-label') +assert(!!el) +``` + +Your `#name` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('name') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#number` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('number') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +You should have a `select` field with an `id` of `dropdown` + +```js +const el = document.getElementById('dropdown') +assert(!!el && el.tagName === 'SELECT') +``` + +Your `#dropdown` should have at least two selectable (not disabled) `option` elements + +```js +const els = document.querySelectorAll('#dropdown option:not([disabled])') +assert(els.length >= 2) +``` + +Your `#dropdown` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #dropdown') +assert(!!el) +``` + +You should have at least two `input` elements with a `type` of `radio` (radio buttons) + +```js +const els = document.querySelectorAll('input[type="radio"]') +assert(els.length >= 2) +``` + +You should have at least two radio buttons that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="radio"]') +assert(els.length >= 2) +``` + +All your radio buttons should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][value=""], input[type="radio"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +All your radio buttons should have a `name` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][name=""], input[type="radio"]:not([name])') +assert(els1.length > 0 && els2.length === 0) +``` + +Every radio button group should have at least 2 radio buttons + +```js +const radioButtons = document.querySelectorAll('input[type="radio"]'); +const groups = {} + +if (radioButtons) { + radioButtons.forEach(el => { + if (!groups[el.name]) groups[el.name] = [] + groups[el.name].push(el) + }) +} + +const groupKeys = Object.keys(groups) + +groupKeys.forEach(key => { + if (groups[key].length < 2) assert(false) +}) + +assert(groupKeys.length > 0) +``` + +You should have at least two `input` elements with a `type` of `checkbox` (checkboxes) that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="checkbox"]'); +assert(els.length >= 2) +``` + +All your checkboxes inside `#survey-form` should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('#survey-form input[type="checkbox"]') +const els2 = document.querySelectorAll('#survey-form input[type="checkbox"][value=""], #survey-form input[type="checkbox"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +You should have at least one `textarea` element that is a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form textarea') +assert(!!el) +``` + +You should have an `input` or `button` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && (el.tagName === 'INPUT' || el.tagName === 'BUTTON')) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#submit` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #submit') +assert(!!el) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Survey Form + + +

Survey Form

+

The card below was built as a sample survey form for freeCodeCamp.

+
+

Join the Togepi Fan Club!

+

+ Enter your information here to receive updates about club activities, + our monthly newsletter, and other email communications. +

+
+ + + + +

Who is your favourite Pokemon?

+ + + +

Which communications do you want to receive?

+ + + +

Any other information you would like to share?

+ +

+ Please note: This form is a proof of concept. Submitting the form + will not actually transmit your data. +

+ +
+
+ + + +``` + +```css +main { + text-align: center; + background-color: #92869c; + background-blend-mode: lighten; + max-width: 500px; + margin: 20px auto; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); + color: black; +} +body { + text-align: center; + background: #3a3240; + color: white; +} +input, textarea, select, button { + background: #3a3240; + color: white; +} +a { + color: white; +} ``` diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md index a7aa06ba99c..6c433375ba7 100644 --- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md +++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md @@ -1,55 +1,525 @@ --- id: 587d78b0367417b2b2512b05 -title: 製作一個技術文檔頁面 -challengeType: 3 +title: Build a Technical Documentation Page +challengeType: 14 forumTopicId: 301146 dashedName: build-a-technical-documentation-page --- # --description-- -**目標:** 在 [CodePen.io](https://codepen.io) 上創建一個與這個功能類似的 app:。 +**Objective:** Build an app that is functionally similar to https://technical-documentation-page.freecodecamp.rocks -在滿足以下 [需求](https://en.wikipedia.org/wiki/User_story) 並能通過所有測試的前提下, 你可以根據自己的喜好來美化你的 app。 +**User Stories:** -你可以使用 HTML、JavaScript 以及 CSS 來完成項目。 由於目前你只學到了 CSS 課程,所以我們建議你只使用 CSS 來完成這個項目,同時鞏固一下你之前所學的內容。 你也可以使用 Bootstrap 或者 SASS。 我們不推薦你在這個項目中使用其他技術(比如 jQuery、React、Angular 或 Vue)。 在後續的其他項目中,你將有機會使用像是 React 等其他技術棧。 我們會接受並嘗試修復你在使用推薦技術棧創建項目時報告的問題。 祝你編碼愉快! +1. You can see a `main` element with a corresponding `id="main-doc"`, which contains the page's main content (technical documentation) +1. Within the `#main-doc` element, you can see several `section` elements, each with a class of `main-section`. There should be a minimum of five +1. The first element within each `.main-section` should be a `header` element, which contains text that describes the topic of that section. +1. Each `section` element with the class of `main-section` should also have an `id` that corresponds with the text of each `header` contained within it. Any spaces should be replaced with underscores (e.g. The section that contains the header "JavaScript and Java" should have a corresponding `id="JavaScript_and_Java"`) +1. The `.main-section` elements should contain at least ten `p` elements total (not each) +1. The `.main-section` elements should contain at least five `code` elements total (not each) +1. The `.main-section` elements should contain at least five `li` items total (not each) +1. You can see a `nav` element with a corresponding `id="navbar"` +1. The navbar element should contain one `header` element which contains text that describes the topic of the technical documentation +1. Additionally, the navbar should contain link (`a`) elements with the class of `nav-link`. There should be one for every element with the class `main-section` +1. The `header` element in the `#navbar` must come before any link (`a`) elements in the navbar +1. Each element with the class of `nav-link` should contain text that corresponds to the `header` text within each `section` (e.g. if you have a "Hello world" section/header, your navbar should have an element which contains the text "Hello world") +1. When you click on a navbar element, the page should navigate to the corresponding section of the `main-doc` element (e.g. If you click on a `nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id, and contains the corresponding header) +1. On regular sized devices (laptops, desktops), the element with `id="navbar"` should be shown on the left side of the screen and should always be visible to the user +1. Your technical documentation should use at least one media query -**需求 1:** 此 app 中應存在一個 `id="main-doc"` 的 `main` 元素,它包含頁面的主要內容(技術文檔)。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**需求 2:** 在 `#main-doc` 元素內,應有一些 `section` 元素,每個元素的 class 都應爲 `main-section`。 應存在至少 5 個這樣的元素。 +# --hints-- -**需求 3:** 每個 `.main-section` 內的第一個元素應爲 `header` 元素,其中包含描述該部分主題的內容文本。 +You should have a `main` element with an `id` of `main-doc` -**需求 4:** 類名爲 `main-section` 的每個 `section` 元素都應有一個與包含在其中的每個 `header` 的文本相對應的 id, 所有空格都應該被替換爲下劃線(例如,包含標題 “JavaScript and Java” 的 `section` 應有一個相應的 `id="JavaScript_and_Java"`)。 +```js +const el = document.getElementById('main-doc') +assert(!!el) +``` -**需求 5:** 所有 `.main-section` 元素內總計應有至少 10 個 `p` 元素。 +You should have at least five `section` elements with a class of `main-section` -**需求 6:** 所有 `.main-section` 元素內總計應有至少 5 個 `code` 元素。 +```js +const els = document.querySelectorAll('#main-doc section') +assert(els.length >= 5) +``` -**需求 7:** 所有 `.main-section` 元素內總計應有至少 5 個 `li` 元素。 +All of your `.main-section` elements should be `section` elements -**需求 8:** 此 app 中應存在一個 `id="navbar"` 的 `nav` 元素。 +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (el.tagName !== 'SECTION') assert(false) +}) +assert(els.length > 0) +``` -**需求 9:** navbar 元素內應有一個 `header` 元素,其中包含描述技術文檔主題的內容文本。 +You should have at least five `.main-section` elements that are descendants of `#main-doc` -**需求 10:** 此外,navbar 元素應包含 class 爲 `nav-link` 的 `a` 元素, 每個 class 爲 `main-section` 的元素都需要有一個。 +```js +const els = document.querySelectorAll('#main-doc .main-section') +assert(els.length >= 5) +``` -**需求 11:** navbar 中的 `header` 元素應置於 navbar 中所有 `a` 元素之前。 +The first child of each `.main-section` should be a `header` element -**需求 12:** 所有 class 爲 `nav-link` 的元素都需要包含與 `section` 中 `header` 相應的內容文本。例如,對於一個文本爲 "Hello world" 的一節或標題,你的 navbar 中也應存在一個內容文本爲 "Hello world" 的元素。 +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if(el.firstElementChild?.tagName !== 'HEADER') assert(false) +}) +assert(els.length > 0) +``` -**需求 13:** 當點擊 navbar 中一個元素時,頁面應滾動到 `main-doc` 中的相應部分。例如,點擊文本爲 "Hello world" 的 `nav-link` 元素的時候,頁面應滾動到包含相同內容的 `header` 和 id 所處的 `section` 元素。 +None of your `header` elements should be empty -**需求 14:** 在常規尺寸的設備上(如筆記本電腦和臺式機),`id="navbar"` 的元素應顯示在屏幕左側,且始終對用戶可見。 +```js +const els = document.querySelectorAll('header') +els.forEach(el => { + if (el.innerText?.length <= 0) assert(false) +}) +assert(els.length > 0) +``` -**需求 15:** 在此 app 中,應至少使用一次媒體查詢。 +All of your `.main-section` elements should have an `id` -你可以使用這個 CodePen 模版創建你自己的項目,點擊 `Save` 即可創建你的新項目。 也可以使用此 CDN 鏈接在任何你喜歡的環境中運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`。 +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (!el.id || el.id === '') assert(false) +}) +assert(els.length > 0) +``` -完成項目並通過所有測試後,請輸入你的項目在 CodePen 上的鏈接並提交。 +Each `.main-section` should have an `id` that matches the text of its first child, having any spaces in the child's text replaced with underscores (`_`) for the id’s -# --solutions-- +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + const text = el.firstElementChild?.innerText?.replaceAll(' ', '_') + if (el.id?.toUpperCase() !== text?.toUpperCase()) assert(false) +}) +assert(els.length > 0) +``` + +You should have at least 10 `p` elements (total) within your `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section p') +assert(els.length >= 10) +``` + +You should have at least five `code` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section code') +assert(els.length >= 5) +``` + +You should have at least five `li` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section li') +assert(els.length >= 5) +``` + +You should have a `nav` element with an `id` of `navbar` + +```js +const el = document.getElementById('navbar') +assert(!!el && el.tagName === 'NAV') +``` + +Your `#navbar` should have exactly one `header` element within it + +```js +const els = document.querySelectorAll('#navbar header') +assert(els.length === 1) +``` + +You should have at least one `a` element with a class of `nav-link` + +```js +const els = document.querySelectorAll('a[class="nav-link"]') +assert(els.length >= 1) +``` + +All of your `.nav-link` elements should be anchor (`a`) elements + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (el.tagName !== 'A') assert(false) +}) +assert(els.length > 0) +``` + +All of your `.nav-link` elements should be in the `#navbar` + +```js +const els1 = document.querySelectorAll('.nav-link') +const els2 = document.querySelectorAll('#navbar .nav-link') +assert(els2.length > 0 && els1.length === els2.length) +``` + +You should have the same number of `.nav-link` and `.main-section` elements + +```js +const els1 = document.querySelectorAll('.main-section') +const els2 = document.querySelectorAll('.nav-link') +assert(els1.length > 0 && els2.length > 0 && els1.length === els2.length) +``` + +The `header` element in the `#navbar` should come before any link (`a`) elements also in the `#navbar` + +```js +const navLinks = document.querySelectorAll('#navbar a.nav-link'); +const header = document.querySelector('#navbar header'); +navLinks.forEach((navLink) => { + if ( + ( + header.compareDocumentPosition(navLink) & + Node.DOCUMENT_POSITION_PRECEDING + ) + ) assert(false) +}); +assert(!!header) +``` + +Each `.nav-link` should have text that corresponds to the `header` text of its related `section` (e.g. if you have a "Hello world" section/header, your `#navbar` should have a `.nav-link` which has the text "Hello world") + +```js +const headerText = Array.from(document.querySelectorAll('.main-section')).map(el => + el.firstElementChild?.innerText?.trim().toUpperCase() +) +const linkText = Array.from(document.querySelectorAll('.nav-link')).map(el => + el.innerText?.trim().toUpperCase() +) +const remainder = headerText.filter(str => linkText.indexOf(str) === -1) +assert(headerText.length > 0 && headerText.length > 0 && remainder.length === 0) +``` + +Each `.nav-link` should have an `href` attribute that links to its corresponding `.main-section` (e.g. If you click on a `.nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id) + +```js +const hrefValues = Array.from(document.querySelectorAll('.nav-link')).map(el => el.getAttribute('href')) +const mainSectionIDs = Array.from(document.querySelectorAll('.main-section')).map(el => el.id) +const missingHrefValues = mainSectionIDs.filter(str => hrefValues.indexOf('#' + str) === -1) +assert(hrefValues.length > 0 && mainSectionIDs.length > 0 && missingHrefValues.length === 0) +``` + +Your `#navbar` should always be on the left edge of the window + +```js +const el = document.getElementById('navbar') +const left1 = el?.offsetLeft +const left2 = el?.offsetLeft +assert(!!el && left1 >= -15 && left1 <= 15 && left2 >= -15 && left2 <= 15) +``` + +Your Technical Documentation project should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Technical Documentation Page + + + +
+
+
Introduction
+

+ Welcome to a basic introduction of algebra. In this tutorial, we will + review some of the more common algebraic concepts. +

+
+
+
Definitions
+

+ To start with, let's define some of the more common terms used in + algebra: +

+
    +
  • + Variable: A variable is an unknown value, usually represented + by a letter. +
  • +
  • + Expression: Essentially a mathematical object. For the + purpose of this tutorial, an expression is one part of an equation. +
  • +
  • + Equation: An equation is a mathematical argument in which two + expressions result in the same value. +
  • +
+
+
+
Examples
+

+ Sometimes it is easier to understand the definitions when you have a + physical example to look at. Here is an example of the above terms.

+ x + 5 = 12

+ In this above example, we have: +

+
    +
  • Variable: The variable in the example is "x".
  • +
  • + Expression: There are two expressions in this example. They + are "x+5" and "12". +
  • +
  • + Equation: The entire example, "x+5=12", is an equation. +
  • +
+
+
+
Solving Equations
+

+ The primary use for algebra is to determine an unknown value, the + "variable", with the information provided. Continuing to use our + example from above, we can find the value of the variable "x".

+ x + 5 = 12

+ In an equation, both sides result in the same value. So you can + manipulate the two expressions however you need, as long as you + perform the same operation (or change) to each side. You do this + because the goal when solving an equation is to + get the variable into its own expression, or by itself on one side + of the = sign.
For this example, we want to remove the "+5" so the "x" is + alone. To do this, we can subtract 5, because subtraction is + the opposite operation to addition. But remember, we have to perform + the same operation to both sides of the equation. Now our equation + looks like this.

+ x + 5 - 5 = 12 - 5

+ The equation looks like a mess right now, because we haven't completed + the operations. We can simplify this equation to make it easier + to read by performing the operations "5-5" and "12-5". The result + is:

+ x = 7

+ We now have our solution to this equation! +

+
+
+
Solving Equations II
+

+ Let us look at a slightly more challenging equation.

+ 3x + 4 = 13

+ Again we can start with subtraction. In this case, we want to subtract + 4 from each side of the equation. We will also go ahead and simplify + with each step. So now we have:

+ 3x = 9

+ "3x" translates to "3*x", where the "*" symbol indicates + multiplication. We use the "*" to avoid confusion, as the "x" is now a + variable instead of a multiplication symbol. The opposite operation + for multiplication is division, so we need to + divide each expression by 3.

+ x = 3

+ And now we have our solution! +

+
+
+
Solving Equations III
+

+ Now we are getting in to more complex operations. Here is another + equation for us to look at:

+ x^2 - 8 = 8

+ Our very first step will be to add 8 to each side. This is + different from our previous examples, where we had to subtract. But + remember, our goal is to get the variable alone by performing opposite + operations.

+ x^2 = 16

+ But what does the "^2" mean? The "^" symbol is used to denote + exponents in situations where superscript is not available. When + superscript is available, you would see it as x2. + For the sake of this project, however, we will use the "^" symbol.
+ An exponent tells you how many times the base (in our case, "x") is + multiplied by itself. So, "x^2" would be the same as "x*x". Now the + opposite function of multiplication is division, but we would have to + divide both sides by "x". We do not want to do this, as that + would put an "x" on the other side of the equation. So instead, we + need to use the root operation! For an exponent of "2", we call this + the "square root" and denote it with "√". Our equation is now: +

+ x = √9

+ Performing a root operation by hand can be a tedious process, so we + recommend using a calculator when necessary. However, we are lucky in + that "9" is a + perfect square, so we do not need to calculate anything. Instead, we find our + answer to be:

+ x = 3 +

+
+
+
System of Equations
+

+ As you explore your algebra studies further, you may start to run + across equations with more than one variable. The first such equations + will likely look like:

+ y = 3x

+ An equation like this does not have one single solution. + Rather, there are a series of values for which the equation is true. + For example, if "x=3" and "y=9", the equation is true. These equations + are usually used to plot a graph.
+ Getting more complicated, though, you may be given a pair of + equations. This is called a "system of equations", and CAN be solved. + Let's look at how we do this! Consider the following system of + equations:

+ y = 3x | y - 6 = x + A system of equations IS solvable, but it is a multi-step process. To + get started, we need to chose a variable we are solving for. Let's + solve for "x" first. From the second equation, we know that "x" equals + "y - 6", but we cannot simplify that further because we do not have a + value for "y". Except, thanks to the system of equations, we DO have a + value for "y". We know that "y" equals "3x". So, looking at our second + equation, we can replace "y" with "3x" because they have the same + value. We then get:

+ 3x - 6 = x

+ Now we can solve for "x"! We start by adding 6 to each side.

+ 3x = x + 6

+ We still need to get "x" by itself, so we subtract "x" from both sides + and get:

+ 2x = 6

+ If this confuses you, remember that "3x" is the same as "x+x+x". + Subtract an "x" from that and you get "x+x", or "2x". Now we divide + both sides by 2 and have our value for x!

+ x = 3

+ However, our work is not done yet. We still need to find the value for + "y". Let's go back to our first equation:

+ y = 3x

+ We have a value for "x" now, so let's see what happens if we put that + value in.

+ y = 3*3

+ We perform the multiplication and discover that "y=9"! Our solution to + this system of equations then is:

+ x = 3 and y = 9

+

+
+
+
Try it Yourself!
+

Coming Soon!

+

Keep an eye out for new additions!

+
+
+
More Information
+

Check out the following links for more information!

+ +
+
+ + + +``` + +```css +* { + background-color: #3a3240; +} +a { + color: #92869c; +} +a:hover { + background-color: #92869c; + color: #3a3240; +} +#navbar { + border-style: solid; + border-width: 5px; + border-color: #92869c; + height: 100%; + top: -5px; + left: -5px; + padding: 5px; + text-align: center; + color: #92869c +} +@media (min-width: 480px) { + #navbar { + position: fixed; + } +} +main { + margin-left: 220px; + color: #92869c +} +header { + font-size: 20pt; +} +code { + background-color: #92869c; + border-style: dashed; + border-width: 2px; + border-color: #92869c; + padding: 5px; + color: black; +} +footer { + text-align: center; +} ``` diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md index 013bfda2db4..231292b4373 100644 --- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md +++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md @@ -1,43 +1,327 @@ --- id: bd7158d8c442eddfaeb5bd18 -title: 製作一個致敬頁 -challengeType: 3 +title: Build a Tribute Page +challengeType: 14 forumTopicId: 301147 dashedName: build-a-tribute-page --- # --description-- -**目標:** 在 [CodePen.io](https://codepen.io) 上創建一個與這個功能類似的 app:。 +**Objective:** Build an app that is functionally similar to https://tribute-page.freecodecamp.rocks -在滿足以下 [需求](https://en.wikipedia.org/wiki/User_story) 並能通過所有測試的前提下, 你可以根據自己的喜好來美化你的 app。 +**User Stories:** -你可以使用 HTML、JavaScript 以及 CSS 來完成項目。 由於目前你只學到了 CSS 課程,所以我們建議你只使用 CSS 來完成這個項目,同時鞏固一下你之前所學的內容。 你也可以使用 Bootstrap 或者 SASS。 我們不推薦你在這個項目中使用其他技術(比如 jQuery、React、Angular 或 Vue)。 在後續的其他項目中,你將有機會使用像是 React 等其他技術棧。 我們會接受並嘗試修復你在使用推薦技術棧創建項目時報告的問題。 祝你編碼愉快! +1. Your tribute page should have an element with a corresponding `id="main"`, which contains all other elements +1. You should see an element with an `id` of `title`, which contains a string (i.e. text), that describes the subject of the tribute page (e.g. "Dr. Norman Borlaug") +1. You should see either a `figure` or a `div` element with an `id` of `img-div` +1. Within the `img-div` element, you should see an `img` element with a corresponding `id="image"` +1. Within the `img-div` element, you should see an element with a corresponding `id="img-caption"` that contains textual content describing the image shown in `img-div` +1. You should see an element with a corresponding `id="tribute-info"`, which contains textual content describing the subject of the tribute page +1. You should see an a element with a corresponding `id="tribute-link"`, which links to an outside site, that contains additional information about the subject of the tribute page. HINT: You must give your element an attribute of `target` and set it to `_blank` in order for your link to open in a new tab +1. Your `#image` should use `max-width` and `height` properties to resize responsively, relative to the width of its parent element, without exceeding its original size +1. Your `img` element should be centered within its parent element -**需求 1:** 此 app 中應存在一個 `id="main"` 的元素,頁面上的所有元素都應置於這個元素中。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**需求 2:** 此 app 中應存在一個 `id="title"` 的元素,其中包含描述致敬頁主題的字符串文本,如 "Dr. Norman Borlaug"。 +# --hints-- -**需求 3:** 此 app 中應存在一個 `id="img-div"` 的 `figure` 或 `div` 元素。 +You should have a `main` element with an `id` of `main` -**需求 4:** 在 `img-div` 元素內,應存在一個 `id="image"` 的 `img` 元素。 +```js +const el = document.getElementById('main') +assert(!!el && el.tagName === 'MAIN') +``` -**需求 5:** 在 `img-div` 元素內,應存在一個相應的 `id="img-caption"` 的元素,其中包含對 `img-div` 中圖像的描述文本。 +Your `#img-div`, `#image`, `#img-caption`, `#tribute-info`, and `#tribute-link` should all be descendants of `#main` -**需求 6:** 此 app 中應存在一個 `id="tribute-info"` 的元素,其中應包含描述致敬頁主題的內容文本。 +```js +const el1 = document.querySelector('#main #img-div') +const el2 = document.querySelector('#main #image') +const el3 = document.querySelector('#main #img-caption') +const el4 = document.querySelector('#main #tribute-info') +const el5 = document.querySelector('#main #tribute-link') +assert(!!el1 & !!el2 && !!el3 && !!el4 && !!el5) +``` -**需求 7:** 此 app 中應存在一個 `id="tribute-link"` 的 `a` 元素,它應鏈接到一個包含有關致敬頁主題額外信息的外部網頁。 提示:你必須爲 a 元素提供 `target` 屬性,並將其屬性值設置爲 `_blank`(即 `target="_blank"`),這樣纔可以在新選項卡中打開鏈接。 +You should have an element with an `id` of `title` -**需求 8:** `img` 元素應相對於其父元素的寬度自動調整大小,但不超過圖片的原始大小。 +```js +const el = document.getElementById('title') +assert(!!el) +``` -**需求 9:** `img` 應在其父元素內居中。 +Your `#title` should not be empty -你可以使用這個 CodePen 模版創建你的新項目,點擊 `Save` 即可創建你的新項目。 也可以使用此 CDN 鏈接在任何你喜歡的環境中運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`。 +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) -完成項目並通過所有測試後,請輸入你的項目在 CodePen 上的鏈接並提交。 +``` -# --solutions-- +You should have a `figure` or `div` element with an `id` of `img-div` + +```js +const el = document.getElementById('img-div') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGURE')) +``` + +You should have an `img` element with an `id` of `image` + +```js +const el = document.getElementById('image') +assert(!!el && el.tagName === 'IMG') +``` + +Your `#image` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #image') +assert(!!el) +``` + +You should have a `figcaption` or `div` element with an `id` of `img-caption` + +```js +const el = document.getElementById('img-caption') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGCAPTION')) +``` + +Your `#img-caption` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #img-caption') +assert(!!el) +``` + +Your `#img-caption` should not be empty + +```js +const el = document.getElementById('img-caption') +assert(!!el && el.innerText.length > 0) +``` + +You should have an element with an `id` of `tribute-info` + +```js +const el = document.getElementById('tribute-info') +assert(!!el) +``` + +Your `#tribute-info` should not be empty + +```js +const el = document.getElementById('tribute-info') +assert(!!el && el.innerText.length > 0) +``` + +You should have an `a` element with an `id` of `tribute-link` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.tagName === 'A') +``` + +Your `#tribute-link` should have an `href` attribute and value + +```js +const el = document.getElementById('tribute-link') +assert(!!el && !!el.href && el.href.length > 0) +``` + +Your `#tribute-link` should have a `target` attribute set to `_blank` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.target === '_blank') +``` + +You should use an `#image` selector in your CSS to style the `#image` and pass the next three tests + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image') +assert(!!style) +``` + +Your `#image` should have a `display` of `block` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +assert(style === 'block') +``` + +Your `#image` should have a `max-width` of `100%` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +assert(style === '100%') +``` + +Your `#image` should have a `height` of `auto` + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'); +const maxWidthValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +const displayValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +const oldDisplayValue = img?.style.getPropertyValue('display'); +const oldDisplayPriority = img?.style.getPropertyPriority('display'); +img?.style.setProperty('display', 'none', 'important'); +const heightValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('height') +img?.style.setProperty('display', oldDisplayValue, oldDisplayPriority); +assert(heightValue === 'auto') +``` + +Your `#image` should be centered within its parent + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'), + imgParent = img?.parentElement, + imgLeft = img?.getBoundingClientRect().left, + imgRight = img?.getBoundingClientRect().right, + parentLeft = imgParent?.getBoundingClientRect().left, + parentRight = imgParent?.getBoundingClientRect().right, + leftMargin = imgLeft - parentLeft, + rightMargin = parentRight - imgRight; +assert(leftMargin - rightMargin < 6 && rightMargin - leftMargin < 6) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + + + Tribute Page + + +

Tribute Page

+

The below card was designed as a tribute page for freeCodeCamp.

+
+
+ An image of Togepi +
Togepi, happy as always.
+
+

Togepi

+
+
+

+ Togepi was first discovered in the Johto region, when Ash Ketchum + discovered a mysterious egg. However, when the egg hatched, Togepi saw + Ash's friend Misty first and imprinted on her. Like many other + creatures, this imprinting process created a bond and Togepi views + Misty as his mother. +

+

+ Togepi is a very childlike Pokemon, and is very emotionally + expressive. He demonstrates extreme levels of joy and sadness. +

+
+

Battle Information

+
    +
  • Type: Fairy
  • +
  • Evolutions: Togepi -> Togetic -> Togekiss
  • +
  • Moves: Growl, Pound, Sweet Kiss, Charm
  • +
  • Weaknesses: Poison, Steel
  • +
  • Resistances: Dragon
  • +
+

+ Check out this + Bulbapedia article on Togepi + for more information on this great Pokemon. +

+
+
+ + + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + background-color: #92869c; + font-family: Lobster; + max-width: 500px; + margin: 20px auto; + color: black; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); +} +h2 { + text-align: center; + font-size: 20pt; + font-family: Pacifico; +} +body { + text-align: center; + font-size: 12pt; +} +footer { + text-align: center; + font-size: 10pt; +} +.border { + border-color: black; + border-width: 5px; + border-style: solid; +} +#image { + height: auto; + display: block; + margin: auto; + max-width: 100%; + border-radius: 50%; +} +#img-caption { + font-size: 10pt; +} +a:not(#tribute-link) { + color: white; +} +hr { + border-color: black; +} ``` diff --git a/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md b/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md index 2b5444a94d8..0226992eec9 100644 --- a/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md +++ b/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md @@ -1,47 +1,277 @@ --- id: bd7158d8c242eddfaeb5bd13 -title: 制作一个个人作品集展示页 -challengeType: 3 +title: Build a Personal Portfolio Webpage +challengeType: 14 forumTopicId: 301143 dashedName: build-a-personal-portfolio-webpage --- # --description-- -**目标:** 在 [CodePen.io](https://codepen.io) 上创建一个与这个功能类似的 app:。 +**Objective:** Build an app that is functionally similar to https://personal-portfolio.freecodecamp.rocks -在满足以下[需求](https://en.wikipedia.org/wiki/User_story)并能通过所有测试的前提下, 你可以根据自己的喜好来美化你的 app。 +**User Stories:** -你可以使用 HTML、JavaScript 以及 CSS 来完成项目。 由于目前你只学到了 CSS 课程,所以我们建议你只使用 CSS 来完成这个项目,同时巩固一下你之前所学的内容。 你也可以使用 Bootstrap 或者 SASS。 我们不推荐你在这个项目中使用其他技术(比如 jQuery、React、Angular 或 Vue)。 在后续的其他项目中,你将有机会使用像是 React 等其他技术栈。 我们会接受并尝试修复你在使用推荐技术栈创建项目时报告的问题。 祝你编码愉快! +1. Your portfolio should have a welcome section with an `id` of `welcome-section` +1. The welcome section should have an `h1` element that contains text +1. Your portfolio should have a projects section with an `id` of `projects` +1. The projects section should contain at least one element with a `class` of `project-tile` to hold a project +1. The projects section should contain at least one link to a project +1. Your portfolio should have a navbar with an id of `navbar` +1. The navbar should contain at least one link that you can click on to navigate to different sections of the page +1. Your portfolio should have a link with an id of `profile-link`, which opens your GitHub or freeCodeCamp profile in a new tab +1. Your portfolio should have at least one media query +1. The height of the welcome section should be equal to the height of the viewport +1. The navbar should always be at the top of the viewport -**需求 1:** 此 app 中应存在一个 id 为 `welcome-section` 的欢迎区。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**需求 2:** 欢迎区内应存在一个包含标题文本的 `h1` 元素。 +# --hints-- -**需求 3:** 此 app 中应存在一个 id 为 `projects` 的项目展示区。 +Your portfolio should have a "Welcome" section with an `id` of `welcome-section`. -**需求 4:** 项目展示区应至少包含一个 class 为 `project-tile` 的元素来展示项目。 +```js +const el = document.getElementById('welcome-section') +assert(!!el); +``` -**需求 5:** 项目展示区应至少包含一个链接到项目的超链接元素。 +Your `#welcom-section` element should contain an `h1` element. -**需求 6:** 此 app 中应存在一个 id 为 `navbar` 的导航栏。 +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1').length, + 0, + 'Welcome section should contain an h1 element ' +); +``` -**需求 7:** 导航栏中应包含一个可以滚动到本页面不同区域的链接。 +You should not have any empty `h1` elements within `#welcome-section` element. -**需求 8:** 此 app 中应包含一个 id 为 `profile-link` 的链接。 点击这个链接时,它应在浏览器的新标签页内打开我的 GitHub 或者 FCC 作品集页面。 +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1')?.[0]?.innerText?.length, + 0, + 'h1 element in welcome section should contain your name or camper ' + + 'name ' +); +``` -**需求 9:** 在此 app 中,应至少使用一次媒体查询。 +You should have a "Projects" section with an `id` of `projects`. -**需求 10:** 欢迎区的高度应该与视口的高度保持一致。 +```js +const el = document.getElementById('projects') +assert(!!el); +``` -**需求 11:** 导航栏应始终保持在视口顶部。 +Your portfolio should contain at least one elment with a class of `project-tile`. -你可以使用这个 CodePen 模版创建你自己的项目,点击 `Save` 即可创建你的新项目。 也可以使用此 CDN 链接在任何你喜欢的环境中运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`。 +```js +assert.isAbove( + document.querySelectorAll('#projects .project-tile').length, + 0 +); +``` -完成项目并通过所有测试后,请输入你的项目在 CodePen 上的链接并提交。 +Your `#projects` element should contain at least one `a` element. -# --solutions-- +```js +assert.isAbove(document.querySelectorAll('#projects a').length, 0); +``` + +Your portfolio should have a navbar with an `id` of `navbar`. + +```js +const el = document.getElementById('navbar'); +assert(!!el); +``` + +Your `#navbar` element should contain at least one `a` element whose `href` attribute starts with `#`. + +```js +const links = [...document.querySelectorAll('#navbar a')].filter( + (nav) => (nav?.getAttribute('href') || '').substr(0, 1) === '#' +); + +assert.isAbove( + links.length, + 0, + 'Navbar should contain an anchor link ' +); +``` + +Your portfolio should have an `a` element with an `id` of `profile-link`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.tagName === 'A') +``` + +Your `#profile-link` element should have a `target` attribute of `_blank`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.target === '_blank') +``` + +Your portfolio should use at least one media query. + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your `#navbar` element should always be at the top of the viewport. + +```js +(async () => { + const timeout = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)); + + const navbar = document.getElementById('navbar'); + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + "Navbar's parent should be body and it should be at the top of " + + 'the viewport ' + ); + + window.scroll(0, 500); + + await timeout(1); + + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + 'Navbar should be at the top of the viewport even after ' + + 'scrolling ' + ); + window.scroll(0, 0); +})(); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Personal Portfolio + + + + + +
+
+
+

It's me!

+ +

Naomi Carrigan

+

Welcome to my portfolio page!

+

+
+

Projects

+

Here's what I've worked on!

+

+ + + + +


+
+

Contact me!

+

Use the links below to get in touch.

+

FreeCodeCamp.org | GitHub | Facebook | LinkedIn +

+ + + +``` + +```css +nav{ + position: fixed; + width: 100%; + text-align: right; + font-size: 24pt; + top: 0%; + right: 5px; + background-color: #000000; + color: #ffffff; +} +@media (max-width: 500px){ + nav{ + display: none; + } +} +a{ + color: #ffffff; +} +main{ + text-align: center; + background-color: black; + font-family:Pacifico +} +h1{ + font-size: 48pt; +} +h2{ + font-size: 24pt; +} +p{ + font-size: 12pt; +} +#welcome-section{ + background-color:#251a4a; + color: #FFFFFF; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#projects{ + background-color: #060a9c; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#contact{ + background-color: #03300b; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} ``` diff --git a/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md b/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md index 4fa469685f0..cdd62359751 100644 --- a/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md +++ b/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md @@ -1,55 +1,424 @@ --- id: 587d78af367417b2b2512b04 -title: 制作一个产品登录页 -challengeType: 3 +title: Build a Product Landing Page +challengeType: 14 forumTopicId: 301144 dashedName: build-a-product-landing-page --- # --description-- -**目标:** 在 [CodePen.io](https://codepen.io) 上创建一个与这个功能类似的 app:。 +**Objective:** Build an app that is functionally similar to https://product-landing-page.freecodecamp.rocks -在满足以下[需求](https://en.wikipedia.org/wiki/User_story)并能通过所有测试的前提下, 你可以根据自己的喜好来美化你的 app。 +**User Stories:** -你可以使用 HTML、JavaScript 以及 CSS 来完成项目。 由于目前你只学到了 CSS 课程,所以我们建议你只使用 CSS 来完成这个项目,同时巩固一下你之前所学的内容。 你也可以使用 Bootstrap 或者 SASS。 我们不推荐你在这个项目中使用其他技术(比如 jQuery、React、Angular 或 Vue)。 在后续的其他项目中,你将有机会使用像是 React 等其他技术栈。 我们会接受并尝试修复你在使用推荐技术栈创建项目时报告的问题。 祝你编码愉快! +1. Your product landing page should have a `header` element with a corresponding `id="header"` +1. You can see an image within the `header` element with a corresponding `id="header-img"` (A logo would make a good image here) +1. Within the `#header` element, you can see a `nav` element with a corresponding `id="nav-bar"` +1. You can see at least three clickable elements inside the `nav` element, each with the class `nav-link` +1. When you click a `.nav-link` button in the `nav` element, you are taken to the corresponding section of the landing page +1. You can watch an embedded product video with `id="video"` +1. Your landing page has a `form` element with a corresponding `id="form"` +1. Within the form, there is an `input` field with `id="email"` where you can enter an email address +1. The `#email` input field should have placeholder text to let users know what the field is for +1. The `#email` input field uses HTML5 validation to confirm that the entered text is an email address +1. Within the form, there is a submit `input` with a corresponding `id="submit"` +1. When you click the `#submit` element, the email is submitted to a static page (use this mock URL: `https://www.freecodecamp.com/email-submit`) +1. The navbar should always be at the top of the viewport +1. Your product landing page should have at least one media query +1. Your product landing page should utilize CSS flexbox at least once -**需求 1:** 产品登录页应存在 `id="header"` 的 `header` 元素。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**需求 2:** 在 `header` 元素内应存在 `id="header-img"` 的图像, 这里通常用来放置公司的 logo。 +# --hints-- -**需求 3:** 在 `#header` 元素内,应存在一个 `id="nav-bar"` 的 `nav` 元素。 +You should have a `header` element with an `id` of `header` -**需求 4:** `nav` 元素中应至少包含三个 class 为 `nav-link` 且可点击的元素。 +```js +const el = document.getElementById('header') +assert(!!el && el.tagName === 'HEADER') +``` -**需求 5:** 当点击 `nav` 内的 `.nav-link` 按钮时,应滚动到产品主页上相应的部分。 +You should have an `img` element with an `id` of `header-img` -**需求 6:** 页面上应存在 `id="video"` 的嵌入式视频播放区域。 +```js +const el = document.getElementById('header-img') +assert(!!el && el.tagName === 'IMG') +``` -**需求 7:** 产品登陆页应存在一个 `id="form"` 的 `form` 元素。 +Your `#header-img` should be a descendant of the `#header` -**需求 8:** 在表单中,应存在一个 `id="email"` 的 `input` 输入框供用户填写邮箱。 +```js +const els = document.querySelectorAll('#header #header-img') +assert(els.length > 0) +``` -**需求 9:** `#email` 输入框内应存在描述该区域用途的占位符文字。 +Your `#header-img` should have a `src` attribute -**需求 10:** `#email` 输入框应使用 HTML5 验证来确认输入的内容是否为邮箱。 +```js +const el = document.getElementById('header-img') +assert(!!el && !!el.src) +``` -**需求 11:** 在表单中,应存在一个 `id="submit"` 的 `input` 提交按钮。 +Your `#header-img`’s `src` value should be a valid URL (starts with `http`) -**需求 12:** 当点击 `#submit` 元素时,应将邮箱信息提交到一个静态页面(请使用这个模拟的 URL:)。 +```js +const el = document.getElementById('header-img') +assert(!!el && /^http/.test(el.src)) +``` -**需求 13:** navbar 应保持在视口(viewport)的顶部。 +You should have a `nav` element with an `id` of `nav-bar` -**需求 14:** 在此 app 中,应至少使用一次媒体查询。 +```js +const el = document.getElementById('nav-bar') +assert(!!el && el.tagName === 'NAV') +``` -**需求 15:** 在此 app 中,应至少使用一次 CSS 的 flexbox 布局。 +Your `#nav-bar` should be a descendant of the `#header` -你可以使用这个 CodePen 模版创建你自己的项目,点击 `Save` 即可创建你的新项目。 也可以使用此 CDN 链接在任何你喜欢的环境中运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`。 +```js +const els = document.querySelectorAll('#header #nav-bar') +assert(els.length > 0) +``` -完成项目并通过所有测试后,请输入你的项目在 CodePen 上的链接并提交。 +You should have at least 3 `.nav-link` elements within the `#nav-bar` -# --solutions-- +```js +const els = document.querySelectorAll('#nav-bar .nav-link') +assert(els.length >= 3) +``` + +Each `.nav-link` element should have an `href` attribute + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (!el.href) assert(false) +}) +assert(els.length > 0) +``` + +Each `.nav-link` element should link to a corresponding element on the landing page (has an `href` with a value of another element's id. e.g. `#footer`) + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + const linkDestination = el.getAttribute('href').slice(1) + if (!document.getElementById(linkDestination)) assert(false) +}) +assert(els.length > 0) +``` + +You should have a `video` or `iframe` element with an `id` of `video` + +```js +const el = document.getElementById('video') +assert(!!el && (el.tagName === 'VIDEO' || el.tagName === 'IFRAME')) +``` + +Your `#video` should have a `src` attribute + +```js +const el = document.getElementById('video') +assert(!!el && !!el.src) +``` + +You should have a `form` element with an `id` of `form` + +```js +const el = document.getElementById('form') +assert(!!el && el.tagName === 'FORM') +``` + +You should have an `input` element with an `id of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #email') +assert(els.length > 0) +``` + +Your `#email` should have the `placeholder` attribute with placeholder text + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should use HTML5 validation by setting its `type` to `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +You should have an `input` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#submit` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #submit') +assert(els.length > 0) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#form` should have an `action` attribute of `https://www.freecodecamp.com/email-submit` + +```js +const el = document.getElementById('form') +assert(!!el && el.action === 'https://www.freecodecamp.com/email-submit') +``` + +Your `#email` should have a `name` attribute of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.name === 'email') +``` + +Your `#nav-bar` should always be at the top of the viewport + +```js +const el = document.getElementById('nav-bar') +const top1 = el?.offsetTop +const top2 = el?.offsetTop +assert(!!el && top1 >= -15 && top1 <= 15 && top2 >= -15 && top2 <= 15) +``` + +Your Product Landing Page should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your Product Landing Page should use CSS Flexbox at least once + +```js +const stylesheet = new __helpers.CSSHelp(document).getStyleSheet() +const cssRules = new __helpers.CSSHelp(document).styleSheetToCssRulesArray(stylesheet) +const usesFlex = cssRules.find(rule => { + return rule.style?.display === 'flex' || rule.style?.display === 'inline-flex' +}) +assert(usesFlex) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Product Landing Page + + + +
+

+ Pokemon Daycare Service +

+
+

What we offer

+
+
+ +
+
Guaranteed friendly and loving staff!
+
+
+
+ +
+
+ Comfortable environment for Pokemon to explore and play! +
+
+
+
+ +
+
+ Multiple membership plans to fit your lifestyle! +
+
+
+
+

Check us out!

+ A sneak peek into our facility: +
+ +
+
+

Membership Plans

+
+
+ Basic Membership
+
    +
  • One Pokemon
  • +
  • Food and berries provided
  • +
+ $9.99/month +
+
+ Silver Membership
+
    +
  • Up to Three Pokemon
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
+ $19.99/month +
+
+ Gold Membership
+
    +
  • Up to six Pokemon!
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
  • Personal training for each Pokemon
  • +
  • Breeding and egg hatching
  • +
+ $29.99/month +
+
+
+
+

Sign up for our newsletter!

+ + +
+ +
+ + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + max-width: 750px; + margin: 50px auto; +} +input { + background-color: #92869c; +} +a:not(.nav-link) { + color: white; +} +#header-img { + max-height: 25px; +} +#nav-bar { + position: fixed; + width: 100%; + text-align: center; + top: 0%; + background-color: #92869c; +} +h1 { + text-align: center; +} +body { + text-align: center; +} +footer { + text-align: center; +} +#bullet { + max-height: 25px; +} +.flex-here { + display: flex; + justify-content: center; +} +.flex-left { + height: 25px; +} +.flex-mem { + display: flex; + justify-content: center; +} +.flex-mem-box { + background-color: #92869c; + border-color: black; + border-width: 5px; + border-style: solid; + margin: 10px; + padding: 10px; + color: black; +} +@media (max-width: 350px) { + #video { + width: 300; + height: 200; + } +} ``` diff --git a/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md b/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md index 544c2494fcf..937c4482c93 100644 --- a/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md +++ b/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md @@ -1,57 +1,516 @@ --- id: 587d78af367417b2b2512b03 -title: 制作一个调查表格 -challengeType: 3 +title: Build a Survey Form +challengeType: 14 forumTopicId: 301145 dashedName: build-a-survey-form --- # --description-- -**目标:** 在 [CodePen.io](https://codepen.io) 上创建一个与这个功能类似的 app:。 +**Objective:** Build an app that is functionally similar to https://survey-form.freecodecamp.rocks -在满足以下 [需求](https://en.wikipedia.org/wiki/User_story) 并能通过所有测试的前提下, 你可以根据自己的喜好来美化你的 app。 +**User Stories:** -你可以使用 HTML、JavaScript 以及 CSS 来完成项目。 由于目前你只学到了 CSS 课程,所以我们建议你只使用 CSS 来完成这个项目,同时巩固一下你之前所学的内容。 你也可以使用 Bootstrap 或者 SASS。 我们不推荐你在这个项目中使用其他技术(比如 jQuery、React、Angular 或 Vue)。 在后续的其他项目中,你将有机会使用像是 React 等其他技术栈。 我们会接受并尝试修复你在使用推荐技术栈创建项目时报告的问题。 祝你编码愉快! +1. You should have a page title in an `h1` element with an `id` of `title` +1. You should have a short explanation in a `p` element with an `id` of `description` +1. You should have a `form` element with an `id` of `survey-form` +1. Inside the form element, you are **required** to enter your name in an `input` field that has an `id` of `name` and a `type` of `text` +1. Inside the form element, you are **required** to enter your email in an `input` field that has an `id` of `email` +1. If you enter an email that is not formatted correctly, you will see an HTML5 validation error +1. Inside the form, you can enter a number in an `input` field that has an `id` of `number` +1. If you enter non-numbers in the number input, you will see an HTML5 validation error +1. If you enter numbers outside the range of the number input, which are defined by the `min` and `max` attributes, you will see an HTML5 validation error +1. For the name, email, and number input fields, you can see corresponding `label` elements in the form, that describe the purpose of each field with the following ids: `id="name-label"`, `id="email-label"`, and `id="number-label"` +1. For the name, email, and number input fields, you can see placeholder text that gives a description or instructions for each field +1. Inside the form element, you should have a `select` dropdown element with an `id` of `dropdown` and at least two options to choose from +1. Inside the form element, you can select an option from a group of at least two radio buttons that are grouped using the `name` attribute +1. Inside the form element, you can select several fields from a series of checkboxes, each of which must have a `value` attribute +1. Inside the form element, you are presented with a `textarea` for additional comments +1. Inside the form element, you are presented with a button with `id` of `submit` to submit all the inputs -**需求 1:** 此 app 中应存在一个 `id="title"` 的大小为 H1 的标题。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**需求 2:** 此 app 中应存在一段 `id="description"` 的大小为 P 的短小的描述。 +# --hints-- -**需求 3:** 此 app 中应存在一个 `id="survey-form"` 的 `form` 元素。 +You should have an `h1` element with an `id` of `title` -**需求 4:** 在表单元素内,应存在 `id="name"` 的输入框(必填项),以便用户输入姓名。 +```js +const el = document.getElementById('title') +assert(!!el && el.tagName === 'H1') +``` -**需求 5:** 在表单元素内,应存在 `id="email"` 的输入框(必填项),以便用户输入邮箱。 +Your `#title` should not be empty -**需求 6:** 如果用户输入了格式不正确的邮箱,则应出现来自 HTML5 表单数据校验的错误信息。 +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) +``` -**需求 7:** 在表单内,用户应可以在 `id="number"` 的输入框中输入数字。 +You should have a `p` element with an `id` of `description` -**需求 8:** 如果用户在数字输入框内输入非数字内容,则应出现来自 HTML5 表单数据校验的错误信息。 +```js +const el = document.getElementById('description') +assert(!!el && el.tagName === 'P') +``` -**需求 9:** 如果用户输入的数字超出了使用 `min` 和 `max` 属性定义的范围,则应出现来自 HTML5 表单数据校验的错误信息。 +Your `#description` should not be empty -**需求 10:** 表单中的姓名、邮箱和数字输入框需有对应的包含描述输入框用途的标签。这些标签的 id 应分别为 `id="name-label"`、`id="email-label"` 和 `id="number-label"`。 +```js +const el = document.getElementById('description') +assert(!!el && el.innerText.length > 0) +``` -**需求 11:** 表单中的姓名、邮箱和数字输入框需有对应的描述文字作为占位符。 +You should have a `form` element with an `id` of `survey-form` -**需求 12:** 在表单元素内,应存在一个 `id="dropdown"` 的下拉列表,用户可以从中选取一个选项。 +```js +const el = document.getElementById('survey-form') +assert(!!el && el.tagName === 'FORM') +``` -**需求 13:** 在表单元素内,应至少存在一组单选按钮,用户可以从中选取一个选项。 每组应使用 `name` 属性进行分组。 +You should have an `input` element with an `id` of `name` -**需求 14:** 在表单元素内,应存在几个复选框,且每个复选框都应有 `value` 属性。 +```js +const el = document.getElementById('name') +assert(!!el && el.tagName === 'INPUT') +``` -**需求 15:** 在表单元素的最后,应存在一个 `textarea` 元素,以便用户输入额外的批注。 +Your `#name` should have a `type` of `text` -**需求 16:** 在表单元素内,应存在一个 `id="submit"` 的按钮,以便用户提交表单。 +```js +const el = document.getElementById('name') +assert(!!el && el.type === 'text') +``` -你可以使用这个 CodePen 模版创建你自己的项目,点击 `Save` 即可创建你的新项目。 也可以使用此 CDN 链接在任何你喜欢的环境中运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`。 +Your `#name` should require input -完成项目并通过所有测试后,请输入你的项目在 CodePen 上的链接并提交。 +```js +const el = document.getElementById('name') +assert(!!el && el.required) +``` -# --solutions-- +Your `#name` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name') +assert(!!el) +``` + +You should have an `input` element with an `id` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should have a `type` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +Your `#email` should require input + +```js +const el = document.getElementById('email') +assert(!!el && el.required) +``` + +Your `#email` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email') +assert(!!el) +``` + +You should have an `input` element with an `id` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#number` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number') +assert(!!el) +``` + +Your `#number` should have a `type` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.type === 'number') +``` + +Your `#number` should have a `min` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.min && isFinite(el.min)) +``` + +Your `#number` should have a `max` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.max && isFinite(el.max)) +``` + +You should have a `label` element with an `id` of `name-label` + +```js +const el = document.getElementById('name-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `email-label` + +```js +const el = document.getElementById('email-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `number-label` + +```js +const el = document.getElementById('number-label') +assert(!!el && el.tagName === 'LABEL') +``` + +Your `#name-label` should not be empty + +```js +const el = document.getElementById('name-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#email-label` should not be empty + +```js +const el = document.getElementById('email-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#number-label` should not be empty + +```js +const el = document.getElementById('number-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#name-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name-label') +assert(!!el) +``` + +Your `#email-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email-label') +assert(!!el) +``` + +Your `#number-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number-label') +assert(!!el) +``` + +Your `#name` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('name') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#number` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('number') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +You should have a `select` field with an `id` of `dropdown` + +```js +const el = document.getElementById('dropdown') +assert(!!el && el.tagName === 'SELECT') +``` + +Your `#dropdown` should have at least two selectable (not disabled) `option` elements + +```js +const els = document.querySelectorAll('#dropdown option:not([disabled])') +assert(els.length >= 2) +``` + +Your `#dropdown` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #dropdown') +assert(!!el) +``` + +You should have at least two `input` elements with a `type` of `radio` (radio buttons) + +```js +const els = document.querySelectorAll('input[type="radio"]') +assert(els.length >= 2) +``` + +You should have at least two radio buttons that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="radio"]') +assert(els.length >= 2) +``` + +All your radio buttons should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][value=""], input[type="radio"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +All your radio buttons should have a `name` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][name=""], input[type="radio"]:not([name])') +assert(els1.length > 0 && els2.length === 0) +``` + +Every radio button group should have at least 2 radio buttons + +```js +const radioButtons = document.querySelectorAll('input[type="radio"]'); +const groups = {} + +if (radioButtons) { + radioButtons.forEach(el => { + if (!groups[el.name]) groups[el.name] = [] + groups[el.name].push(el) + }) +} + +const groupKeys = Object.keys(groups) + +groupKeys.forEach(key => { + if (groups[key].length < 2) assert(false) +}) + +assert(groupKeys.length > 0) +``` + +You should have at least two `input` elements with a `type` of `checkbox` (checkboxes) that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="checkbox"]'); +assert(els.length >= 2) +``` + +All your checkboxes inside `#survey-form` should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('#survey-form input[type="checkbox"]') +const els2 = document.querySelectorAll('#survey-form input[type="checkbox"][value=""], #survey-form input[type="checkbox"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +You should have at least one `textarea` element that is a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form textarea') +assert(!!el) +``` + +You should have an `input` or `button` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && (el.tagName === 'INPUT' || el.tagName === 'BUTTON')) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#submit` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #submit') +assert(!!el) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Survey Form + + +

Survey Form

+

The card below was built as a sample survey form for freeCodeCamp.

+
+

Join the Togepi Fan Club!

+

+ Enter your information here to receive updates about club activities, + our monthly newsletter, and other email communications. +

+
+ + + + +

Who is your favourite Pokemon?

+ + + +

Which communications do you want to receive?

+ + + +

Any other information you would like to share?

+ +

+ Please note: This form is a proof of concept. Submitting the form + will not actually transmit your data. +

+ +
+
+ + + +``` + +```css +main { + text-align: center; + background-color: #92869c; + background-blend-mode: lighten; + max-width: 500px; + margin: 20px auto; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); + color: black; +} +body { + text-align: center; + background: #3a3240; + color: white; +} +input, textarea, select, button { + background: #3a3240; + color: white; +} +a { + color: white; +} ``` diff --git a/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md b/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md index b16d78431d4..6c433375ba7 100644 --- a/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md +++ b/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md @@ -1,55 +1,525 @@ --- id: 587d78b0367417b2b2512b05 -title: 制作一个技术文档页面 -challengeType: 3 +title: Build a Technical Documentation Page +challengeType: 14 forumTopicId: 301146 dashedName: build-a-technical-documentation-page --- # --description-- -**目标:** 在 [CodePen.io](https://codepen.io) 上创建一个与这个功能类似的 app:。 +**Objective:** Build an app that is functionally similar to https://technical-documentation-page.freecodecamp.rocks -在满足以下 [需求](https://en.wikipedia.org/wiki/User_story) 并能通过所有测试的前提下, 你可以根据自己的喜好来美化你的 app。 +**User Stories:** -你可以使用 HTML、JavaScript 以及 CSS 来完成项目。 由于目前你只学到了 CSS 课程,所以我们建议你只使用 CSS 来完成这个项目,同时巩固一下你之前所学的内容。 你也可以使用 Bootstrap 或者 SASS。 我们不推荐你在这个项目中使用其他技术(比如 jQuery、React、Angular 或 Vue)。 在后续的其他项目中,你将有机会使用像是 React 等其他技术栈。 我们会接受并尝试修复你在使用推荐技术栈创建项目时报告的问题。 祝你编码愉快! +1. You can see a `main` element with a corresponding `id="main-doc"`, which contains the page's main content (technical documentation) +1. Within the `#main-doc` element, you can see several `section` elements, each with a class of `main-section`. There should be a minimum of five +1. The first element within each `.main-section` should be a `header` element, which contains text that describes the topic of that section. +1. Each `section` element with the class of `main-section` should also have an `id` that corresponds with the text of each `header` contained within it. Any spaces should be replaced with underscores (e.g. The section that contains the header "JavaScript and Java" should have a corresponding `id="JavaScript_and_Java"`) +1. The `.main-section` elements should contain at least ten `p` elements total (not each) +1. The `.main-section` elements should contain at least five `code` elements total (not each) +1. The `.main-section` elements should contain at least five `li` items total (not each) +1. You can see a `nav` element with a corresponding `id="navbar"` +1. The navbar element should contain one `header` element which contains text that describes the topic of the technical documentation +1. Additionally, the navbar should contain link (`a`) elements with the class of `nav-link`. There should be one for every element with the class `main-section` +1. The `header` element in the `#navbar` must come before any link (`a`) elements in the navbar +1. Each element with the class of `nav-link` should contain text that corresponds to the `header` text within each `section` (e.g. if you have a "Hello world" section/header, your navbar should have an element which contains the text "Hello world") +1. When you click on a navbar element, the page should navigate to the corresponding section of the `main-doc` element (e.g. If you click on a `nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id, and contains the corresponding header) +1. On regular sized devices (laptops, desktops), the element with `id="navbar"` should be shown on the left side of the screen and should always be visible to the user +1. Your technical documentation should use at least one media query -**需求 1:** 此 app 中应存在一个 `id="main-doc"` 的 `main` 元素,它包含页面的主要内容(技术文档)。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**需求 2:** 在 `#main-doc` 元素内,应有一些 `section` 元素,每个元素的 class 都应为 `main-section`。 应存在至少 5 个这样的元素。 +# --hints-- -**需求 3:** 每个 `.main-section` 内的第一个元素应为 `header` 元素,其中包含描述该部分主题的内容文本。 +You should have a `main` element with an `id` of `main-doc` -**需求 4:** 类名为 `main-section` 的每个 `section` 元素都应有一个与包含在其中的每个 `header` 的文本相对应的 id, 所有空格都应该被替换为下划线(例如,包含标题 “JavaScript and Java” 的 `section` 应有一个相应的 `id="JavaScript_and_Java"`)。 +```js +const el = document.getElementById('main-doc') +assert(!!el) +``` -**需求 5:** 所有 `.main-section` 元素内总计应有至少 10 个 `p` 元素。 +You should have at least five `section` elements with a class of `main-section` -**需求 6:** 所有 `.main-section` 元素内总计应有至少 5 个 `code` 元素。 +```js +const els = document.querySelectorAll('#main-doc section') +assert(els.length >= 5) +``` -**需求 7:** 所有 `.main-section` 元素内总计应有至少 5 个 `li` 元素。 +All of your `.main-section` elements should be `section` elements -**需求 8:** 此 app 中应存在一个 `id="navbar"` 的 `nav` 元素。 +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (el.tagName !== 'SECTION') assert(false) +}) +assert(els.length > 0) +``` -**需求 9:** navbar 元素内应有一个 `header` 元素,其中包含描述技术文档主题的内容文本。 +You should have at least five `.main-section` elements that are descendants of `#main-doc` -**需求 10:** 此外,navbar 元素应包含 class 为 `nav-link` 的 `a` 元素, 每个 class 为 `main-section` 的元素都需要有一个。 +```js +const els = document.querySelectorAll('#main-doc .main-section') +assert(els.length >= 5) +``` -**需求 11:** navbar 中的 `header` 元素应置于 navbar 中所有 `a` 元素之前。 +The first child of each `.main-section` should be a `header` element -**需求 12:** 所有 class 为 `nav-link` 的元素都需要包含与 `section` 中 `header` 相应的内容文本。例如,对于一个文本为 "Hello world" 的一节或标题,你的 navbar 中也应存在一个内容文本为 "Hello world" 的元素。 +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if(el.firstElementChild?.tagName !== 'HEADER') assert(false) +}) +assert(els.length > 0) +``` -**需求 13:** 当点击 navbar 中一个元素时,页面应滚动到 `main-doc` 中的相应部分。例如,点击文本为 "Hello world" 的 `nav-link` 元素的时候,页面应滚动到包含相同内容的 `header` 和 id 所处的 `section` 元素。 +None of your `header` elements should be empty -**需求 14:** 在常规尺寸的设备上(如笔记本电脑和台式机),`id="navbar"` 的元素应显示在屏幕左侧,且始终对用户可见。 +```js +const els = document.querySelectorAll('header') +els.forEach(el => { + if (el.innerText?.length <= 0) assert(false) +}) +assert(els.length > 0) +``` -**需求 15:** 在此 app 中,应至少使用一次媒体查询。 +All of your `.main-section` elements should have an `id` -你可以使用这个 CodePen 模版创建你自己的项目,点击 `Save` 即可创建你的新项目。 也可以使用此 CDN 链接在任何你喜欢的环境中运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`。 +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (!el.id || el.id === '') assert(false) +}) +assert(els.length > 0) +``` -完成项目并通过所有测试后,请输入你的项目在 CodePen 上的链接并提交。 +Each `.main-section` should have an `id` that matches the text of its first child, having any spaces in the child's text replaced with underscores (`_`) for the id’s -# --solutions-- +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + const text = el.firstElementChild?.innerText?.replaceAll(' ', '_') + if (el.id?.toUpperCase() !== text?.toUpperCase()) assert(false) +}) +assert(els.length > 0) +``` + +You should have at least 10 `p` elements (total) within your `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section p') +assert(els.length >= 10) +``` + +You should have at least five `code` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section code') +assert(els.length >= 5) +``` + +You should have at least five `li` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section li') +assert(els.length >= 5) +``` + +You should have a `nav` element with an `id` of `navbar` + +```js +const el = document.getElementById('navbar') +assert(!!el && el.tagName === 'NAV') +``` + +Your `#navbar` should have exactly one `header` element within it + +```js +const els = document.querySelectorAll('#navbar header') +assert(els.length === 1) +``` + +You should have at least one `a` element with a class of `nav-link` + +```js +const els = document.querySelectorAll('a[class="nav-link"]') +assert(els.length >= 1) +``` + +All of your `.nav-link` elements should be anchor (`a`) elements + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (el.tagName !== 'A') assert(false) +}) +assert(els.length > 0) +``` + +All of your `.nav-link` elements should be in the `#navbar` + +```js +const els1 = document.querySelectorAll('.nav-link') +const els2 = document.querySelectorAll('#navbar .nav-link') +assert(els2.length > 0 && els1.length === els2.length) +``` + +You should have the same number of `.nav-link` and `.main-section` elements + +```js +const els1 = document.querySelectorAll('.main-section') +const els2 = document.querySelectorAll('.nav-link') +assert(els1.length > 0 && els2.length > 0 && els1.length === els2.length) +``` + +The `header` element in the `#navbar` should come before any link (`a`) elements also in the `#navbar` + +```js +const navLinks = document.querySelectorAll('#navbar a.nav-link'); +const header = document.querySelector('#navbar header'); +navLinks.forEach((navLink) => { + if ( + ( + header.compareDocumentPosition(navLink) & + Node.DOCUMENT_POSITION_PRECEDING + ) + ) assert(false) +}); +assert(!!header) +``` + +Each `.nav-link` should have text that corresponds to the `header` text of its related `section` (e.g. if you have a "Hello world" section/header, your `#navbar` should have a `.nav-link` which has the text "Hello world") + +```js +const headerText = Array.from(document.querySelectorAll('.main-section')).map(el => + el.firstElementChild?.innerText?.trim().toUpperCase() +) +const linkText = Array.from(document.querySelectorAll('.nav-link')).map(el => + el.innerText?.trim().toUpperCase() +) +const remainder = headerText.filter(str => linkText.indexOf(str) === -1) +assert(headerText.length > 0 && headerText.length > 0 && remainder.length === 0) +``` + +Each `.nav-link` should have an `href` attribute that links to its corresponding `.main-section` (e.g. If you click on a `.nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id) + +```js +const hrefValues = Array.from(document.querySelectorAll('.nav-link')).map(el => el.getAttribute('href')) +const mainSectionIDs = Array.from(document.querySelectorAll('.main-section')).map(el => el.id) +const missingHrefValues = mainSectionIDs.filter(str => hrefValues.indexOf('#' + str) === -1) +assert(hrefValues.length > 0 && mainSectionIDs.length > 0 && missingHrefValues.length === 0) +``` + +Your `#navbar` should always be on the left edge of the window + +```js +const el = document.getElementById('navbar') +const left1 = el?.offsetLeft +const left2 = el?.offsetLeft +assert(!!el && left1 >= -15 && left1 <= 15 && left2 >= -15 && left2 <= 15) +``` + +Your Technical Documentation project should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Technical Documentation Page + + + +
+
+
Introduction
+

+ Welcome to a basic introduction of algebra. In this tutorial, we will + review some of the more common algebraic concepts. +

+
+
+
Definitions
+

+ To start with, let's define some of the more common terms used in + algebra: +

+
    +
  • + Variable: A variable is an unknown value, usually represented + by a letter. +
  • +
  • + Expression: Essentially a mathematical object. For the + purpose of this tutorial, an expression is one part of an equation. +
  • +
  • + Equation: An equation is a mathematical argument in which two + expressions result in the same value. +
  • +
+
+
+
Examples
+

+ Sometimes it is easier to understand the definitions when you have a + physical example to look at. Here is an example of the above terms.

+ x + 5 = 12

+ In this above example, we have: +

+
    +
  • Variable: The variable in the example is "x".
  • +
  • + Expression: There are two expressions in this example. They + are "x+5" and "12". +
  • +
  • + Equation: The entire example, "x+5=12", is an equation. +
  • +
+
+
+
Solving Equations
+

+ The primary use for algebra is to determine an unknown value, the + "variable", with the information provided. Continuing to use our + example from above, we can find the value of the variable "x".

+ x + 5 = 12

+ In an equation, both sides result in the same value. So you can + manipulate the two expressions however you need, as long as you + perform the same operation (or change) to each side. You do this + because the goal when solving an equation is to + get the variable into its own expression, or by itself on one side + of the = sign.
For this example, we want to remove the "+5" so the "x" is + alone. To do this, we can subtract 5, because subtraction is + the opposite operation to addition. But remember, we have to perform + the same operation to both sides of the equation. Now our equation + looks like this.

+ x + 5 - 5 = 12 - 5

+ The equation looks like a mess right now, because we haven't completed + the operations. We can simplify this equation to make it easier + to read by performing the operations "5-5" and "12-5". The result + is:

+ x = 7

+ We now have our solution to this equation! +

+
+
+
Solving Equations II
+

+ Let us look at a slightly more challenging equation.

+ 3x + 4 = 13

+ Again we can start with subtraction. In this case, we want to subtract + 4 from each side of the equation. We will also go ahead and simplify + with each step. So now we have:

+ 3x = 9

+ "3x" translates to "3*x", where the "*" symbol indicates + multiplication. We use the "*" to avoid confusion, as the "x" is now a + variable instead of a multiplication symbol. The opposite operation + for multiplication is division, so we need to + divide each expression by 3.

+ x = 3

+ And now we have our solution! +

+
+
+
Solving Equations III
+

+ Now we are getting in to more complex operations. Here is another + equation for us to look at:

+ x^2 - 8 = 8

+ Our very first step will be to add 8 to each side. This is + different from our previous examples, where we had to subtract. But + remember, our goal is to get the variable alone by performing opposite + operations.

+ x^2 = 16

+ But what does the "^2" mean? The "^" symbol is used to denote + exponents in situations where superscript is not available. When + superscript is available, you would see it as x2. + For the sake of this project, however, we will use the "^" symbol.
+ An exponent tells you how many times the base (in our case, "x") is + multiplied by itself. So, "x^2" would be the same as "x*x". Now the + opposite function of multiplication is division, but we would have to + divide both sides by "x". We do not want to do this, as that + would put an "x" on the other side of the equation. So instead, we + need to use the root operation! For an exponent of "2", we call this + the "square root" and denote it with "√". Our equation is now: +

+ x = √9

+ Performing a root operation by hand can be a tedious process, so we + recommend using a calculator when necessary. However, we are lucky in + that "9" is a + perfect square, so we do not need to calculate anything. Instead, we find our + answer to be:

+ x = 3 +

+
+
+
System of Equations
+

+ As you explore your algebra studies further, you may start to run + across equations with more than one variable. The first such equations + will likely look like:

+ y = 3x

+ An equation like this does not have one single solution. + Rather, there are a series of values for which the equation is true. + For example, if "x=3" and "y=9", the equation is true. These equations + are usually used to plot a graph.
+ Getting more complicated, though, you may be given a pair of + equations. This is called a "system of equations", and CAN be solved. + Let's look at how we do this! Consider the following system of + equations:

+ y = 3x | y - 6 = x + A system of equations IS solvable, but it is a multi-step process. To + get started, we need to chose a variable we are solving for. Let's + solve for "x" first. From the second equation, we know that "x" equals + "y - 6", but we cannot simplify that further because we do not have a + value for "y". Except, thanks to the system of equations, we DO have a + value for "y". We know that "y" equals "3x". So, looking at our second + equation, we can replace "y" with "3x" because they have the same + value. We then get:

+ 3x - 6 = x

+ Now we can solve for "x"! We start by adding 6 to each side.

+ 3x = x + 6

+ We still need to get "x" by itself, so we subtract "x" from both sides + and get:

+ 2x = 6

+ If this confuses you, remember that "3x" is the same as "x+x+x". + Subtract an "x" from that and you get "x+x", or "2x". Now we divide + both sides by 2 and have our value for x!

+ x = 3

+ However, our work is not done yet. We still need to find the value for + "y". Let's go back to our first equation:

+ y = 3x

+ We have a value for "x" now, so let's see what happens if we put that + value in.

+ y = 3*3

+ We perform the multiplication and discover that "y=9"! Our solution to + this system of equations then is:

+ x = 3 and y = 9

+

+
+
+
Try it Yourself!
+

Coming Soon!

+

Keep an eye out for new additions!

+
+
+
More Information
+

Check out the following links for more information!

+ +
+
+ + + +``` + +```css +* { + background-color: #3a3240; +} +a { + color: #92869c; +} +a:hover { + background-color: #92869c; + color: #3a3240; +} +#navbar { + border-style: solid; + border-width: 5px; + border-color: #92869c; + height: 100%; + top: -5px; + left: -5px; + padding: 5px; + text-align: center; + color: #92869c +} +@media (min-width: 480px) { + #navbar { + position: fixed; + } +} +main { + margin-left: 220px; + color: #92869c +} +header { + font-size: 20pt; +} +code { + background-color: #92869c; + border-style: dashed; + border-width: 2px; + border-color: #92869c; + padding: 5px; + color: black; +} +footer { + text-align: center; +} ``` diff --git a/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md b/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md index 6703bd11532..231292b4373 100644 --- a/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md +++ b/curriculum/challenges/chinese/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md @@ -1,43 +1,327 @@ --- id: bd7158d8c442eddfaeb5bd18 -title: 制作一个致敬页 -challengeType: 3 +title: Build a Tribute Page +challengeType: 14 forumTopicId: 301147 dashedName: build-a-tribute-page --- # --description-- -**目标:** 在 [CodePen.io](https://codepen.io) 上创建一个与这个功能类似的 app:。 +**Objective:** Build an app that is functionally similar to https://tribute-page.freecodecamp.rocks -在满足以下 [需求](https://en.wikipedia.org/wiki/User_story) 并能通过所有测试的前提下, 你可以根据自己的喜好来美化你的 app。 +**User Stories:** -你可以使用 HTML、JavaScript 以及 CSS 来完成项目。 由于目前你只学到了 CSS 课程,所以我们建议你只使用 CSS 来完成这个项目,同时巩固一下你之前所学的内容。 你也可以使用 Bootstrap 或者 SASS。 我们不推荐你在这个项目中使用其他技术(比如 jQuery、React、Angular 或 Vue)。 在后续的其他项目中,你将有机会使用像是 React 等其他技术栈。 我们会接受并尝试修复你在使用推荐技术栈创建项目时报告的问题。 祝你编码愉快! +1. Your tribute page should have an element with a corresponding `id="main"`, which contains all other elements +1. You should see an element with an `id` of `title`, which contains a string (i.e. text), that describes the subject of the tribute page (e.g. "Dr. Norman Borlaug") +1. You should see either a `figure` or a `div` element with an `id` of `img-div` +1. Within the `img-div` element, you should see an `img` element with a corresponding `id="image"` +1. Within the `img-div` element, you should see an element with a corresponding `id="img-caption"` that contains textual content describing the image shown in `img-div` +1. You should see an element with a corresponding `id="tribute-info"`, which contains textual content describing the subject of the tribute page +1. You should see an a element with a corresponding `id="tribute-link"`, which links to an outside site, that contains additional information about the subject of the tribute page. HINT: You must give your element an attribute of `target` and set it to `_blank` in order for your link to open in a new tab +1. Your `#image` should use `max-width` and `height` properties to resize responsively, relative to the width of its parent element, without exceeding its original size +1. Your `img` element should be centered within its parent element -**需求 1:** 此 app 中应存在一个 `id="main"` 的元素,页面上的所有元素都应置于这个元素中。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**需求 2:** 此 app 中应存在一个 `id="title"` 的元素,其中包含描述致敬页主题的字符串文本,如 "Dr. Norman Borlaug"。 +# --hints-- -**需求 3:** 此 app 中应存在一个 `id="img-div"` 的 `figure` 或 `div` 元素。 +You should have a `main` element with an `id` of `main` -**需求 4:** 在 `img-div` 元素内,应存在一个 `id="image"` 的 `img` 元素。 +```js +const el = document.getElementById('main') +assert(!!el && el.tagName === 'MAIN') +``` -**需求 5:** 在 `img-div` 元素内,应存在一个相应的 `id="img-caption"` 的元素,其中包含对 `img-div` 中图像的描述文本。 +Your `#img-div`, `#image`, `#img-caption`, `#tribute-info`, and `#tribute-link` should all be descendants of `#main` -**需求 6:** 此 app 中应存在一个 `id="tribute-info"` 的元素,其中应包含描述致敬页主题的内容文本。 +```js +const el1 = document.querySelector('#main #img-div') +const el2 = document.querySelector('#main #image') +const el3 = document.querySelector('#main #img-caption') +const el4 = document.querySelector('#main #tribute-info') +const el5 = document.querySelector('#main #tribute-link') +assert(!!el1 & !!el2 && !!el3 && !!el4 && !!el5) +``` -**需求 7:** 此 app 中应存在一个 `id="tribute-link"` 的 `a` 元素,它应链接到一个包含有关致敬页主题额外信息的外部网页。 提示:你必须为 a 元素提供 `target` 属性,并将其属性值设置为 `_blank`(即 `target="_blank"`),这样才可以在新选项卡中打开链接。 +You should have an element with an `id` of `title` -**需求 8:** `img` 元素应相对于其父元素的宽度自动调整大小,但不超过图片的原始大小。 +```js +const el = document.getElementById('title') +assert(!!el) +``` -**需求 9:** `img` 应在其父元素内居中。 +Your `#title` should not be empty -你可以使用这个 CodePen 模版创建你的新项目,点击 `Save` 即可创建你的新项目。 也可以使用此 CDN 链接在任何你喜欢的环境中运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`。 +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) -完成项目并通过所有测试后,请输入你的项目在 CodePen 上的链接并提交。 +``` -# --solutions-- +You should have a `figure` or `div` element with an `id` of `img-div` + +```js +const el = document.getElementById('img-div') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGURE')) +``` + +You should have an `img` element with an `id` of `image` + +```js +const el = document.getElementById('image') +assert(!!el && el.tagName === 'IMG') +``` + +Your `#image` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #image') +assert(!!el) +``` + +You should have a `figcaption` or `div` element with an `id` of `img-caption` + +```js +const el = document.getElementById('img-caption') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGCAPTION')) +``` + +Your `#img-caption` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #img-caption') +assert(!!el) +``` + +Your `#img-caption` should not be empty + +```js +const el = document.getElementById('img-caption') +assert(!!el && el.innerText.length > 0) +``` + +You should have an element with an `id` of `tribute-info` + +```js +const el = document.getElementById('tribute-info') +assert(!!el) +``` + +Your `#tribute-info` should not be empty + +```js +const el = document.getElementById('tribute-info') +assert(!!el && el.innerText.length > 0) +``` + +You should have an `a` element with an `id` of `tribute-link` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.tagName === 'A') +``` + +Your `#tribute-link` should have an `href` attribute and value + +```js +const el = document.getElementById('tribute-link') +assert(!!el && !!el.href && el.href.length > 0) +``` + +Your `#tribute-link` should have a `target` attribute set to `_blank` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.target === '_blank') +``` + +You should use an `#image` selector in your CSS to style the `#image` and pass the next three tests + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image') +assert(!!style) +``` + +Your `#image` should have a `display` of `block` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +assert(style === 'block') +``` + +Your `#image` should have a `max-width` of `100%` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +assert(style === '100%') +``` + +Your `#image` should have a `height` of `auto` + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'); +const maxWidthValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +const displayValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +const oldDisplayValue = img?.style.getPropertyValue('display'); +const oldDisplayPriority = img?.style.getPropertyPriority('display'); +img?.style.setProperty('display', 'none', 'important'); +const heightValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('height') +img?.style.setProperty('display', oldDisplayValue, oldDisplayPriority); +assert(heightValue === 'auto') +``` + +Your `#image` should be centered within its parent + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'), + imgParent = img?.parentElement, + imgLeft = img?.getBoundingClientRect().left, + imgRight = img?.getBoundingClientRect().right, + parentLeft = imgParent?.getBoundingClientRect().left, + parentRight = imgParent?.getBoundingClientRect().right, + leftMargin = imgLeft - parentLeft, + rightMargin = parentRight - imgRight; +assert(leftMargin - rightMargin < 6 && rightMargin - leftMargin < 6) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + + + Tribute Page + + +

Tribute Page

+

The below card was designed as a tribute page for freeCodeCamp.

+
+
+ An image of Togepi +
Togepi, happy as always.
+
+

Togepi

+
+
+

+ Togepi was first discovered in the Johto region, when Ash Ketchum + discovered a mysterious egg. However, when the egg hatched, Togepi saw + Ash's friend Misty first and imprinted on her. Like many other + creatures, this imprinting process created a bond and Togepi views + Misty as his mother. +

+

+ Togepi is a very childlike Pokemon, and is very emotionally + expressive. He demonstrates extreme levels of joy and sadness. +

+
+

Battle Information

+
    +
  • Type: Fairy
  • +
  • Evolutions: Togepi -> Togetic -> Togekiss
  • +
  • Moves: Growl, Pound, Sweet Kiss, Charm
  • +
  • Weaknesses: Poison, Steel
  • +
  • Resistances: Dragon
  • +
+

+ Check out this + Bulbapedia article on Togepi + for more information on this great Pokemon. +

+
+
+ + + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + background-color: #92869c; + font-family: Lobster; + max-width: 500px; + margin: 20px auto; + color: black; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); +} +h2 { + text-align: center; + font-size: 20pt; + font-family: Pacifico; +} +body { + text-align: center; + font-size: 12pt; +} +footer { + text-align: center; + font-size: 10pt; +} +.border { + border-color: black; + border-width: 5px; + border-style: solid; +} +#image { + height: auto; + display: block; + margin: auto; + max-width: 100%; + border-radius: 50%; +} +#img-caption { + font-size: 10pt; +} +a:not(#tribute-link) { + color: white; +} +hr { + border-color: black; +} ``` diff --git a/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md b/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md index fe6a5cb0e81..0226992eec9 100644 --- a/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md +++ b/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md @@ -1,47 +1,277 @@ --- id: bd7158d8c242eddfaeb5bd13 -title: Construye una página portafolio personal -challengeType: 3 +title: Build a Personal Portfolio Webpage +challengeType: 14 forumTopicId: 301143 dashedName: build-a-personal-portfolio-webpage --- # --description-- -**Objetivo:** Construye una aplicación en [CodePen.io](https://codepen.io) que funcionalmente sea similar a esta: . +**Objective:** Build an app that is functionally similar to https://personal-portfolio.freecodecamp.rocks -Completa las siguientes [historias de usuario](https://es.wikipedia.org/wiki/Historias_de_usuario) y consigue aprobar todas las pruebas. Dale tu propio estilo personal. +**User Stories:** -Puedes usar HTML, JavaScript y CSS para completar este proyecto. Se recomienda usar CSS puro porque eso es lo que las lecciones han cubierto hasta ahora y debes practicar un poco con él. Puedes usar Bootstrap o SASS si lo deseas. Tecnologías adicionales (por ejemplo, jQuery, React, Angular o Vue) no se recomiendan para este proyecto, y usarlas es bajo tu propio riesgo. Otros proyectos te darán la oportunidad de trabajar con diferentes stacks de tecnologías como React. Aceptaremos e intentaremos solucionar todos los informes de incidencias que utilicen el stack de tecnología sugerido para este proyecto. ¡Feliz día programando! +1. Your portfolio should have a welcome section with an `id` of `welcome-section` +1. The welcome section should have an `h1` element that contains text +1. Your portfolio should have a projects section with an `id` of `projects` +1. The projects section should contain at least one element with a `class` of `project-tile` to hold a project +1. The projects section should contain at least one link to a project +1. Your portfolio should have a navbar with an id of `navbar` +1. The navbar should contain at least one link that you can click on to navigate to different sections of the page +1. Your portfolio should have a link with an id of `profile-link`, which opens your GitHub or freeCodeCamp profile in a new tab +1. Your portfolio should have at least one media query +1. The height of the welcome section should be equal to the height of the viewport +1. The navbar should always be at the top of the viewport -**Historia de Usuario #1:** Mi portafolio debería tener una sección de bienvenida con un id establecido como `welcome-section`. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**Historia de Usuario #2:** La sección de bienvenida debería tener un elemento `h1` que contenga texto. +# --hints-- -**Historia de Usuario #3:** Mi portafolio debería tener una sección de proyectos con un id establecido como `projects`. +Your portfolio should have a "Welcome" section with an `id` of `welcome-section`. -**Historia de Usuario #4:** La sección de proyectos debería contener al menos un elemento con una clase de `project-tile` para abarcar un proyecto. +```js +const el = document.getElementById('welcome-section') +assert(!!el); +``` -**Historia de Usuario #5:** La sección de proyectos debe contener al menos un enlace a un proyecto. +Your `#welcom-section` element should contain an `h1` element. -**Historia de Usuario #6:** Mi portafolio debería tener una barra de navegación con un id establecido como `navbar`. +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1').length, + 0, + 'Welcome section should contain an h1 element ' +); +``` -**Historia de Usuario #7:** La barra de navegación debe contener al menos un enlace en el que puedo hacer clic para navegar a diferentes secciones de la página. +You should not have any empty `h1` elements within `#welcome-section` element. -**Historia de Usuario #8:** Mi portafolio debería tener un enlace con un id establecido como `profile-link`, el cual abre mi perfil de GitHub o FCC en una nueva pestaña. +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1')?.[0]?.innerText?.length, + 0, + 'h1 element in welcome section should contain your name or camper ' + + 'name ' +); +``` -**Historia de Usuario #9:** Mi portafolio debería tener al menos una consulta de medios (media query). +You should have a "Projects" section with an `id` of `projects`. -**Historia de Usuario #10:** La altura de la sección de bienvenida debe ser igual a la altura del viewport. +```js +const el = document.getElementById('projects') +assert(!!el); +``` -**Historia de Usuario #11:** La barra de navegación debe estar siempre en la parte superior del viewport. +Your portfolio should contain at least one elment with a class of `project-tile`. -Puedes construir tu proyecto con usando esta plantilla CodePen y haciendo clic en `Save` para crear tu propio lápiz. O puedes utilizar este enlace CDN para ejecutar los tests en cualquier entorno que desees: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +assert.isAbove( + document.querySelectorAll('#projects .project-tile').length, + 0 +); +``` -Una vez que hayas terminado, envía la URL de tu proyecto funcional con todos los tests aprobados. +Your `#projects` element should contain at least one `a` element. -# --solutions-- +```js +assert.isAbove(document.querySelectorAll('#projects a').length, 0); +``` + +Your portfolio should have a navbar with an `id` of `navbar`. + +```js +const el = document.getElementById('navbar'); +assert(!!el); +``` + +Your `#navbar` element should contain at least one `a` element whose `href` attribute starts with `#`. + +```js +const links = [...document.querySelectorAll('#navbar a')].filter( + (nav) => (nav?.getAttribute('href') || '').substr(0, 1) === '#' +); + +assert.isAbove( + links.length, + 0, + 'Navbar should contain an anchor link ' +); +``` + +Your portfolio should have an `a` element with an `id` of `profile-link`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.tagName === 'A') +``` + +Your `#profile-link` element should have a `target` attribute of `_blank`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.target === '_blank') +``` + +Your portfolio should use at least one media query. + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your `#navbar` element should always be at the top of the viewport. + +```js +(async () => { + const timeout = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)); + + const navbar = document.getElementById('navbar'); + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + "Navbar's parent should be body and it should be at the top of " + + 'the viewport ' + ); + + window.scroll(0, 500); + + await timeout(1); + + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + 'Navbar should be at the top of the viewport even after ' + + 'scrolling ' + ); + window.scroll(0, 0); +})(); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Personal Portfolio + + + + + +
+
+
+

It's me!

+ +

Naomi Carrigan

+

Welcome to my portfolio page!

+

+
+

Projects

+

Here's what I've worked on!

+

+ + + + +


+
+

Contact me!

+

Use the links below to get in touch.

+

FreeCodeCamp.org | GitHub | Facebook | LinkedIn +

+ + + +``` + +```css +nav{ + position: fixed; + width: 100%; + text-align: right; + font-size: 24pt; + top: 0%; + right: 5px; + background-color: #000000; + color: #ffffff; +} +@media (max-width: 500px){ + nav{ + display: none; + } +} +a{ + color: #ffffff; +} +main{ + text-align: center; + background-color: black; + font-family:Pacifico +} +h1{ + font-size: 48pt; +} +h2{ + font-size: 24pt; +} +p{ + font-size: 12pt; +} +#welcome-section{ + background-color:#251a4a; + color: #FFFFFF; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#projects{ + background-color: #060a9c; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#contact{ + background-color: #03300b; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} ``` diff --git a/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md b/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md index f4fdf8e5316..cdd62359751 100644 --- a/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md +++ b/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md @@ -1,55 +1,424 @@ --- id: 587d78af367417b2b2512b04 -title: Construye una página de aterrizaje de producto -challengeType: 3 +title: Build a Product Landing Page +challengeType: 14 forumTopicId: 301144 dashedName: build-a-product-landing-page --- # --description-- -**Objetivo:** Construye una aplicación en [CodePen.io](https://codepen.io) que funcionalmente sea similar a esta: . +**Objective:** Build an app that is functionally similar to https://product-landing-page.freecodecamp.rocks -Completa las siguientes [historias de usuario](https://es.wikipedia.org/wiki/Historias_de_usuario) y consigue aprobar todos los tests. Dale tu propio estilo personal. +**User Stories:** -Puedes usar HTML, JavaScript y CSS para completar este proyecto. Se recomienda usar CSS puro porque eso es lo que las lecciones han cubierto hasta ahora y debes practicar un poco con él. Puedes usar Bootstrap o SASS si lo deseas. Tecnologías adicionales (por ejemplo, jQuery, React, Angular o Vue) no se recomiendan para este proyecto, y usarlas es bajo tu propio riesgo. Otros proyectos te darán la oportunidad de trabajar con diferentes stacks de tecnologías como React. Aceptaremos e intentaremos solucionar todos los informes de incidencias que utilicen el stack de tecnología sugerido para este proyecto. ¡Feliz día programando! +1. Your product landing page should have a `header` element with a corresponding `id="header"` +1. You can see an image within the `header` element with a corresponding `id="header-img"` (A logo would make a good image here) +1. Within the `#header` element, you can see a `nav` element with a corresponding `id="nav-bar"` +1. You can see at least three clickable elements inside the `nav` element, each with the class `nav-link` +1. When you click a `.nav-link` button in the `nav` element, you are taken to the corresponding section of the landing page +1. You can watch an embedded product video with `id="video"` +1. Your landing page has a `form` element with a corresponding `id="form"` +1. Within the form, there is an `input` field with `id="email"` where you can enter an email address +1. The `#email` input field should have placeholder text to let users know what the field is for +1. The `#email` input field uses HTML5 validation to confirm that the entered text is an email address +1. Within the form, there is a submit `input` with a corresponding `id="submit"` +1. When you click the `#submit` element, the email is submitted to a static page (use this mock URL: `https://www.freecodecamp.com/email-submit`) +1. The navbar should always be at the top of the viewport +1. Your product landing page should have at least one media query +1. Your product landing page should utilize CSS flexbox at least once -**Historia de Usuario #1:** Mi página de aterrizaje de producto debería tener un elemento `header` con un respectivo `id="header"`. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**Historia de Usuario #2:** Puedo ver una imagen dentro del elemento `header` con un respectivo `id="header-img"`. El logotipo de una empresa sería una buena opción de imagen aquí. +# --hints-- -**Historia de Usuario #3:** Dentro del elemento `#header` puedo ver un elemento `nav` con un respectivo `id="nav-bar"`. +You should have a `header` element with an `id` of `header` -**Historia de Usuario #4:** Puedo ver al menos tres elementos en los que se puede hacer click dentro del elemento `nav`, cada uno con la clase `nav-link`. +```js +const el = document.getElementById('header') +assert(!!el && el.tagName === 'HEADER') +``` -**Historia de Usuario #5:** Cuando hago clic en un botón `.nav-link` en el elemento `nav`, soy llevado a la sección correspondiente de la página de aterrizaje. +You should have an `img` element with an `id` of `header-img` -**Historia de Usuario #6:** Puedo ver un video de producto incrustado con `id="video"`. +```js +const el = document.getElementById('header-img') +assert(!!el && el.tagName === 'IMG') +``` -**Historia de usuario #8:** Mi página de aterrizaje tiene un elemento `form` con un respectivo `id="form"`. +Your `#header-img` should be a descendant of the `#header` -**Historia de Usuario #8:** Dentro del formulario, hay un campo de entrada `input` con `id="email"` donde puedo introducir una dirección de correo electrónico. +```js +const els = document.querySelectorAll('#header #header-img') +assert(els.length > 0) +``` -**Historia de Usuario #9:** El campo de entrada `#email` debe tener un texto provisional para que el usuario sepa para qué sirve el campo. +Your `#header-img` should have a `src` attribute -**Historia de Usuario #10:** El campo de entrada `#email` utiliza la validación de HTML5 para confirmar que el texto introducido es una dirección de correo electrónico. +```js +const el = document.getElementById('header-img') +assert(!!el && !!el.src) +``` -**Historia de Usuario #11:** Dentro del formulario, hay un `input` de envío con un respectivo `id="submit"`. +Your `#header-img`’s `src` value should be a valid URL (starts with `http`) -**Historia de Usuario #12:** Cuando hago clic en el elemento `#submit`, el correo electrónico se envía a una página estática (utiliza esta URL de pruebas: [https://www. reecodecamp.com/email-submit](https://www.freecodecamp.com/email-submit)). +```js +const el = document.getElementById('header-img') +assert(!!el && /^http/.test(el.src)) +``` -**Historia de Usuario #13:** La barra de navegación debe estar siempre en la parte superior del viewport. +You should have a `nav` element with an `id` of `nav-bar` -**Historia de Usuario #14:** Mi página de aterrizaje de producto debería tener al menos una media query. +```js +const el = document.getElementById('nav-bar') +assert(!!el && el.tagName === 'NAV') +``` -**Historia de Usuario #15:** Mi página de aterrizaje de producto debería utilizar CSS flexbox al menos una vez. +Your `#nav-bar` should be a descendant of the `#header` -Puedes construir tu proyecto usando esta plantilla CodePen y haciendo clic en `Save` para crear tu propio pen. O puedes utilizar este enlace CDN para ejecutar los tests en cualquier entorno que desees: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +const els = document.querySelectorAll('#header #nav-bar') +assert(els.length > 0) +``` -Una vez que hayas terminado, envía la URL de tu proyecto funcional con todos los tests aprobados. +You should have at least 3 `.nav-link` elements within the `#nav-bar` -# --solutions-- +```js +const els = document.querySelectorAll('#nav-bar .nav-link') +assert(els.length >= 3) +``` + +Each `.nav-link` element should have an `href` attribute + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (!el.href) assert(false) +}) +assert(els.length > 0) +``` + +Each `.nav-link` element should link to a corresponding element on the landing page (has an `href` with a value of another element's id. e.g. `#footer`) + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + const linkDestination = el.getAttribute('href').slice(1) + if (!document.getElementById(linkDestination)) assert(false) +}) +assert(els.length > 0) +``` + +You should have a `video` or `iframe` element with an `id` of `video` + +```js +const el = document.getElementById('video') +assert(!!el && (el.tagName === 'VIDEO' || el.tagName === 'IFRAME')) +``` + +Your `#video` should have a `src` attribute + +```js +const el = document.getElementById('video') +assert(!!el && !!el.src) +``` + +You should have a `form` element with an `id` of `form` + +```js +const el = document.getElementById('form') +assert(!!el && el.tagName === 'FORM') +``` + +You should have an `input` element with an `id of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #email') +assert(els.length > 0) +``` + +Your `#email` should have the `placeholder` attribute with placeholder text + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should use HTML5 validation by setting its `type` to `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +You should have an `input` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#submit` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #submit') +assert(els.length > 0) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#form` should have an `action` attribute of `https://www.freecodecamp.com/email-submit` + +```js +const el = document.getElementById('form') +assert(!!el && el.action === 'https://www.freecodecamp.com/email-submit') +``` + +Your `#email` should have a `name` attribute of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.name === 'email') +``` + +Your `#nav-bar` should always be at the top of the viewport + +```js +const el = document.getElementById('nav-bar') +const top1 = el?.offsetTop +const top2 = el?.offsetTop +assert(!!el && top1 >= -15 && top1 <= 15 && top2 >= -15 && top2 <= 15) +``` + +Your Product Landing Page should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your Product Landing Page should use CSS Flexbox at least once + +```js +const stylesheet = new __helpers.CSSHelp(document).getStyleSheet() +const cssRules = new __helpers.CSSHelp(document).styleSheetToCssRulesArray(stylesheet) +const usesFlex = cssRules.find(rule => { + return rule.style?.display === 'flex' || rule.style?.display === 'inline-flex' +}) +assert(usesFlex) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Product Landing Page + + + +
+

+ Pokemon Daycare Service +

+
+

What we offer

+
+
+ +
+
Guaranteed friendly and loving staff!
+
+
+
+ +
+
+ Comfortable environment for Pokemon to explore and play! +
+
+
+
+ +
+
+ Multiple membership plans to fit your lifestyle! +
+
+
+
+

Check us out!

+ A sneak peek into our facility: +
+ +
+
+

Membership Plans

+
+
+ Basic Membership
+
    +
  • One Pokemon
  • +
  • Food and berries provided
  • +
+ $9.99/month +
+
+ Silver Membership
+
    +
  • Up to Three Pokemon
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
+ $19.99/month +
+
+ Gold Membership
+
    +
  • Up to six Pokemon!
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
  • Personal training for each Pokemon
  • +
  • Breeding and egg hatching
  • +
+ $29.99/month +
+
+
+
+

Sign up for our newsletter!

+ + +
+ +
+ + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + max-width: 750px; + margin: 50px auto; +} +input { + background-color: #92869c; +} +a:not(.nav-link) { + color: white; +} +#header-img { + max-height: 25px; +} +#nav-bar { + position: fixed; + width: 100%; + text-align: center; + top: 0%; + background-color: #92869c; +} +h1 { + text-align: center; +} +body { + text-align: center; +} +footer { + text-align: center; +} +#bullet { + max-height: 25px; +} +.flex-here { + display: flex; + justify-content: center; +} +.flex-left { + height: 25px; +} +.flex-mem { + display: flex; + justify-content: center; +} +.flex-mem-box { + background-color: #92869c; + border-color: black; + border-width: 5px; + border-style: solid; + margin: 10px; + padding: 10px; + color: black; +} +@media (max-width: 350px) { + #video { + width: 300; + height: 200; + } +} ``` diff --git a/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md b/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md index 72914bc43f0..937c4482c93 100644 --- a/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md +++ b/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md @@ -1,57 +1,516 @@ --- id: 587d78af367417b2b2512b03 -title: Crea un formulario de encuesta -challengeType: 3 +title: Build a Survey Form +challengeType: 14 forumTopicId: 301145 dashedName: build-a-survey-form --- # --description-- -**Objetivo:** Construye una aplicación en [CodePen.io](https://codepen.io) que funcionalmente sea similar a esta: . +**Objective:** Build an app that is functionally similar to https://survey-form.freecodecamp.rocks -Completa las siguientes [historias de usuario](https://es.wikipedia.org/wiki/Historias_de_usuario) y consigue aprobar todos los tests. Dale tu propio estilo personal. +**User Stories:** -Puedes usar HTML, JavaScript y CSS para completar este proyecto. Se recomienda usar CSS puro porque eso es lo que las lecciones han cubierto hasta ahora y debes practicar un poco con él. Puedes usar Bootstrap o SASS si lo deseas. Tecnologías adicionales (por ejemplo, jQuery, React, Angular o Vue) no se recomiendan para este proyecto, y usarlas es bajo tu propio riesgo. Otros proyectos te darán la oportunidad de trabajar con diferentes stacks de tecnologías como React. Aceptaremos e intentaremos solucionar todos los informes de incidencias que utilicen el stack de tecnología sugerido para este proyecto. ¡Feliz día programando! +1. You should have a page title in an `h1` element with an `id` of `title` +1. You should have a short explanation in a `p` element with an `id` of `description` +1. You should have a `form` element with an `id` of `survey-form` +1. Inside the form element, you are **required** to enter your name in an `input` field that has an `id` of `name` and a `type` of `text` +1. Inside the form element, you are **required** to enter your email in an `input` field that has an `id` of `email` +1. If you enter an email that is not formatted correctly, you will see an HTML5 validation error +1. Inside the form, you can enter a number in an `input` field that has an `id` of `number` +1. If you enter non-numbers in the number input, you will see an HTML5 validation error +1. If you enter numbers outside the range of the number input, which are defined by the `min` and `max` attributes, you will see an HTML5 validation error +1. For the name, email, and number input fields, you can see corresponding `label` elements in the form, that describe the purpose of each field with the following ids: `id="name-label"`, `id="email-label"`, and `id="number-label"` +1. For the name, email, and number input fields, you can see placeholder text that gives a description or instructions for each field +1. Inside the form element, you should have a `select` dropdown element with an `id` of `dropdown` and at least two options to choose from +1. Inside the form element, you can select an option from a group of at least two radio buttons that are grouped using the `name` attribute +1. Inside the form element, you can select several fields from a series of checkboxes, each of which must have a `value` attribute +1. Inside the form element, you are presented with a `textarea` for additional comments +1. Inside the form element, you are presented with a button with `id` of `submit` to submit all the inputs -**Historia de Usuario #1:** Puedo ver un título con `id="title"` en texto tamaño H1. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**Historia de Usuario #2:** Puedo ver una breve explicación con `id="description"` en texto tamaño P. +# --hints-- -**Historia de Usuario #3:** Puedo ver un elemento `form` con `id="survey-form"`. +You should have an `h1` element with an `id` of `title` -**Historia de Usuario #4:** Dentro del elemento form, es requerido introducir mi nombre en un campo con `id="name"`. +```js +const el = document.getElementById('title') +assert(!!el && el.tagName === 'H1') +``` -**Historia de Usuario #5:** Dentro del elemento form, es requerido introducir un correo electrónico en un campo con `id="email"`. +Your `#title` should not be empty -**Historia de Usuario #6:** Si introduzco un correo electrónico que no cuente con el formato correcto, veré un error de validación HTML5. +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) +``` -**Historia de Usuario #7:** Dentro del formulario, puedo introducir un número en un campo con `id="number"`. +You should have a `p` element with an `id` of `description` -**Historia de Usuario #8:** Si introduzco valores no numéricos en la entrada de números, veré un error de validación HTML5. +```js +const el = document.getElementById('description') +assert(!!el && el.tagName === 'P') +``` -**Historia de Usuario #9:** Si introduzco números fuera del rango de la entrada de números, los cuales son definidos por los atributos `min` y `max`, veré un error de validación HTML5. +Your `#description` should not be empty -**Historia de Usuario #10:** Para los campos nombre, correo, y número dentro del formulario puedo ver las etiquetas (labels) correspondientes que describen el propósito de cada campo con los siguientes ids: `id="name-label"`, `id="email-label"`, y `id="number-label"`. +```js +const el = document.getElementById('description') +assert(!!el && el.innerText.length > 0) +``` -**Historia de Usuario #11:** Para los campos nombre, correo y número, puedo ver el texto provisional que me da una descripción o instrucciones para cada campo. +You should have a `form` element with an `id` of `survey-form` -**Historia de Usuario #12:** Dentro del elemento form, puedo seleccionar una opción de un menú desplegable que tiene el respectivo `id="dropdown"`. +```js +const el = document.getElementById('survey-form') +assert(!!el && el.tagName === 'FORM') +``` -**Historia de Usuario #13:** Dentro del elemento form, puedo seleccionar un campo de uno o más grupos de botones de radio. Cada grupo debe agruparse utilizando el atributo `name`. +You should have an `input` element with an `id` of `name` -**Historia de Usuario #14:** Dentro del elemento form, puedo seleccionar varios campos en una serie de casillas de verificación, cada una de las cuales debe tener un atributo `value`. +```js +const el = document.getElementById('name') +assert(!!el && el.tagName === 'INPUT') +``` -**Historia de Usuario #15:** Dentro del elemento form, me es presentado un `textarea` final para hacer comentarios adicionales. +Your `#name` should have a `type` of `text` -**Historia de Usuario #16:** Dentro del elemento form, me es presentado un botón con `id="submit"` para enviar todas mis entradas. +```js +const el = document.getElementById('name') +assert(!!el && el.type === 'text') +``` -Puedes construir tu proyecto usando esta plantilla CodePen y haciendo clic en `Save` para crear tu propio pen. O puedes utilizar este enlace CDN para ejecutar los tests en cualquier entorno que desees: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +Your `#name` should require input -Una vez que hayas terminado, envía la URL de tu proyecto funcional con todos los tests aprobados. +```js +const el = document.getElementById('name') +assert(!!el && el.required) +``` -# --solutions-- +Your `#name` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name') +assert(!!el) +``` + +You should have an `input` element with an `id` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should have a `type` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +Your `#email` should require input + +```js +const el = document.getElementById('email') +assert(!!el && el.required) +``` + +Your `#email` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email') +assert(!!el) +``` + +You should have an `input` element with an `id` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#number` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number') +assert(!!el) +``` + +Your `#number` should have a `type` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.type === 'number') +``` + +Your `#number` should have a `min` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.min && isFinite(el.min)) +``` + +Your `#number` should have a `max` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.max && isFinite(el.max)) +``` + +You should have a `label` element with an `id` of `name-label` + +```js +const el = document.getElementById('name-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `email-label` + +```js +const el = document.getElementById('email-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `number-label` + +```js +const el = document.getElementById('number-label') +assert(!!el && el.tagName === 'LABEL') +``` + +Your `#name-label` should not be empty + +```js +const el = document.getElementById('name-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#email-label` should not be empty + +```js +const el = document.getElementById('email-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#number-label` should not be empty + +```js +const el = document.getElementById('number-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#name-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name-label') +assert(!!el) +``` + +Your `#email-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email-label') +assert(!!el) +``` + +Your `#number-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number-label') +assert(!!el) +``` + +Your `#name` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('name') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#number` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('number') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +You should have a `select` field with an `id` of `dropdown` + +```js +const el = document.getElementById('dropdown') +assert(!!el && el.tagName === 'SELECT') +``` + +Your `#dropdown` should have at least two selectable (not disabled) `option` elements + +```js +const els = document.querySelectorAll('#dropdown option:not([disabled])') +assert(els.length >= 2) +``` + +Your `#dropdown` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #dropdown') +assert(!!el) +``` + +You should have at least two `input` elements with a `type` of `radio` (radio buttons) + +```js +const els = document.querySelectorAll('input[type="radio"]') +assert(els.length >= 2) +``` + +You should have at least two radio buttons that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="radio"]') +assert(els.length >= 2) +``` + +All your radio buttons should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][value=""], input[type="radio"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +All your radio buttons should have a `name` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][name=""], input[type="radio"]:not([name])') +assert(els1.length > 0 && els2.length === 0) +``` + +Every radio button group should have at least 2 radio buttons + +```js +const radioButtons = document.querySelectorAll('input[type="radio"]'); +const groups = {} + +if (radioButtons) { + radioButtons.forEach(el => { + if (!groups[el.name]) groups[el.name] = [] + groups[el.name].push(el) + }) +} + +const groupKeys = Object.keys(groups) + +groupKeys.forEach(key => { + if (groups[key].length < 2) assert(false) +}) + +assert(groupKeys.length > 0) +``` + +You should have at least two `input` elements with a `type` of `checkbox` (checkboxes) that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="checkbox"]'); +assert(els.length >= 2) +``` + +All your checkboxes inside `#survey-form` should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('#survey-form input[type="checkbox"]') +const els2 = document.querySelectorAll('#survey-form input[type="checkbox"][value=""], #survey-form input[type="checkbox"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +You should have at least one `textarea` element that is a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form textarea') +assert(!!el) +``` + +You should have an `input` or `button` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && (el.tagName === 'INPUT' || el.tagName === 'BUTTON')) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#submit` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #submit') +assert(!!el) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Survey Form + + +

Survey Form

+

The card below was built as a sample survey form for freeCodeCamp.

+
+

Join the Togepi Fan Club!

+

+ Enter your information here to receive updates about club activities, + our monthly newsletter, and other email communications. +

+
+ + + + +

Who is your favourite Pokemon?

+ + + +

Which communications do you want to receive?

+ + + +

Any other information you would like to share?

+ +

+ Please note: This form is a proof of concept. Submitting the form + will not actually transmit your data. +

+ +
+
+ + + +``` + +```css +main { + text-align: center; + background-color: #92869c; + background-blend-mode: lighten; + max-width: 500px; + margin: 20px auto; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); + color: black; +} +body { + text-align: center; + background: #3a3240; + color: white; +} +input, textarea, select, button { + background: #3a3240; + color: white; +} +a { + color: white; +} ``` diff --git a/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md b/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md index 57a94b9880d..6c433375ba7 100644 --- a/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md +++ b/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md @@ -1,55 +1,525 @@ --- id: 587d78b0367417b2b2512b05 -title: Construye una página de documentación técnica -challengeType: 3 +title: Build a Technical Documentation Page +challengeType: 14 forumTopicId: 301146 dashedName: build-a-technical-documentation-page --- # --description-- -**Objetivo:** Construye una aplicación en [CodePen.io](https://codepen.io) que funcionalmente sea similar a esta: . +**Objective:** Build an app that is functionally similar to https://technical-documentation-page.freecodecamp.rocks -Completa las siguientes [historias de usuario](https://es.wikipedia.org/wiki/Historias_de_usuario) y consigue aprobar todos los tests. Dale tu propio estilo personal. +**User Stories:** -Puedes usar HTML, JavaScript y CSS para completar este proyecto. Se recomienda usar CSS puro porque eso es lo que las lecciones han cubierto hasta ahora y debes practicar un poco con él. Puedes usar Bootstrap o SASS si lo deseas. Tecnologías adicionales (por ejemplo, jQuery, React, Angular o Vue) no se recomiendan para este proyecto, y usarlas es bajo tu propio riesgo. Otros proyectos te darán la oportunidad de trabajar con diferentes stacks de tecnologías como React. Aceptaremos e intentaremos solucionar todos los informes de incidencias que utilicen el stack de tecnología sugerido para este proyecto. ¡Feliz día programando! +1. You can see a `main` element with a corresponding `id="main-doc"`, which contains the page's main content (technical documentation) +1. Within the `#main-doc` element, you can see several `section` elements, each with a class of `main-section`. There should be a minimum of five +1. The first element within each `.main-section` should be a `header` element, which contains text that describes the topic of that section. +1. Each `section` element with the class of `main-section` should also have an `id` that corresponds with the text of each `header` contained within it. Any spaces should be replaced with underscores (e.g. The section that contains the header "JavaScript and Java" should have a corresponding `id="JavaScript_and_Java"`) +1. The `.main-section` elements should contain at least ten `p` elements total (not each) +1. The `.main-section` elements should contain at least five `code` elements total (not each) +1. The `.main-section` elements should contain at least five `li` items total (not each) +1. You can see a `nav` element with a corresponding `id="navbar"` +1. The navbar element should contain one `header` element which contains text that describes the topic of the technical documentation +1. Additionally, the navbar should contain link (`a`) elements with the class of `nav-link`. There should be one for every element with the class `main-section` +1. The `header` element in the `#navbar` must come before any link (`a`) elements in the navbar +1. Each element with the class of `nav-link` should contain text that corresponds to the `header` text within each `section` (e.g. if you have a "Hello world" section/header, your navbar should have an element which contains the text "Hello world") +1. When you click on a navbar element, the page should navigate to the corresponding section of the `main-doc` element (e.g. If you click on a `nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id, and contains the corresponding header) +1. On regular sized devices (laptops, desktops), the element with `id="navbar"` should be shown on the left side of the screen and should always be visible to the user +1. Your technical documentation should use at least one media query -**Historia de Usuario #1:** Puedo ver un elemento `main` con un respectivo `id="main-doc"`, que contiene el contenido principal de la página (documentación técnica). +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**Historia de Usuario #2:** Dentro del elemento `#main-doc` puedo ver varios elementos `section`, cada uno con una clase `main-section`. Debería haber un mínimo de 5. +# --hints-- -**Historia de Usuario #3:** El primer elemento dentro de cada sección `.main-section` debería ser un elemento `header` que contenga texto describiendo el tema de esa sección. +You should have a `main` element with an `id` of `main-doc` -**Historia de Usuario #4:** Cada elemento `section` con la clase `main-section` también debería tener un id que corresponda con el texto de cada `header` contenido en él. Cualquier espacio debería ser reemplazado por guiones bajos (p.e. La sección `section` que contiene el título "JavaScript and Java" debería tener un respectivo `id="JavaScript_and_Java"`). +```js +const el = document.getElementById('main-doc') +assert(!!el) +``` -**Historia de Usuario #5:** Los elementos `.main-section` deberían contener al menos 10 elementos `p` en total (no cada uno). +You should have at least five `section` elements with a class of `main-section` -**Historia de Usuario #6:** Los elementos `.main-section` deberían contener al menos 5 elementos `code` en total (no cada uno). +```js +const els = document.querySelectorAll('#main-doc section') +assert(els.length >= 5) +``` -**Historia de Usuario #7:** Los elementos `.main-section` deberían contener al menos 5 elementos `li` en total (no cada uno). +All of your `.main-section` elements should be `section` elements -**Historia de Usuario #8:** Puedo ver un elemento `nav` con un respectivo `id="navbar"`. +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (el.tagName !== 'SECTION') assert(false) +}) +assert(els.length > 0) +``` -**Historia de Usuario #9:** El elemento de barra de navegación debe contener un elemento `header` que contenga texto describiendo el tema de la documentación técnica. +You should have at least five `.main-section` elements that are descendants of `#main-doc` -**Historia de Usuario #10:** Adicionalmente, la barra de navegación debería contener enlaces (`a`) con la clase `nav-link`. Debería haber uno para cada elemento con la clase `main-section`. +```js +const els = document.querySelectorAll('#main-doc .main-section') +assert(els.length >= 5) +``` -**Historia de Usuario #11:** El elemento `header` en la barra de navegación debe aparecer antes que cualquier elemento de enlace (`a`). +The first child of each `.main-section` should be a `header` element -**Historia de Usuario #12:** Cada elemento con la clase `nav-link` debería tener un texto que corresponda con el título `header` dentro de cada sección `section` (p.e. Si tienes una sección/título "Hola Mundo", tu barra de navegación debería tener un elemento que contenga el texto "Hola Mundo"). +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if(el.firstElementChild?.tagName !== 'HEADER') assert(false) +}) +assert(els.length > 0) +``` -**Historia de Usuario #13:** Cuando hago clic en un elemento de la barra de navegación, la página debe navegar a la sección correspondiente del elemento `main-doc` (p.e. Si hago clic en un elemento `nav-link` que contiene el texto "Hola Mundo", la página navegará al elemento `section` que tiene ese id y contiene el título `header` correspondiente. +None of your `header` elements should be empty -**Historia de Usuario #14:** En dispositivos de tamaño normal (portátiles, escritorios), el elemento con `id="navbar"` debe mostrarse en el lado izquierdo de la pantalla y siempre debe ser visible para el usuario. +```js +const els = document.querySelectorAll('header') +els.forEach(el => { + if (el.innerText?.length <= 0) assert(false) +}) +assert(els.length > 0) +``` -**Historia de Usuario #15:** Mi página de Documentación Técnica debería usar al menos una media query. +All of your `.main-section` elements should have an `id` -Puedes construir tu proyecto usando esta plantilla CodePen y haciendo clic en `Save` para crear tu propio pen. O puedes utilizar este enlace CDN para ejecutar las pruebas en cualquier entorno que desees: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (!el.id || el.id === '') assert(false) +}) +assert(els.length > 0) +``` -Una vez que hayas terminado, envía la URL de tu proyecto funcional con todas las pruebas aprobadas. +Each `.main-section` should have an `id` that matches the text of its first child, having any spaces in the child's text replaced with underscores (`_`) for the id’s -# --solutions-- +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + const text = el.firstElementChild?.innerText?.replaceAll(' ', '_') + if (el.id?.toUpperCase() !== text?.toUpperCase()) assert(false) +}) +assert(els.length > 0) +``` + +You should have at least 10 `p` elements (total) within your `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section p') +assert(els.length >= 10) +``` + +You should have at least five `code` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section code') +assert(els.length >= 5) +``` + +You should have at least five `li` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section li') +assert(els.length >= 5) +``` + +You should have a `nav` element with an `id` of `navbar` + +```js +const el = document.getElementById('navbar') +assert(!!el && el.tagName === 'NAV') +``` + +Your `#navbar` should have exactly one `header` element within it + +```js +const els = document.querySelectorAll('#navbar header') +assert(els.length === 1) +``` + +You should have at least one `a` element with a class of `nav-link` + +```js +const els = document.querySelectorAll('a[class="nav-link"]') +assert(els.length >= 1) +``` + +All of your `.nav-link` elements should be anchor (`a`) elements + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (el.tagName !== 'A') assert(false) +}) +assert(els.length > 0) +``` + +All of your `.nav-link` elements should be in the `#navbar` + +```js +const els1 = document.querySelectorAll('.nav-link') +const els2 = document.querySelectorAll('#navbar .nav-link') +assert(els2.length > 0 && els1.length === els2.length) +``` + +You should have the same number of `.nav-link` and `.main-section` elements + +```js +const els1 = document.querySelectorAll('.main-section') +const els2 = document.querySelectorAll('.nav-link') +assert(els1.length > 0 && els2.length > 0 && els1.length === els2.length) +``` + +The `header` element in the `#navbar` should come before any link (`a`) elements also in the `#navbar` + +```js +const navLinks = document.querySelectorAll('#navbar a.nav-link'); +const header = document.querySelector('#navbar header'); +navLinks.forEach((navLink) => { + if ( + ( + header.compareDocumentPosition(navLink) & + Node.DOCUMENT_POSITION_PRECEDING + ) + ) assert(false) +}); +assert(!!header) +``` + +Each `.nav-link` should have text that corresponds to the `header` text of its related `section` (e.g. if you have a "Hello world" section/header, your `#navbar` should have a `.nav-link` which has the text "Hello world") + +```js +const headerText = Array.from(document.querySelectorAll('.main-section')).map(el => + el.firstElementChild?.innerText?.trim().toUpperCase() +) +const linkText = Array.from(document.querySelectorAll('.nav-link')).map(el => + el.innerText?.trim().toUpperCase() +) +const remainder = headerText.filter(str => linkText.indexOf(str) === -1) +assert(headerText.length > 0 && headerText.length > 0 && remainder.length === 0) +``` + +Each `.nav-link` should have an `href` attribute that links to its corresponding `.main-section` (e.g. If you click on a `.nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id) + +```js +const hrefValues = Array.from(document.querySelectorAll('.nav-link')).map(el => el.getAttribute('href')) +const mainSectionIDs = Array.from(document.querySelectorAll('.main-section')).map(el => el.id) +const missingHrefValues = mainSectionIDs.filter(str => hrefValues.indexOf('#' + str) === -1) +assert(hrefValues.length > 0 && mainSectionIDs.length > 0 && missingHrefValues.length === 0) +``` + +Your `#navbar` should always be on the left edge of the window + +```js +const el = document.getElementById('navbar') +const left1 = el?.offsetLeft +const left2 = el?.offsetLeft +assert(!!el && left1 >= -15 && left1 <= 15 && left2 >= -15 && left2 <= 15) +``` + +Your Technical Documentation project should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Technical Documentation Page + + + +
+
+
Introduction
+

+ Welcome to a basic introduction of algebra. In this tutorial, we will + review some of the more common algebraic concepts. +

+
+
+
Definitions
+

+ To start with, let's define some of the more common terms used in + algebra: +

+
    +
  • + Variable: A variable is an unknown value, usually represented + by a letter. +
  • +
  • + Expression: Essentially a mathematical object. For the + purpose of this tutorial, an expression is one part of an equation. +
  • +
  • + Equation: An equation is a mathematical argument in which two + expressions result in the same value. +
  • +
+
+
+
Examples
+

+ Sometimes it is easier to understand the definitions when you have a + physical example to look at. Here is an example of the above terms.

+ x + 5 = 12

+ In this above example, we have: +

+
    +
  • Variable: The variable in the example is "x".
  • +
  • + Expression: There are two expressions in this example. They + are "x+5" and "12". +
  • +
  • + Equation: The entire example, "x+5=12", is an equation. +
  • +
+
+
+
Solving Equations
+

+ The primary use for algebra is to determine an unknown value, the + "variable", with the information provided. Continuing to use our + example from above, we can find the value of the variable "x".

+ x + 5 = 12

+ In an equation, both sides result in the same value. So you can + manipulate the two expressions however you need, as long as you + perform the same operation (or change) to each side. You do this + because the goal when solving an equation is to + get the variable into its own expression, or by itself on one side + of the = sign.
For this example, we want to remove the "+5" so the "x" is + alone. To do this, we can subtract 5, because subtraction is + the opposite operation to addition. But remember, we have to perform + the same operation to both sides of the equation. Now our equation + looks like this.

+ x + 5 - 5 = 12 - 5

+ The equation looks like a mess right now, because we haven't completed + the operations. We can simplify this equation to make it easier + to read by performing the operations "5-5" and "12-5". The result + is:

+ x = 7

+ We now have our solution to this equation! +

+
+
+
Solving Equations II
+

+ Let us look at a slightly more challenging equation.

+ 3x + 4 = 13

+ Again we can start with subtraction. In this case, we want to subtract + 4 from each side of the equation. We will also go ahead and simplify + with each step. So now we have:

+ 3x = 9

+ "3x" translates to "3*x", where the "*" symbol indicates + multiplication. We use the "*" to avoid confusion, as the "x" is now a + variable instead of a multiplication symbol. The opposite operation + for multiplication is division, so we need to + divide each expression by 3.

+ x = 3

+ And now we have our solution! +

+
+
+
Solving Equations III
+

+ Now we are getting in to more complex operations. Here is another + equation for us to look at:

+ x^2 - 8 = 8

+ Our very first step will be to add 8 to each side. This is + different from our previous examples, where we had to subtract. But + remember, our goal is to get the variable alone by performing opposite + operations.

+ x^2 = 16

+ But what does the "^2" mean? The "^" symbol is used to denote + exponents in situations where superscript is not available. When + superscript is available, you would see it as x2. + For the sake of this project, however, we will use the "^" symbol.
+ An exponent tells you how many times the base (in our case, "x") is + multiplied by itself. So, "x^2" would be the same as "x*x". Now the + opposite function of multiplication is division, but we would have to + divide both sides by "x". We do not want to do this, as that + would put an "x" on the other side of the equation. So instead, we + need to use the root operation! For an exponent of "2", we call this + the "square root" and denote it with "√". Our equation is now: +

+ x = √9

+ Performing a root operation by hand can be a tedious process, so we + recommend using a calculator when necessary. However, we are lucky in + that "9" is a + perfect square, so we do not need to calculate anything. Instead, we find our + answer to be:

+ x = 3 +

+
+
+
System of Equations
+

+ As you explore your algebra studies further, you may start to run + across equations with more than one variable. The first such equations + will likely look like:

+ y = 3x

+ An equation like this does not have one single solution. + Rather, there are a series of values for which the equation is true. + For example, if "x=3" and "y=9", the equation is true. These equations + are usually used to plot a graph.
+ Getting more complicated, though, you may be given a pair of + equations. This is called a "system of equations", and CAN be solved. + Let's look at how we do this! Consider the following system of + equations:

+ y = 3x | y - 6 = x + A system of equations IS solvable, but it is a multi-step process. To + get started, we need to chose a variable we are solving for. Let's + solve for "x" first. From the second equation, we know that "x" equals + "y - 6", but we cannot simplify that further because we do not have a + value for "y". Except, thanks to the system of equations, we DO have a + value for "y". We know that "y" equals "3x". So, looking at our second + equation, we can replace "y" with "3x" because they have the same + value. We then get:

+ 3x - 6 = x

+ Now we can solve for "x"! We start by adding 6 to each side.

+ 3x = x + 6

+ We still need to get "x" by itself, so we subtract "x" from both sides + and get:

+ 2x = 6

+ If this confuses you, remember that "3x" is the same as "x+x+x". + Subtract an "x" from that and you get "x+x", or "2x". Now we divide + both sides by 2 and have our value for x!

+ x = 3

+ However, our work is not done yet. We still need to find the value for + "y". Let's go back to our first equation:

+ y = 3x

+ We have a value for "x" now, so let's see what happens if we put that + value in.

+ y = 3*3

+ We perform the multiplication and discover that "y=9"! Our solution to + this system of equations then is:

+ x = 3 and y = 9

+

+
+
+
Try it Yourself!
+

Coming Soon!

+

Keep an eye out for new additions!

+
+
+
More Information
+

Check out the following links for more information!

+ +
+
+ + + +``` + +```css +* { + background-color: #3a3240; +} +a { + color: #92869c; +} +a:hover { + background-color: #92869c; + color: #3a3240; +} +#navbar { + border-style: solid; + border-width: 5px; + border-color: #92869c; + height: 100%; + top: -5px; + left: -5px; + padding: 5px; + text-align: center; + color: #92869c +} +@media (min-width: 480px) { + #navbar { + position: fixed; + } +} +main { + margin-left: 220px; + color: #92869c +} +header { + font-size: 20pt; +} +code { + background-color: #92869c; + border-style: dashed; + border-width: 2px; + border-color: #92869c; + padding: 5px; + color: black; +} +footer { + text-align: center; +} ``` diff --git a/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md b/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md index 9daf6452828..231292b4373 100644 --- a/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md +++ b/curriculum/challenges/espanol/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md @@ -1,43 +1,327 @@ --- id: bd7158d8c442eddfaeb5bd18 -title: Construye una página tributo -challengeType: 3 +title: Build a Tribute Page +challengeType: 14 forumTopicId: 301147 dashedName: build-a-tribute-page --- # --description-- -**Objetivo:** Construye una aplicación en [CodePen.io](https://codepen.io) que funcionalmente sea similar a esta: . +**Objective:** Build an app that is functionally similar to https://tribute-page.freecodecamp.rocks -Completa las siguientes [historias de usuario](https://es.wikipedia.org/wiki/Historias_de_usuario) y consigue aprobar todos los tests. Dale tu propio estilo personal. +**User Stories:** -Puedes usar HTML, JavaScript y CSS para completar este proyecto. Se recomienda usar CSS puro porque eso es lo que las lecciones han cubierto hasta ahora y debes practicar un poco con él. Puedes usar Bootstrap o SASS si lo deseas. Tecnologías adicionales (por ejemplo, jQuery, React, Angular o Vue) no se recomiendan para este proyecto, y usarlas es bajo tu propio riesgo. Otros proyectos te darán la oportunidad de trabajar con diferentes stacks de tecnologías como React. Aceptaremos e intentaremos solucionar todos los informes de incidencias que utilicen el stack de tecnología sugerido para este proyecto. ¡Feliz día programando! +1. Your tribute page should have an element with a corresponding `id="main"`, which contains all other elements +1. You should see an element with an `id` of `title`, which contains a string (i.e. text), that describes the subject of the tribute page (e.g. "Dr. Norman Borlaug") +1. You should see either a `figure` or a `div` element with an `id` of `img-div` +1. Within the `img-div` element, you should see an `img` element with a corresponding `id="image"` +1. Within the `img-div` element, you should see an element with a corresponding `id="img-caption"` that contains textual content describing the image shown in `img-div` +1. You should see an element with a corresponding `id="tribute-info"`, which contains textual content describing the subject of the tribute page +1. You should see an a element with a corresponding `id="tribute-link"`, which links to an outside site, that contains additional information about the subject of the tribute page. HINT: You must give your element an attribute of `target` and set it to `_blank` in order for your link to open in a new tab +1. Your `#image` should use `max-width` and `height` properties to resize responsively, relative to the width of its parent element, without exceeding its original size +1. Your `img` element should be centered within its parent element -**Historia de Usuario #1:** Mi página tributo debería tener un elemento con un respectivo `id="main"`, el cual contiene todos los demás elementos. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**Historia de Usuario #2:** Debería ver un elemento con un respectivo `id="title"`, que contiene una cadena que describe el tema de la página tributo (p. ej. "Dr. Norman Borlaug"). +# --hints-- -**Historia de Usuario #3:** Debe ver un elemento `figure` o `div` con su respectivo `id="img-div"`. +You should have a `main` element with an `id` of `main` -**Historia de Usuario #4:** Dentro del elemento `img-div`, debería ver un elemento `img` con un respectivo `id="image"`. +```js +const el = document.getElementById('main') +assert(!!el && el.tagName === 'MAIN') +``` -**Historia de Usuario #5:** Dentro del elemento `img-div`, debería ver un elemento con un respectivo `id="img-caption"` que contiene contenido textual describiendo la imagen mostrada en `img-div`. +Your `#img-div`, `#image`, `#img-caption`, `#tribute-info`, and `#tribute-link` should all be descendants of `#main` -**Historia de Usuario #6:** Debería ver un elemento con un respectivo `id="tribute-info"`, que contiene contenido textual describiendo el tema de la página tributo. +```js +const el1 = document.querySelector('#main #img-div') +const el2 = document.querySelector('#main #image') +const el3 = document.querySelector('#main #img-caption') +const el4 = document.querySelector('#main #tribute-info') +const el5 = document.querySelector('#main #tribute-link') +assert(!!el1 & !!el2 && !!el3 && !!el4 && !!el5) +``` -**Historia de Usuario #7:** Debería ver un elemento `a` con un respectivo `id="tribute-link"`, que enlaza a un sitio externo conteniendo información adicional sobre el tema de la página tributo. SUGERENCIA: Debes dar a tu elemento un atributo `target` y establecerlo como `_blank` para que tu enlace se abra en una nueva pestaña (p. ej. `target="_blank"`). +You should have an element with an `id` of `title` -**Historia de Usuario #8:** El elemento `img` debería cambiar de tamaño de forma responsiva, en relación al ancho de su elemento padre, sin exceder su tamaño original. +```js +const el = document.getElementById('title') +assert(!!el) +``` -**Historia de Usuario #9:** El elemento `img` debería estar centrado dentro de su elemento padre. +Your `#title` should not be empty -Puedes construir tu proyecto usando esta plantilla CodePen y haciendo clic en `Save` para crear tu propio pen. O puedes utilizar este enlace CDN para ejecutar los tests en cualquier entorno que desees: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`. +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) -Una vez que hayas terminado, envía la URL de tu proyecto funcional con todos los tests aprobados. +``` -# --solutions-- +You should have a `figure` or `div` element with an `id` of `img-div` + +```js +const el = document.getElementById('img-div') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGURE')) +``` + +You should have an `img` element with an `id` of `image` + +```js +const el = document.getElementById('image') +assert(!!el && el.tagName === 'IMG') +``` + +Your `#image` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #image') +assert(!!el) +``` + +You should have a `figcaption` or `div` element with an `id` of `img-caption` + +```js +const el = document.getElementById('img-caption') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGCAPTION')) +``` + +Your `#img-caption` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #img-caption') +assert(!!el) +``` + +Your `#img-caption` should not be empty + +```js +const el = document.getElementById('img-caption') +assert(!!el && el.innerText.length > 0) +``` + +You should have an element with an `id` of `tribute-info` + +```js +const el = document.getElementById('tribute-info') +assert(!!el) +``` + +Your `#tribute-info` should not be empty + +```js +const el = document.getElementById('tribute-info') +assert(!!el && el.innerText.length > 0) +``` + +You should have an `a` element with an `id` of `tribute-link` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.tagName === 'A') +``` + +Your `#tribute-link` should have an `href` attribute and value + +```js +const el = document.getElementById('tribute-link') +assert(!!el && !!el.href && el.href.length > 0) +``` + +Your `#tribute-link` should have a `target` attribute set to `_blank` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.target === '_blank') +``` + +You should use an `#image` selector in your CSS to style the `#image` and pass the next three tests + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image') +assert(!!style) +``` + +Your `#image` should have a `display` of `block` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +assert(style === 'block') +``` + +Your `#image` should have a `max-width` of `100%` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +assert(style === '100%') +``` + +Your `#image` should have a `height` of `auto` + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'); +const maxWidthValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +const displayValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +const oldDisplayValue = img?.style.getPropertyValue('display'); +const oldDisplayPriority = img?.style.getPropertyPriority('display'); +img?.style.setProperty('display', 'none', 'important'); +const heightValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('height') +img?.style.setProperty('display', oldDisplayValue, oldDisplayPriority); +assert(heightValue === 'auto') +``` + +Your `#image` should be centered within its parent + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'), + imgParent = img?.parentElement, + imgLeft = img?.getBoundingClientRect().left, + imgRight = img?.getBoundingClientRect().right, + parentLeft = imgParent?.getBoundingClientRect().left, + parentRight = imgParent?.getBoundingClientRect().right, + leftMargin = imgLeft - parentLeft, + rightMargin = parentRight - imgRight; +assert(leftMargin - rightMargin < 6 && rightMargin - leftMargin < 6) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + + + Tribute Page + + +

Tribute Page

+

The below card was designed as a tribute page for freeCodeCamp.

+
+
+ An image of Togepi +
Togepi, happy as always.
+
+

Togepi

+
+
+

+ Togepi was first discovered in the Johto region, when Ash Ketchum + discovered a mysterious egg. However, when the egg hatched, Togepi saw + Ash's friend Misty first and imprinted on her. Like many other + creatures, this imprinting process created a bond and Togepi views + Misty as his mother. +

+

+ Togepi is a very childlike Pokemon, and is very emotionally + expressive. He demonstrates extreme levels of joy and sadness. +

+
+

Battle Information

+
    +
  • Type: Fairy
  • +
  • Evolutions: Togepi -> Togetic -> Togekiss
  • +
  • Moves: Growl, Pound, Sweet Kiss, Charm
  • +
  • Weaknesses: Poison, Steel
  • +
  • Resistances: Dragon
  • +
+

+ Check out this + Bulbapedia article on Togepi + for more information on this great Pokemon. +

+
+
+ + + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + background-color: #92869c; + font-family: Lobster; + max-width: 500px; + margin: 20px auto; + color: black; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); +} +h2 { + text-align: center; + font-size: 20pt; + font-family: Pacifico; +} +body { + text-align: center; + font-size: 12pt; +} +footer { + text-align: center; + font-size: 10pt; +} +.border { + border-color: black; + border-width: 5px; + border-style: solid; +} +#image { + height: auto; + display: block; + margin: auto; + max-width: 100%; + border-radius: 50%; +} +#img-caption { + font-size: 10pt; +} +a:not(#tribute-link) { + color: white; +} +hr { + border-color: black; +} ``` diff --git a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md index ef918d81369..0226992eec9 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md +++ b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md @@ -1,47 +1,277 @@ --- id: bd7158d8c242eddfaeb5bd13 -title: Creare una pagina Web per il Portfolio Personale -challengeType: 3 +title: Build a Personal Portfolio Webpage +challengeType: 14 forumTopicId: 301143 dashedName: build-a-personal-portfolio-webpage --- # --description-- -**Obiettivo:** Costruire un'app [CodePen.io](https://codepen.io) funzionalmente simile a questa: . +**Objective:** Build an app that is functionally similar to https://personal-portfolio.freecodecamp.rocks -Compila le [user stories](https://en.wikipedia.org/wiki/User_story) qui sotto e fai passare tutti i test. Dalle il tuo stile personale. +**User Stories:** -Puoi utilizzare HTML, JavaScript, e CSS per completare questo progetto. CSS è raccomandato perché è l'argomento delle lezioni viste finora e dovresti fare pratica con il CSS di base. Se lo desideri puoi anche utilizzare Bootstrap o SASS. Ulteriori tecnologie (solo per esempio jQuery, React, Angular, o Vue) non sono raccomandate per questo progetto, e usarle è a tuo rischio. Altri progetti ti daranno la possibilità di lavorare con diversi stack tecnologici come React. Accetteremo e cercheremo di risolvere tutte le segnalazioni di problemi che utilizzano lo stack tecnologico suggerito per questo progetto. Happy coding! +1. Your portfolio should have a welcome section with an `id` of `welcome-section` +1. The welcome section should have an `h1` element that contains text +1. Your portfolio should have a projects section with an `id` of `projects` +1. The projects section should contain at least one element with a `class` of `project-tile` to hold a project +1. The projects section should contain at least one link to a project +1. Your portfolio should have a navbar with an id of `navbar` +1. The navbar should contain at least one link that you can click on to navigate to different sections of the page +1. Your portfolio should have a link with an id of `profile-link`, which opens your GitHub or freeCodeCamp profile in a new tab +1. Your portfolio should have at least one media query +1. The height of the welcome section should be equal to the height of the viewport +1. The navbar should always be at the top of the viewport -**User Story #1:** Il mio portfolio dovrebbe avere una sezione di benvenuto con un id di `welcome-section`. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**User Story #2:** La sezione di benvenuto dovrebbe avere un elemento `h1` che contiene testo. +# --hints-- -**User Story #3:** Il mio portfolio dovrebbe avere una sezione progetti con un id di `projects`. +Your portfolio should have a "Welcome" section with an `id` of `welcome-section`. -**User Story #4:** La sezione progetti dovrebbe contenere almeno un elemento con una classe `project-tile` che contenga un progetto. +```js +const el = document.getElementById('welcome-section') +assert(!!el); +``` -**User Story #5:** La sezione progetti dovrebbe contenere almeno un link a un progetto. +Your `#welcom-section` element should contain an `h1` element. -**User Story #6:** Il mio portfolio dovrebbe avere una navbar con un id di `navbar`. +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1').length, + 0, + 'Welcome section should contain an h1 element ' +); +``` -**User Story #7:** La barra di navigazione dovrebbe contenere almeno un link su cui posso cliccare per navigare in diverse sezioni della pagina. +You should not have any empty `h1` elements within `#welcome-section` element. -**User Story #8:** Il mio portfolio dovrebbe avere un link con un id di `profile-link`, che apre il mio profilo GitHub o FCC in una nuova scheda. +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1')?.[0]?.innerText?.length, + 0, + 'h1 element in welcome section should contain your name or camper ' + + 'name ' +); +``` -**User Story #9:** Il mio portfolio dovrebbe avere almeno una media query. +You should have a "Projects" section with an `id` of `projects`. -**User Story #10:** L'altezza della sezione di benvenuto dovrebbe essere uguale all'altezza della viewport. +```js +const el = document.getElementById('projects') +assert(!!el); +``` -**User Story #11:** La barra di navigazione dovrebbe sempre essere in cima alla viewport. +Your portfolio should contain at least one elment with a class of `project-tile`. -Puoi costruire il tuo progetto usando questo modello CodePen e facendo clic su `Save` per creare il tuo pen. Oppure puoi usare questo link CDN per eseguire i test in qualsiasi ambiente tu voglia: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +assert.isAbove( + document.querySelectorAll('#projects .project-tile').length, + 0 +); +``` -Una volta fatto, invia l'URL del tuo progetto di lavoro con tutti i suoi test superati. +Your `#projects` element should contain at least one `a` element. -# --solutions-- +```js +assert.isAbove(document.querySelectorAll('#projects a').length, 0); +``` + +Your portfolio should have a navbar with an `id` of `navbar`. + +```js +const el = document.getElementById('navbar'); +assert(!!el); +``` + +Your `#navbar` element should contain at least one `a` element whose `href` attribute starts with `#`. + +```js +const links = [...document.querySelectorAll('#navbar a')].filter( + (nav) => (nav?.getAttribute('href') || '').substr(0, 1) === '#' +); + +assert.isAbove( + links.length, + 0, + 'Navbar should contain an anchor link ' +); +``` + +Your portfolio should have an `a` element with an `id` of `profile-link`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.tagName === 'A') +``` + +Your `#profile-link` element should have a `target` attribute of `_blank`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.target === '_blank') +``` + +Your portfolio should use at least one media query. + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your `#navbar` element should always be at the top of the viewport. + +```js +(async () => { + const timeout = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)); + + const navbar = document.getElementById('navbar'); + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + "Navbar's parent should be body and it should be at the top of " + + 'the viewport ' + ); + + window.scroll(0, 500); + + await timeout(1); + + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + 'Navbar should be at the top of the viewport even after ' + + 'scrolling ' + ); + window.scroll(0, 0); +})(); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Personal Portfolio + + + + + +
+
+
+

It's me!

+ +

Naomi Carrigan

+

Welcome to my portfolio page!

+

+
+

Projects

+

Here's what I've worked on!

+

+ + + + +


+
+

Contact me!

+

Use the links below to get in touch.

+

FreeCodeCamp.org | GitHub | Facebook | LinkedIn +

+ + + +``` + +```css +nav{ + position: fixed; + width: 100%; + text-align: right; + font-size: 24pt; + top: 0%; + right: 5px; + background-color: #000000; + color: #ffffff; +} +@media (max-width: 500px){ + nav{ + display: none; + } +} +a{ + color: #ffffff; +} +main{ + text-align: center; + background-color: black; + font-family:Pacifico +} +h1{ + font-size: 48pt; +} +h2{ + font-size: 24pt; +} +p{ + font-size: 12pt; +} +#welcome-section{ + background-color:#251a4a; + color: #FFFFFF; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#projects{ + background-color: #060a9c; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#contact{ + background-color: #03300b; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} ``` diff --git a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md index 9f4a27499c9..cdd62359751 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md +++ b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md @@ -1,55 +1,424 @@ --- id: 587d78af367417b2b2512b04 -title: Costruire la Landing Page per un prodotto -challengeType: 3 +title: Build a Product Landing Page +challengeType: 14 forumTopicId: 301144 dashedName: build-a-product-landing-page --- # --description-- -**Obiettivo:** Costruire un'app [CodePen.io](https://codepen.io) funzionalmente simile a questa: . +**Objective:** Build an app that is functionally similar to https://product-landing-page.freecodecamp.rocks -Compila le [user stories](https://en.wikipedia.org/wiki/User_story) qui sotto e fai passare tutti i test. Dalle il tuo stile personale. +**User Stories:** -Puoi utilizzare HTML, JavaScript, e CSS per completare questo progetto. Il CSS è raccomandato perché è stato l'argomento delle lezioni viste finora e dovresti fare pratica con il CSS di base. Se lo desideri puoi anche utilizzare Bootstrap o SASS. Ulteriori tecnologie (solo per fare un esempio jQuery, React, Angular, o Vue) non sono raccomandate per questo progetto, e usarle è a tuo rischio. Altri progetti ti daranno la possibilità di lavorare con differenti stack tecnologici come React. Accetteremo e cercheremo di risolvere tutte le segnalazioni di problemi che utilizzano lo stack tecnologico suggerito per questo progetto. Happy coding! +1. Your product landing page should have a `header` element with a corresponding `id="header"` +1. You can see an image within the `header` element with a corresponding `id="header-img"` (A logo would make a good image here) +1. Within the `#header` element, you can see a `nav` element with a corresponding `id="nav-bar"` +1. You can see at least three clickable elements inside the `nav` element, each with the class `nav-link` +1. When you click a `.nav-link` button in the `nav` element, you are taken to the corresponding section of the landing page +1. You can watch an embedded product video with `id="video"` +1. Your landing page has a `form` element with a corresponding `id="form"` +1. Within the form, there is an `input` field with `id="email"` where you can enter an email address +1. The `#email` input field should have placeholder text to let users know what the field is for +1. The `#email` input field uses HTML5 validation to confirm that the entered text is an email address +1. Within the form, there is a submit `input` with a corresponding `id="submit"` +1. When you click the `#submit` element, the email is submitted to a static page (use this mock URL: `https://www.freecodecamp.com/email-submit`) +1. The navbar should always be at the top of the viewport +1. Your product landing page should have at least one media query +1. Your product landing page should utilize CSS flexbox at least once -**User Story#1:** La pagina di destinazione del prodotto dovrebbe avere un elemento `header` con un corrispondente `id="header"`. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**User Story #2:** Posso vedere un'immagine all'interno dell'elemento `header` con un corrispondente `id="header-img"`. Un logo aziendale qui starebbe bene. +# --hints-- -**User Story #3:** All'interno dell'elemento `#header` posso vedere un elemento `nav` con un corrispondente `id="nav-bar"`. +You should have a `header` element with an `id` of `header` -**User Story #4:** Posso vedere almeno tre elementi cliccabili all'interno dell'elemento `nav`, ognuno con la classe `nav-link`. +```js +const el = document.getElementById('header') +assert(!!el && el.tagName === 'HEADER') +``` -**User Story #5:** Quando clicco su un pulsante `.nav-link` nell'elemento `nav`, sono portato nella sezione corrispondente della pagina di destinazione. +You should have an `img` element with an `id` of `header-img` -**User Story #6:** Posso guardare un video incorportato del prodotto con `id="video"`. +```js +const el = document.getElementById('header-img') +assert(!!el && el.tagName === 'IMG') +``` -**User Story #7:** La mia pagina iniziale ha un elemento `form` con un corrispondente `id="form"`. +Your `#header-img` should be a descendant of the `#header` -**User Story #8:** All'interno del modulo c'è un campo `input` con `id="email"` dove posso inserire un indirizzo email. +```js +const els = document.querySelectorAll('#header #header-img') +assert(els.length > 0) +``` -**User Story #9:** Il campo di input `#email` dovrebbe avere un testo segnaposto per far sapere all'utente a cosa serve il campo. +Your `#header-img` should have a `src` attribute -**User Story #10:** Il campo di input `#email` utilizza la validazione HTML5 per confermare che il testo inserito è un indirizzo email. +```js +const el = document.getElementById('header-img') +assert(!!el && !!el.src) +``` -**User Story #11:** All'interno del modulo, c'è un `input` di tipo submit con un `id="submit"`. +Your `#header-img`’s `src` value should be a valid URL (starts with `http`) -**User Story #12:** Quando clicco l'elemento `#submit`, l'email viene inviata a una pagina statica (usa questo URL fittizio: ). +```js +const el = document.getElementById('header-img') +assert(!!el && /^http/.test(el.src)) +``` -**User Story #13:** La barra di navigazione dovrebbe sempre essere in cima alla viewport. +You should have a `nav` element with an `id` of `nav-bar` -**User Story #14:** La landing page del prodotto dovrebbe avere almeno una media query. +```js +const el = document.getElementById('nav-bar') +assert(!!el && el.tagName === 'NAV') +``` -**User Story #15:** La landing page del prodotto dovrebbe utilizzare la flexbox CSS almeno una volta. +Your `#nav-bar` should be a descendant of the `#header` -Puoi costruire il tuo progetto usando questo modello CodePen e cliccando `Save` per creare il tuo pen. Oppure puoi usare questo link CDN per eseguire i test in qualsiasi ambiente tu voglia: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +const els = document.querySelectorAll('#header #nav-bar') +assert(els.length > 0) +``` -Una volta fatto, invia l'URL del tuo progetto di lavoro con tutti i suoi test passati. +You should have at least 3 `.nav-link` elements within the `#nav-bar` -# --solutions-- +```js +const els = document.querySelectorAll('#nav-bar .nav-link') +assert(els.length >= 3) +``` + +Each `.nav-link` element should have an `href` attribute + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (!el.href) assert(false) +}) +assert(els.length > 0) +``` + +Each `.nav-link` element should link to a corresponding element on the landing page (has an `href` with a value of another element's id. e.g. `#footer`) + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + const linkDestination = el.getAttribute('href').slice(1) + if (!document.getElementById(linkDestination)) assert(false) +}) +assert(els.length > 0) +``` + +You should have a `video` or `iframe` element with an `id` of `video` + +```js +const el = document.getElementById('video') +assert(!!el && (el.tagName === 'VIDEO' || el.tagName === 'IFRAME')) +``` + +Your `#video` should have a `src` attribute + +```js +const el = document.getElementById('video') +assert(!!el && !!el.src) +``` + +You should have a `form` element with an `id` of `form` + +```js +const el = document.getElementById('form') +assert(!!el && el.tagName === 'FORM') +``` + +You should have an `input` element with an `id of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #email') +assert(els.length > 0) +``` + +Your `#email` should have the `placeholder` attribute with placeholder text + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should use HTML5 validation by setting its `type` to `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +You should have an `input` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#submit` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #submit') +assert(els.length > 0) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#form` should have an `action` attribute of `https://www.freecodecamp.com/email-submit` + +```js +const el = document.getElementById('form') +assert(!!el && el.action === 'https://www.freecodecamp.com/email-submit') +``` + +Your `#email` should have a `name` attribute of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.name === 'email') +``` + +Your `#nav-bar` should always be at the top of the viewport + +```js +const el = document.getElementById('nav-bar') +const top1 = el?.offsetTop +const top2 = el?.offsetTop +assert(!!el && top1 >= -15 && top1 <= 15 && top2 >= -15 && top2 <= 15) +``` + +Your Product Landing Page should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your Product Landing Page should use CSS Flexbox at least once + +```js +const stylesheet = new __helpers.CSSHelp(document).getStyleSheet() +const cssRules = new __helpers.CSSHelp(document).styleSheetToCssRulesArray(stylesheet) +const usesFlex = cssRules.find(rule => { + return rule.style?.display === 'flex' || rule.style?.display === 'inline-flex' +}) +assert(usesFlex) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Product Landing Page + + + +
+

+ Pokemon Daycare Service +

+
+

What we offer

+
+
+ +
+
Guaranteed friendly and loving staff!
+
+
+
+ +
+
+ Comfortable environment for Pokemon to explore and play! +
+
+
+
+ +
+
+ Multiple membership plans to fit your lifestyle! +
+
+
+
+

Check us out!

+ A sneak peek into our facility: +
+ +
+
+

Membership Plans

+
+
+ Basic Membership
+
    +
  • One Pokemon
  • +
  • Food and berries provided
  • +
+ $9.99/month +
+
+ Silver Membership
+
    +
  • Up to Three Pokemon
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
+ $19.99/month +
+
+ Gold Membership
+
    +
  • Up to six Pokemon!
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
  • Personal training for each Pokemon
  • +
  • Breeding and egg hatching
  • +
+ $29.99/month +
+
+
+
+

Sign up for our newsletter!

+ + +
+ +
+ + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + max-width: 750px; + margin: 50px auto; +} +input { + background-color: #92869c; +} +a:not(.nav-link) { + color: white; +} +#header-img { + max-height: 25px; +} +#nav-bar { + position: fixed; + width: 100%; + text-align: center; + top: 0%; + background-color: #92869c; +} +h1 { + text-align: center; +} +body { + text-align: center; +} +footer { + text-align: center; +} +#bullet { + max-height: 25px; +} +.flex-here { + display: flex; + justify-content: center; +} +.flex-left { + height: 25px; +} +.flex-mem { + display: flex; + justify-content: center; +} +.flex-mem-box { + background-color: #92869c; + border-color: black; + border-width: 5px; + border-style: solid; + margin: 10px; + padding: 10px; + color: black; +} +@media (max-width: 350px) { + #video { + width: 300; + height: 200; + } +} ``` diff --git a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md index 88654e81514..937c4482c93 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md +++ b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md @@ -1,57 +1,516 @@ --- id: 587d78af367417b2b2512b03 -title: Creare un modulo di sondaggio -challengeType: 3 +title: Build a Survey Form +challengeType: 14 forumTopicId: 301145 dashedName: build-a-survey-form --- # --description-- -**Obiettivo:** Costruisci un'app [CodePen.io](https://codepen.io) funzionalmente simile a questa: . +**Objective:** Build an app that is functionally similar to https://survey-form.freecodecamp.rocks -Compila le [user stories](https://en.wikipedia.org/wiki/User_story) qui sotto e fai passare tutti i test. Dalle il tuo stile personale. +**User Stories:** -Puoi utilizzare HTML, JavaScript, e CSS per completare questo progetto. CSS è raccomandato perché è l'argomento delle lezioni viste finora e dovresti fare pratica con il CSS di base. Se lo desideri puoi anche utilizzare Bootstrap o SASS. Ulteriori tecnologie (solo per esempio jQuery, React, Angular, o Vue) non sono raccomandate per questo progetto, e usarle è a tuo rischio. Altri progetti ti daranno la possibilità di lavorare con diversi stack tecnologici come React. Accetteremo e cercheremo di risolvere tutte le segnalazioni di problemi che utilizzano lo stack tecnologico suggerito per questo progetto. Happy coding! +1. You should have a page title in an `h1` element with an `id` of `title` +1. You should have a short explanation in a `p` element with an `id` of `description` +1. You should have a `form` element with an `id` of `survey-form` +1. Inside the form element, you are **required** to enter your name in an `input` field that has an `id` of `name` and a `type` of `text` +1. Inside the form element, you are **required** to enter your email in an `input` field that has an `id` of `email` +1. If you enter an email that is not formatted correctly, you will see an HTML5 validation error +1. Inside the form, you can enter a number in an `input` field that has an `id` of `number` +1. If you enter non-numbers in the number input, you will see an HTML5 validation error +1. If you enter numbers outside the range of the number input, which are defined by the `min` and `max` attributes, you will see an HTML5 validation error +1. For the name, email, and number input fields, you can see corresponding `label` elements in the form, that describe the purpose of each field with the following ids: `id="name-label"`, `id="email-label"`, and `id="number-label"` +1. For the name, email, and number input fields, you can see placeholder text that gives a description or instructions for each field +1. Inside the form element, you should have a `select` dropdown element with an `id` of `dropdown` and at least two options to choose from +1. Inside the form element, you can select an option from a group of at least two radio buttons that are grouped using the `name` attribute +1. Inside the form element, you can select several fields from a series of checkboxes, each of which must have a `value` attribute +1. Inside the form element, you are presented with a `textarea` for additional comments +1. Inside the form element, you are presented with a button with `id` of `submit` to submit all the inputs -**User Story #1:** Posso vedere un titolo con `id="title"` in un testo di dimensioni H1. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**User Story #2:** Posso vedere una breve spiegazione con `id="description"` in un testo di dimensione P. +# --hints-- -**User Story #3:** Posso vedere un `form` con `id="survey-form"`. +You should have an `h1` element with an `id` of `title` -**User Story #4:** All'interno del modulo, mi viene chiesto di inserire il mio nome in un campo con `id="name"`. +```js +const el = document.getElementById('title') +assert(!!el && el.tagName === 'H1') +``` -**User Story #5:** All'interno del modulo, mi viene chiesto di inserire un'email in un campo con `id="email"`. +Your `#title` should not be empty -**User Story #6:** Se inserisco un'email non formattata correttamente, vedrò un errore di validazione HTML5. +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) +``` -**User Story #7:** All'interno del modulo, posso inserire un numero in un campo con `id="number"`. +You should have a `p` element with an `id` of `description` -**User story #8:** Se inserisco caratteri non numerici nell'input di tipo number, vedrò un errore di validazione HTML5. +```js +const el = document.getElementById('description') +assert(!!el && el.tagName === 'P') +``` -**User story #9:** Se inserisco numeri al di fuori dell'intervallo dell'input numerico, che sono definiti dagli attributi `min` e `max`, vedrò un errore di validazione HTML5. +Your `#description` should not be empty -**User story #10:** Per il nome, l'e-mail, e i campi di input numerici all'interno del modulo posso vedere le etichette corrispondenti che descrivono lo scopo di ogni campo con i seguenti id: `id="name-label"`, `id="email-label"`e `id="number-label"`. +```js +const el = document.getElementById('description') +assert(!!el && el.innerText.length > 0) +``` -**User story#11:** Per i campi di input di nome, email e numero, posso vedere il testo segnaposto che mi dà una descrizione o delle istruzioni per ogni campo. +You should have a `form` element with an `id` of `survey-form` -**User story #12:** All'interno del modulo, posso selezionare un'opzione da un menu a discesa che ha un corrispondente `id="dropdown"`. +```js +const el = document.getElementById('survey-form') +assert(!!el && el.tagName === 'FORM') +``` -**User story #13:** All'interno del modulo, posso selezionare un campo da uno o più gruppi di pulsanti di opzione. Ogni gruppo dovrebbe essere raggruppato usando l'attributo `name`. +You should have an `input` element with an `id` of `name` -**User story #14:** All'interno del modulo, posso selezionare diversi campi da una serie di caselle di spunta, ciascuno dei quali deve avere un attributo `value`. +```js +const el = document.getElementById('name') +assert(!!el && el.tagName === 'INPUT') +``` -**User story #15:** All'interno del modulo, mi viene presentata alla fine una `textarea`, per inserire ulteriori commenti. +Your `#name` should have a `type` of `text` -**User story #16:** All'interno del modulo, mi viene presentato un pulsante con `id="submit"` per inviare tutti i miei input. +```js +const el = document.getElementById('name') +assert(!!el && el.type === 'text') +``` -Puoi costruire il tuo progetto usando questo modello CodePen e facendo clic su `Save` per creare il tuo pen. Oppure puoi usare questo link CDN per eseguire i test in qualsiasi ambiente tu voglia: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +Your `#name` should require input -Una volta fatto, invia l'URL del tuo progetto di lavoro con tutti i suoi test passati. +```js +const el = document.getElementById('name') +assert(!!el && el.required) +``` -# --solutions-- +Your `#name` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name') +assert(!!el) +``` + +You should have an `input` element with an `id` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should have a `type` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +Your `#email` should require input + +```js +const el = document.getElementById('email') +assert(!!el && el.required) +``` + +Your `#email` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email') +assert(!!el) +``` + +You should have an `input` element with an `id` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#number` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number') +assert(!!el) +``` + +Your `#number` should have a `type` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.type === 'number') +``` + +Your `#number` should have a `min` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.min && isFinite(el.min)) +``` + +Your `#number` should have a `max` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.max && isFinite(el.max)) +``` + +You should have a `label` element with an `id` of `name-label` + +```js +const el = document.getElementById('name-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `email-label` + +```js +const el = document.getElementById('email-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `number-label` + +```js +const el = document.getElementById('number-label') +assert(!!el && el.tagName === 'LABEL') +``` + +Your `#name-label` should not be empty + +```js +const el = document.getElementById('name-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#email-label` should not be empty + +```js +const el = document.getElementById('email-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#number-label` should not be empty + +```js +const el = document.getElementById('number-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#name-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name-label') +assert(!!el) +``` + +Your `#email-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email-label') +assert(!!el) +``` + +Your `#number-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number-label') +assert(!!el) +``` + +Your `#name` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('name') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#number` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('number') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +You should have a `select` field with an `id` of `dropdown` + +```js +const el = document.getElementById('dropdown') +assert(!!el && el.tagName === 'SELECT') +``` + +Your `#dropdown` should have at least two selectable (not disabled) `option` elements + +```js +const els = document.querySelectorAll('#dropdown option:not([disabled])') +assert(els.length >= 2) +``` + +Your `#dropdown` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #dropdown') +assert(!!el) +``` + +You should have at least two `input` elements with a `type` of `radio` (radio buttons) + +```js +const els = document.querySelectorAll('input[type="radio"]') +assert(els.length >= 2) +``` + +You should have at least two radio buttons that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="radio"]') +assert(els.length >= 2) +``` + +All your radio buttons should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][value=""], input[type="radio"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +All your radio buttons should have a `name` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][name=""], input[type="radio"]:not([name])') +assert(els1.length > 0 && els2.length === 0) +``` + +Every radio button group should have at least 2 radio buttons + +```js +const radioButtons = document.querySelectorAll('input[type="radio"]'); +const groups = {} + +if (radioButtons) { + radioButtons.forEach(el => { + if (!groups[el.name]) groups[el.name] = [] + groups[el.name].push(el) + }) +} + +const groupKeys = Object.keys(groups) + +groupKeys.forEach(key => { + if (groups[key].length < 2) assert(false) +}) + +assert(groupKeys.length > 0) +``` + +You should have at least two `input` elements with a `type` of `checkbox` (checkboxes) that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="checkbox"]'); +assert(els.length >= 2) +``` + +All your checkboxes inside `#survey-form` should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('#survey-form input[type="checkbox"]') +const els2 = document.querySelectorAll('#survey-form input[type="checkbox"][value=""], #survey-form input[type="checkbox"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +You should have at least one `textarea` element that is a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form textarea') +assert(!!el) +``` + +You should have an `input` or `button` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && (el.tagName === 'INPUT' || el.tagName === 'BUTTON')) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#submit` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #submit') +assert(!!el) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Survey Form + + +

Survey Form

+

The card below was built as a sample survey form for freeCodeCamp.

+
+

Join the Togepi Fan Club!

+

+ Enter your information here to receive updates about club activities, + our monthly newsletter, and other email communications. +

+
+ + + + +

Who is your favourite Pokemon?

+ + + +

Which communications do you want to receive?

+ + + +

Any other information you would like to share?

+ +

+ Please note: This form is a proof of concept. Submitting the form + will not actually transmit your data. +

+ +
+
+ + + +``` + +```css +main { + text-align: center; + background-color: #92869c; + background-blend-mode: lighten; + max-width: 500px; + margin: 20px auto; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); + color: black; +} +body { + text-align: center; + background: #3a3240; + color: white; +} +input, textarea, select, button { + background: #3a3240; + color: white; +} +a { + color: white; +} ``` diff --git a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md index 34ac0d78a1a..6c433375ba7 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md +++ b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md @@ -1,55 +1,525 @@ --- id: 587d78b0367417b2b2512b05 -title: Creare una pagina di documentazione tecnica -challengeType: 3 +title: Build a Technical Documentation Page +challengeType: 14 forumTopicId: 301146 dashedName: build-a-technical-documentation-page --- # --description-- -**Obiettivo:** Costuire un'app [CodePen.io](https://codepen.io) funzionalmente simile a questa: . +**Objective:** Build an app that is functionally similar to https://technical-documentation-page.freecodecamp.rocks -Compila le [user stories](https://en.wikipedia.org/wiki/User_story) qui sotto e fai passare tutti i test. Dalle il tuo stile personale. +**User Stories:** -Puoi utilizzare HTML, JavaScript, e CSS per completare questo progetto. CSS è raccomandato perché è l'argomento delle lezioni viste finora, e dovresti fare pratica con il CSS di base. Se lo desideri puoi anche utilizzare Bootstrap o SASS. Ulteriori tecnologie (solo per esempio jQuery, React, Angular, o Vue) non sono raccomandate per questo progetto, e usarle è a tuo rischio. Altri progetti ti daranno la possibilità di lavorare con differenti stack tecnologici come React. Accetteremo e cercheremo di risolvere tutte le segnalazioni di problemi che utilizzano lo stack tecnologico suggerito per questo progetto. Happy coding! +1. You can see a `main` element with a corresponding `id="main-doc"`, which contains the page's main content (technical documentation) +1. Within the `#main-doc` element, you can see several `section` elements, each with a class of `main-section`. There should be a minimum of five +1. The first element within each `.main-section` should be a `header` element, which contains text that describes the topic of that section. +1. Each `section` element with the class of `main-section` should also have an `id` that corresponds with the text of each `header` contained within it. Any spaces should be replaced with underscores (e.g. The section that contains the header "JavaScript and Java" should have a corresponding `id="JavaScript_and_Java"`) +1. The `.main-section` elements should contain at least ten `p` elements total (not each) +1. The `.main-section` elements should contain at least five `code` elements total (not each) +1. The `.main-section` elements should contain at least five `li` items total (not each) +1. You can see a `nav` element with a corresponding `id="navbar"` +1. The navbar element should contain one `header` element which contains text that describes the topic of the technical documentation +1. Additionally, the navbar should contain link (`a`) elements with the class of `nav-link`. There should be one for every element with the class `main-section` +1. The `header` element in the `#navbar` must come before any link (`a`) elements in the navbar +1. Each element with the class of `nav-link` should contain text that corresponds to the `header` text within each `section` (e.g. if you have a "Hello world" section/header, your navbar should have an element which contains the text "Hello world") +1. When you click on a navbar element, the page should navigate to the corresponding section of the `main-doc` element (e.g. If you click on a `nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id, and contains the corresponding header) +1. On regular sized devices (laptops, desktops), the element with `id="navbar"` should be shown on the left side of the screen and should always be visible to the user +1. Your technical documentation should use at least one media query -**User Story #1:** Posso vedere un elemento `main` con un corrispondente `id="main-doc"`, che contiene il contenuto principale della pagina (documentazione tecnica). +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**User story #2:** All'interno dell'elemento `#main-doc`, posso vedere diversi elementi `section`, ciascuno con una classe `main-section`. Dovrebbero essercene almeno 5. +# --hints-- -**User Story #3:** Il primo elemento all'interno di ogni `.main-section` dovrebbe essere un elemento `header` che contiene un testo che descrive l'argomento di quella sezione. +You should have a `main` element with an `id` of `main-doc` -**User Story #4:** Ogni elemento `section` con la classe `main-section` dovrebbe avere anche un id che corrisponde al testo di ogni `header` contenuto al suo interno. Qualsiasi spazio deve essere sostituito con underscore (ad es. La sezione `section` che contiene l'intestazione "JavaScript e Java" dovrebbe avere un corrispondente `id="JavaScript_and_Java"`). +```js +const el = document.getElementById('main-doc') +assert(!!el) +``` -**User Story #5:** Gli elementi `.main-section` dovrebbero contenere almeno 10 elementi `p` in totale (non ciascuno). +You should have at least five `section` elements with a class of `main-section` -**User Story #6:** Gli elementi `.main-section` dovrebbero contenere almeno 5 elementi `code` in totale (non ciascuno). +```js +const els = document.querySelectorAll('#main-doc section') +assert(els.length >= 5) +``` -**User story #7:** Gli elementi `.main-section` dovrebbero contenere almeno 5 elementi `li` in totale (non ciascuno). +All of your `.main-section` elements should be `section` elements -**User story #8:** Posso vedere un elemento `nav` con un corrispondente `id="navbar"`. +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (el.tagName !== 'SECTION') assert(false) +}) +assert(els.length > 0) +``` -**User Story #9:** L'elemento navbar dovrebbe contenere un elemento `header` che contiene del testo che descrive l'argomento della documentazione tecnica. +You should have at least five `.main-section` elements that are descendants of `#main-doc` -**User story #10:** Inoltre, la barra di navigazione dovrebbe contenere degli elementi link (`a`) con la classe `nav-link`. Dovrebbe essercene uno per ogni elemento di classe `main-section`. +```js +const els = document.querySelectorAll('#main-doc .main-section') +assert(els.length >= 5) +``` -**User story #11:** L'elemento `header` nella barra di navigazione deve venire prima di qualsiasi elemento link (`a`) nella barra di navigazione. +The first child of each `.main-section` should be a `header` element -**User story #12:** Ogni elemento di classe `nav-link` dovrebbe contenere un testo che corrisponde al testo `header` di ogni `section` (ad es. se hai una sezione/intestazione "Ciao mondo", la tua barra di navigazione dovrebbe avere un elemento che contiene il testo "Ciao mondo"). +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if(el.firstElementChild?.tagName !== 'HEADER') assert(false) +}) +assert(els.length > 0) +``` -**User story #13:** Quando clicco su un elemento della barra di navigazione, la pagina dovrebbe passare alla sezione corrispondente dell'elemento `main-doc` (ad es. se clicco su un elemento `nav-link` che contiene il testo "Ciao mondo", la pagina passa a un elemento `section` che ha quell'id e contiene il corrispondente `header`. +None of your `header` elements should be empty -**User story #14:** Su dispositivi di dimensioni regolari (computer portatili, desktop), l'elemento con `id="navbar"` dovrebbe essere mostrato sul lato sinistro dello schermo e dovrebbe essere sempre visibile all'utente. +```js +const els = document.querySelectorAll('header') +els.forEach(el => { + if (el.innerText?.length <= 0) assert(false) +}) +assert(els.length > 0) +``` -**User story #15:** La pagina Documentazione Tecnica dovrebbe utilizzare almeno una media query. +All of your `.main-section` elements should have an `id` -Puoi costruire il tuo progetto usando questo modello CodePen e cliccando `Save` per creare il tuo pen. Oppure puoi usare questo link CDN per eseguire i test in qualsiasi ambiente tu voglia: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (!el.id || el.id === '') assert(false) +}) +assert(els.length > 0) +``` -Una volta fatto, invia l'URL del tuo progetto di lavoro con tutti i suoi test passati. +Each `.main-section` should have an `id` that matches the text of its first child, having any spaces in the child's text replaced with underscores (`_`) for the id’s -# --solutions-- +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + const text = el.firstElementChild?.innerText?.replaceAll(' ', '_') + if (el.id?.toUpperCase() !== text?.toUpperCase()) assert(false) +}) +assert(els.length > 0) +``` + +You should have at least 10 `p` elements (total) within your `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section p') +assert(els.length >= 10) +``` + +You should have at least five `code` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section code') +assert(els.length >= 5) +``` + +You should have at least five `li` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section li') +assert(els.length >= 5) +``` + +You should have a `nav` element with an `id` of `navbar` + +```js +const el = document.getElementById('navbar') +assert(!!el && el.tagName === 'NAV') +``` + +Your `#navbar` should have exactly one `header` element within it + +```js +const els = document.querySelectorAll('#navbar header') +assert(els.length === 1) +``` + +You should have at least one `a` element with a class of `nav-link` + +```js +const els = document.querySelectorAll('a[class="nav-link"]') +assert(els.length >= 1) +``` + +All of your `.nav-link` elements should be anchor (`a`) elements + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (el.tagName !== 'A') assert(false) +}) +assert(els.length > 0) +``` + +All of your `.nav-link` elements should be in the `#navbar` + +```js +const els1 = document.querySelectorAll('.nav-link') +const els2 = document.querySelectorAll('#navbar .nav-link') +assert(els2.length > 0 && els1.length === els2.length) +``` + +You should have the same number of `.nav-link` and `.main-section` elements + +```js +const els1 = document.querySelectorAll('.main-section') +const els2 = document.querySelectorAll('.nav-link') +assert(els1.length > 0 && els2.length > 0 && els1.length === els2.length) +``` + +The `header` element in the `#navbar` should come before any link (`a`) elements also in the `#navbar` + +```js +const navLinks = document.querySelectorAll('#navbar a.nav-link'); +const header = document.querySelector('#navbar header'); +navLinks.forEach((navLink) => { + if ( + ( + header.compareDocumentPosition(navLink) & + Node.DOCUMENT_POSITION_PRECEDING + ) + ) assert(false) +}); +assert(!!header) +``` + +Each `.nav-link` should have text that corresponds to the `header` text of its related `section` (e.g. if you have a "Hello world" section/header, your `#navbar` should have a `.nav-link` which has the text "Hello world") + +```js +const headerText = Array.from(document.querySelectorAll('.main-section')).map(el => + el.firstElementChild?.innerText?.trim().toUpperCase() +) +const linkText = Array.from(document.querySelectorAll('.nav-link')).map(el => + el.innerText?.trim().toUpperCase() +) +const remainder = headerText.filter(str => linkText.indexOf(str) === -1) +assert(headerText.length > 0 && headerText.length > 0 && remainder.length === 0) +``` + +Each `.nav-link` should have an `href` attribute that links to its corresponding `.main-section` (e.g. If you click on a `.nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id) + +```js +const hrefValues = Array.from(document.querySelectorAll('.nav-link')).map(el => el.getAttribute('href')) +const mainSectionIDs = Array.from(document.querySelectorAll('.main-section')).map(el => el.id) +const missingHrefValues = mainSectionIDs.filter(str => hrefValues.indexOf('#' + str) === -1) +assert(hrefValues.length > 0 && mainSectionIDs.length > 0 && missingHrefValues.length === 0) +``` + +Your `#navbar` should always be on the left edge of the window + +```js +const el = document.getElementById('navbar') +const left1 = el?.offsetLeft +const left2 = el?.offsetLeft +assert(!!el && left1 >= -15 && left1 <= 15 && left2 >= -15 && left2 <= 15) +``` + +Your Technical Documentation project should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Technical Documentation Page + + + +
+
+
Introduction
+

+ Welcome to a basic introduction of algebra. In this tutorial, we will + review some of the more common algebraic concepts. +

+
+
+
Definitions
+

+ To start with, let's define some of the more common terms used in + algebra: +

+
    +
  • + Variable: A variable is an unknown value, usually represented + by a letter. +
  • +
  • + Expression: Essentially a mathematical object. For the + purpose of this tutorial, an expression is one part of an equation. +
  • +
  • + Equation: An equation is a mathematical argument in which two + expressions result in the same value. +
  • +
+
+
+
Examples
+

+ Sometimes it is easier to understand the definitions when you have a + physical example to look at. Here is an example of the above terms.

+ x + 5 = 12

+ In this above example, we have: +

+
    +
  • Variable: The variable in the example is "x".
  • +
  • + Expression: There are two expressions in this example. They + are "x+5" and "12". +
  • +
  • + Equation: The entire example, "x+5=12", is an equation. +
  • +
+
+
+
Solving Equations
+

+ The primary use for algebra is to determine an unknown value, the + "variable", with the information provided. Continuing to use our + example from above, we can find the value of the variable "x".

+ x + 5 = 12

+ In an equation, both sides result in the same value. So you can + manipulate the two expressions however you need, as long as you + perform the same operation (or change) to each side. You do this + because the goal when solving an equation is to + get the variable into its own expression, or by itself on one side + of the = sign.
For this example, we want to remove the "+5" so the "x" is + alone. To do this, we can subtract 5, because subtraction is + the opposite operation to addition. But remember, we have to perform + the same operation to both sides of the equation. Now our equation + looks like this.

+ x + 5 - 5 = 12 - 5

+ The equation looks like a mess right now, because we haven't completed + the operations. We can simplify this equation to make it easier + to read by performing the operations "5-5" and "12-5". The result + is:

+ x = 7

+ We now have our solution to this equation! +

+
+
+
Solving Equations II
+

+ Let us look at a slightly more challenging equation.

+ 3x + 4 = 13

+ Again we can start with subtraction. In this case, we want to subtract + 4 from each side of the equation. We will also go ahead and simplify + with each step. So now we have:

+ 3x = 9

+ "3x" translates to "3*x", where the "*" symbol indicates + multiplication. We use the "*" to avoid confusion, as the "x" is now a + variable instead of a multiplication symbol. The opposite operation + for multiplication is division, so we need to + divide each expression by 3.

+ x = 3

+ And now we have our solution! +

+
+
+
Solving Equations III
+

+ Now we are getting in to more complex operations. Here is another + equation for us to look at:

+ x^2 - 8 = 8

+ Our very first step will be to add 8 to each side. This is + different from our previous examples, where we had to subtract. But + remember, our goal is to get the variable alone by performing opposite + operations.

+ x^2 = 16

+ But what does the "^2" mean? The "^" symbol is used to denote + exponents in situations where superscript is not available. When + superscript is available, you would see it as x2. + For the sake of this project, however, we will use the "^" symbol.
+ An exponent tells you how many times the base (in our case, "x") is + multiplied by itself. So, "x^2" would be the same as "x*x". Now the + opposite function of multiplication is division, but we would have to + divide both sides by "x". We do not want to do this, as that + would put an "x" on the other side of the equation. So instead, we + need to use the root operation! For an exponent of "2", we call this + the "square root" and denote it with "√". Our equation is now: +

+ x = √9

+ Performing a root operation by hand can be a tedious process, so we + recommend using a calculator when necessary. However, we are lucky in + that "9" is a + perfect square, so we do not need to calculate anything. Instead, we find our + answer to be:

+ x = 3 +

+
+
+
System of Equations
+

+ As you explore your algebra studies further, you may start to run + across equations with more than one variable. The first such equations + will likely look like:

+ y = 3x

+ An equation like this does not have one single solution. + Rather, there are a series of values for which the equation is true. + For example, if "x=3" and "y=9", the equation is true. These equations + are usually used to plot a graph.
+ Getting more complicated, though, you may be given a pair of + equations. This is called a "system of equations", and CAN be solved. + Let's look at how we do this! Consider the following system of + equations:

+ y = 3x | y - 6 = x + A system of equations IS solvable, but it is a multi-step process. To + get started, we need to chose a variable we are solving for. Let's + solve for "x" first. From the second equation, we know that "x" equals + "y - 6", but we cannot simplify that further because we do not have a + value for "y". Except, thanks to the system of equations, we DO have a + value for "y". We know that "y" equals "3x". So, looking at our second + equation, we can replace "y" with "3x" because they have the same + value. We then get:

+ 3x - 6 = x

+ Now we can solve for "x"! We start by adding 6 to each side.

+ 3x = x + 6

+ We still need to get "x" by itself, so we subtract "x" from both sides + and get:

+ 2x = 6

+ If this confuses you, remember that "3x" is the same as "x+x+x". + Subtract an "x" from that and you get "x+x", or "2x". Now we divide + both sides by 2 and have our value for x!

+ x = 3

+ However, our work is not done yet. We still need to find the value for + "y". Let's go back to our first equation:

+ y = 3x

+ We have a value for "x" now, so let's see what happens if we put that + value in.

+ y = 3*3

+ We perform the multiplication and discover that "y=9"! Our solution to + this system of equations then is:

+ x = 3 and y = 9

+

+
+
+
Try it Yourself!
+

Coming Soon!

+

Keep an eye out for new additions!

+
+
+
More Information
+

Check out the following links for more information!

+ +
+
+ + + +``` + +```css +* { + background-color: #3a3240; +} +a { + color: #92869c; +} +a:hover { + background-color: #92869c; + color: #3a3240; +} +#navbar { + border-style: solid; + border-width: 5px; + border-color: #92869c; + height: 100%; + top: -5px; + left: -5px; + padding: 5px; + text-align: center; + color: #92869c +} +@media (min-width: 480px) { + #navbar { + position: fixed; + } +} +main { + margin-left: 220px; + color: #92869c +} +header { + font-size: 20pt; +} +code { + background-color: #92869c; + border-style: dashed; + border-width: 2px; + border-color: #92869c; + padding: 5px; + color: black; +} +footer { + text-align: center; +} ``` diff --git a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md index 7b688567036..231292b4373 100644 --- a/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md +++ b/curriculum/challenges/italian/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md @@ -1,43 +1,327 @@ --- id: bd7158d8c442eddfaeb5bd18 -title: Costruire una pagina di tributo -challengeType: 3 +title: Build a Tribute Page +challengeType: 14 forumTopicId: 301147 dashedName: build-a-tribute-page --- # --description-- -**Obiettivo:** Costruisci un'app [CodePen.io](https://codepen.io) funzionalmente simile a questa: . +**Objective:** Build an app that is functionally similar to https://tribute-page.freecodecamp.rocks -Compila le [user stories](https://en.wikipedia.org/wiki/User_story) qui sotto e fai passare tutti i test. Dalle il tuo stile personale. +**User Stories:** -Puoi utilizzare HTML, JavaScript, e CSS per completare questo progetto. CSS è raccomandato perché è l'argomento delle lezioni viste finora e dovresti fare pratica con il CSS di base. Se lo desideri puoi anche utilizzare Bootstrap o SASS. Ulteriori tecnologie (solo per esempio jQuery, React, Angular, o Vue) non sono raccomandate per questo progetto, e usarle è a tuo rischio. Altri progetti ti daranno la possibilità di lavorare con differenti stack tecnologici come React. Accetteremo e cercheremo di risolvere tutte le segnalazioni di problemi che utilizzano lo stack tecnologico suggerito per questo progetto. Happy coding! +1. Your tribute page should have an element with a corresponding `id="main"`, which contains all other elements +1. You should see an element with an `id` of `title`, which contains a string (i.e. text), that describes the subject of the tribute page (e.g. "Dr. Norman Borlaug") +1. You should see either a `figure` or a `div` element with an `id` of `img-div` +1. Within the `img-div` element, you should see an `img` element with a corresponding `id="image"` +1. Within the `img-div` element, you should see an element with a corresponding `id="img-caption"` that contains textual content describing the image shown in `img-div` +1. You should see an element with a corresponding `id="tribute-info"`, which contains textual content describing the subject of the tribute page +1. You should see an a element with a corresponding `id="tribute-link"`, which links to an outside site, that contains additional information about the subject of the tribute page. HINT: You must give your element an attribute of `target` and set it to `_blank` in order for your link to open in a new tab +1. Your `#image` should use `max-width` and `height` properties to resize responsively, relative to the width of its parent element, without exceeding its original size +1. Your `img` element should be centered within its parent element -**User story #1:** La mia pagina di tributo dovrebbe avere un elemento con un corrispondente `id="main"`che contiene tutti gli altri elementi. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**User Story #2:** Dovrei vedere un elemento con un corrispondente `id="title"`che contiene una stringa (cioè un testo) che descrive l'oggetto della pagina di tributo (ad esempio "Dr. Norman Borlaug"). +# --hints-- -**User story #3:** Dovrei vedere un elemento `figure` oppure un elemento `div` con un corrispondente `id="img-div"`. +You should have a `main` element with an `id` of `main` -**User story #4:** All'interno dell'elemento `img-div`, dovrei vedere un elemento `img` con un corrispondente `id="image"`. +```js +const el = document.getElementById('main') +assert(!!el && el.tagName === 'MAIN') +``` -**User story #5:** All'interno dell'elemento `img-div`, dovrei vedere un elemento con un corrispondente `id="img-caption"` che contiene un testo che descrive l'immagine mostrata in `img-div`. +Your `#img-div`, `#image`, `#img-caption`, `#tribute-info`, and `#tribute-link` should all be descendants of `#main` -**User Story #6:** Dovrei vedere un elemento con un corrispondente `id="tribute-info"`, che contiene dei testi che descrivono l'oggetto della pagina di tributo. +```js +const el1 = document.querySelector('#main #img-div') +const el2 = document.querySelector('#main #image') +const el3 = document.querySelector('#main #img-caption') +const el4 = document.querySelector('#main #tribute-info') +const el5 = document.querySelector('#main #tribute-link') +assert(!!el1 & !!el2 && !!el3 && !!el4 && !!el5) +``` -**User story #7:** Dovrei vedere un elemento `a` con un corrispondente `id="tribute-link"`, che si collega a un sito esterno che contiene ulteriori informazioni sull'oggetto della pagina di tributo. SUGGERIMENTO: Dovresti dare al tuo elemento un attributo `target` e impostarlo a `_blank` in modo che il link si apra in una nuova scheda (`target="_blank"`). +You should have an element with an `id` of `title` -**User story #8:** L'elemento `img` dovrebbe ridimensionarsi responsivamente, rispetto alla larghezza dell'elemento principale, senza superare la dimensione originale. +```js +const el = document.getElementById('title') +assert(!!el) +``` -**User story #9:** L'elemento `img` dovrebbe essere centrato all'interno del suo elemento genitore. +Your `#title` should not be empty -Puoi costruire il tuo progetto usando questo modello CodePen e facendo clic su `Save` per creare il tuo pen. Oppure puoi usare questo link CDN per eseguire i test in qualsiasi ambiente tu voglia: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`. +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) -Una volta fatto, invia l'URL del tuo progetto di lavoro con tutti i suoi test passati. +``` -# --solutions-- +You should have a `figure` or `div` element with an `id` of `img-div` + +```js +const el = document.getElementById('img-div') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGURE')) +``` + +You should have an `img` element with an `id` of `image` + +```js +const el = document.getElementById('image') +assert(!!el && el.tagName === 'IMG') +``` + +Your `#image` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #image') +assert(!!el) +``` + +You should have a `figcaption` or `div` element with an `id` of `img-caption` + +```js +const el = document.getElementById('img-caption') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGCAPTION')) +``` + +Your `#img-caption` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #img-caption') +assert(!!el) +``` + +Your `#img-caption` should not be empty + +```js +const el = document.getElementById('img-caption') +assert(!!el && el.innerText.length > 0) +``` + +You should have an element with an `id` of `tribute-info` + +```js +const el = document.getElementById('tribute-info') +assert(!!el) +``` + +Your `#tribute-info` should not be empty + +```js +const el = document.getElementById('tribute-info') +assert(!!el && el.innerText.length > 0) +``` + +You should have an `a` element with an `id` of `tribute-link` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.tagName === 'A') +``` + +Your `#tribute-link` should have an `href` attribute and value + +```js +const el = document.getElementById('tribute-link') +assert(!!el && !!el.href && el.href.length > 0) +``` + +Your `#tribute-link` should have a `target` attribute set to `_blank` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.target === '_blank') +``` + +You should use an `#image` selector in your CSS to style the `#image` and pass the next three tests + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image') +assert(!!style) +``` + +Your `#image` should have a `display` of `block` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +assert(style === 'block') +``` + +Your `#image` should have a `max-width` of `100%` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +assert(style === '100%') +``` + +Your `#image` should have a `height` of `auto` + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'); +const maxWidthValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +const displayValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +const oldDisplayValue = img?.style.getPropertyValue('display'); +const oldDisplayPriority = img?.style.getPropertyPriority('display'); +img?.style.setProperty('display', 'none', 'important'); +const heightValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('height') +img?.style.setProperty('display', oldDisplayValue, oldDisplayPriority); +assert(heightValue === 'auto') +``` + +Your `#image` should be centered within its parent + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'), + imgParent = img?.parentElement, + imgLeft = img?.getBoundingClientRect().left, + imgRight = img?.getBoundingClientRect().right, + parentLeft = imgParent?.getBoundingClientRect().left, + parentRight = imgParent?.getBoundingClientRect().right, + leftMargin = imgLeft - parentLeft, + rightMargin = parentRight - imgRight; +assert(leftMargin - rightMargin < 6 && rightMargin - leftMargin < 6) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + + + Tribute Page + + +

Tribute Page

+

The below card was designed as a tribute page for freeCodeCamp.

+
+
+ An image of Togepi +
Togepi, happy as always.
+
+

Togepi

+
+
+

+ Togepi was first discovered in the Johto region, when Ash Ketchum + discovered a mysterious egg. However, when the egg hatched, Togepi saw + Ash's friend Misty first and imprinted on her. Like many other + creatures, this imprinting process created a bond and Togepi views + Misty as his mother. +

+

+ Togepi is a very childlike Pokemon, and is very emotionally + expressive. He demonstrates extreme levels of joy and sadness. +

+
+

Battle Information

+
    +
  • Type: Fairy
  • +
  • Evolutions: Togepi -> Togetic -> Togekiss
  • +
  • Moves: Growl, Pound, Sweet Kiss, Charm
  • +
  • Weaknesses: Poison, Steel
  • +
  • Resistances: Dragon
  • +
+

+ Check out this + Bulbapedia article on Togepi + for more information on this great Pokemon. +

+
+
+ + + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + background-color: #92869c; + font-family: Lobster; + max-width: 500px; + margin: 20px auto; + color: black; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); +} +h2 { + text-align: center; + font-size: 20pt; + font-family: Pacifico; +} +body { + text-align: center; + font-size: 12pt; +} +footer { + text-align: center; + font-size: 10pt; +} +.border { + border-color: black; + border-width: 5px; + border-style: solid; +} +#image { + height: auto; + display: block; + margin: auto; + max-width: 100%; + border-radius: 50%; +} +#img-caption { + font-size: 10pt; +} +a:not(#tribute-link) { + color: white; +} +hr { + border-color: black; +} ``` diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/build-a-personal-portfolio-webpage-project/build-a-personal-portfolio-webpage.md b/curriculum/challenges/italian/14-responsive-web-design-22/build-a-personal-portfolio-webpage-project/build-a-personal-portfolio-webpage.md index 83a27d403c4..0226992eec9 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/build-a-personal-portfolio-webpage-project/build-a-personal-portfolio-webpage.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/build-a-personal-portfolio-webpage-project/build-a-personal-portfolio-webpage.md @@ -1,47 +1,277 @@ --- id: bd7158d8c242eddfaeb5bd13 -title: Creare una pagina Web per il Portfolio Personale -challengeType: 3 +title: Build a Personal Portfolio Webpage +challengeType: 14 forumTopicId: 301143 dashedName: build-a-personal-portfolio-webpage --- # --description-- -**Obiettivo:** Costruire un'app [CodePen.io](https://codepen.io) funzionalmente simile a questa: . +**Objective:** Build an app that is functionally similar to https://personal-portfolio.freecodecamp.rocks -Soddisfa le seguenti [user story](https://en.wikipedia.org/wiki/User_story) e fai passare tutti i test. Usa il tuo stile personale. +**User Stories:** -Puoi utilizzare HTML, JavaScript, e CSS per completare questo progetto. CSS è raccomandato perché è l'argomento delle lezioni viste finora e dovresti fare pratica con il CSS di base. Se lo desideri puoi anche utilizzare Bootstrap o SASS. Ulteriori tecnologie (solo per fare un esempio jQuery, React, Angular, o Vue) non sono raccomandate per questo progetto, e usarle è a tuo rischio. Altri progetti ti daranno la possibilità di lavorare con diversi stack tecnologici come React. Accetteremo e cercheremo di risolvere tutte le segnalazioni di problemi che utilizzano lo stack tecnologico suggerito per questo progetto. Happy coding! +1. Your portfolio should have a welcome section with an `id` of `welcome-section` +1. The welcome section should have an `h1` element that contains text +1. Your portfolio should have a projects section with an `id` of `projects` +1. The projects section should contain at least one element with a `class` of `project-tile` to hold a project +1. The projects section should contain at least one link to a project +1. Your portfolio should have a navbar with an id of `navbar` +1. The navbar should contain at least one link that you can click on to navigate to different sections of the page +1. Your portfolio should have a link with an id of `profile-link`, which opens your GitHub or freeCodeCamp profile in a new tab +1. Your portfolio should have at least one media query +1. The height of the welcome section should be equal to the height of the viewport +1. The navbar should always be at the top of the viewport -**User Story #1:** Il mio portfolio dovrebbe avere una sezione di benvenuto con un id di `welcome-section`. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**User Story #2:** La sezione di benvenuto dovrebbe avere un elemento `h1` che contiene testo. +# --hints-- -**User Story #3:** Il mio portfolio dovrebbe avere una sezione progetti con un id di `projects`. +Your portfolio should have a "Welcome" section with an `id` of `welcome-section`. -**User Story #4:** La sezione progetti dovrebbe contenere almeno un elemento con una classe `project-tile` che contenga un progetto. +```js +const el = document.getElementById('welcome-section') +assert(!!el); +``` -**User Story #5:** La sezione progetti dovrebbe contenere almeno un link a un progetto. +Your `#welcom-section` element should contain an `h1` element. -**User Story #6:** Il mio portfolio dovrebbe avere una navbar con un id di `navbar`. +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1').length, + 0, + 'Welcome section should contain an h1 element ' +); +``` -**User Story #7:** La barra di navigazione dovrebbe contenere almeno un link su cui posso cliccare per navigare in diverse sezioni della pagina. +You should not have any empty `h1` elements within `#welcome-section` element. -**User Story #8:** Il mio portfolio dovrebbe avere un link con un id di `profile-link`, che apre il mio profilo GitHub o FCC in una nuova scheda. +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1')?.[0]?.innerText?.length, + 0, + 'h1 element in welcome section should contain your name or camper ' + + 'name ' +); +``` -**User Story #9:** Il mio portfolio dovrebbe avere almeno una media query. +You should have a "Projects" section with an `id` of `projects`. -**User Story #10:** L'altezza della sezione di benvenuto dovrebbe essere uguale all'altezza della viewport. +```js +const el = document.getElementById('projects') +assert(!!el); +``` -**User Story #11:** La barra di navigazione dovrebbe sempre essere in cima alla viewport. +Your portfolio should contain at least one elment with a class of `project-tile`. -Puoi costruire il tuo progetto usando questo modello CodePen e facendo clic su `Save` per creare il tuo pen. Oppure puoi usare questo link CDN per eseguire i test in qualsiasi ambiente tu voglia: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +assert.isAbove( + document.querySelectorAll('#projects .project-tile').length, + 0 +); +``` -Una volta fatto, invia l'URL del tuo progetto di lavoro con tutti i suoi test superati. +Your `#projects` element should contain at least one `a` element. -# --solutions-- +```js +assert.isAbove(document.querySelectorAll('#projects a').length, 0); +``` + +Your portfolio should have a navbar with an `id` of `navbar`. + +```js +const el = document.getElementById('navbar'); +assert(!!el); +``` + +Your `#navbar` element should contain at least one `a` element whose `href` attribute starts with `#`. + +```js +const links = [...document.querySelectorAll('#navbar a')].filter( + (nav) => (nav?.getAttribute('href') || '').substr(0, 1) === '#' +); + +assert.isAbove( + links.length, + 0, + 'Navbar should contain an anchor link ' +); +``` + +Your portfolio should have an `a` element with an `id` of `profile-link`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.tagName === 'A') +``` + +Your `#profile-link` element should have a `target` attribute of `_blank`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.target === '_blank') +``` + +Your portfolio should use at least one media query. + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your `#navbar` element should always be at the top of the viewport. + +```js +(async () => { + const timeout = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)); + + const navbar = document.getElementById('navbar'); + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + "Navbar's parent should be body and it should be at the top of " + + 'the viewport ' + ); + + window.scroll(0, 500); + + await timeout(1); + + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + 'Navbar should be at the top of the viewport even after ' + + 'scrolling ' + ); + window.scroll(0, 0); +})(); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Personal Portfolio + + + + + +
+
+
+

It's me!

+ +

Naomi Carrigan

+

Welcome to my portfolio page!

+

+
+

Projects

+

Here's what I've worked on!

+

+ + + + +


+
+

Contact me!

+

Use the links below to get in touch.

+

FreeCodeCamp.org | GitHub | Facebook | LinkedIn +

+ + + +``` + +```css +nav{ + position: fixed; + width: 100%; + text-align: right; + font-size: 24pt; + top: 0%; + right: 5px; + background-color: #000000; + color: #ffffff; +} +@media (max-width: 500px){ + nav{ + display: none; + } +} +a{ + color: #ffffff; +} +main{ + text-align: center; + background-color: black; + font-family:Pacifico +} +h1{ + font-size: 48pt; +} +h2{ + font-size: 24pt; +} +p{ + font-size: 12pt; +} +#welcome-section{ + background-color:#251a4a; + color: #FFFFFF; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#projects{ + background-color: #060a9c; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#contact{ + background-color: #03300b; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} ``` diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/build-a-product-landing-page-project/build-a-product-landing-page.md b/curriculum/challenges/italian/14-responsive-web-design-22/build-a-product-landing-page-project/build-a-product-landing-page.md index f60b6700f10..dbe9f50c4b1 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/build-a-product-landing-page-project/build-a-product-landing-page.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/build-a-product-landing-page-project/build-a-product-landing-page.md @@ -1,55 +1,424 @@ --- id: 587d78af367417b2b2512b04 -title: Costruire la Landing Page per un prodotto -challengeType: 3 +title: Build a Product Landing Page +challengeType: 14 forumTopicId: 301144 dashedName: build-a-product-landing-page --- # --description-- -**Obiettivo:** Costruire un'app [CodePen.io](https://codepen.io) funzionalmente simile a questa: . +**Objective:** Build an app that is functionally similar to https://product-landing-page.freecodecamp.rocks -Soddisfa le seguenti [user story](https://en.wikipedia.org/wiki/User_story) e fai passare tutti i test. Usa il tuo stile personale. +**User Stories:** -Puoi utilizzare HTML, JavaScript, e CSS per completare questo progetto. CSS è raccomandato perché è l'argomento delle lezioni viste finora e dovresti fare pratica con il CSS di base. Se lo desideri puoi anche utilizzare Bootstrap o SASS. Ulteriori tecnologie (solo per fare un esempio jQuery, React, Angular, o Vue) non sono raccomandate per questo progetto, e usarle è a tuo rischio. Altri progetti ti daranno la possibilità di lavorare con diversi stack tecnologici come React. Accetteremo e cercheremo di risolvere tutte le segnalazioni di problemi che utilizzano lo stack tecnologico suggerito per questo progetto. Happy coding! +1. Your product landing page should have a `header` element with a corresponding `id="header"` +1. You can see an image within the `header` element with a corresponding `id="header-img"` (A logo would make a good image here) +1. Within the `#header` element, you can see a `nav` element with a corresponding `id="nav-bar"` +1. You can see at least three clickable elements inside the `nav` element, each with the class `nav-link` +1. When you click a `.nav-link` button in the `nav` element, you are taken to the corresponding section of the landing page +1. You can watch an embedded product video with `id="video"` +1. Your landing page has a `form` element with a corresponding `id="form"` +1. Within the form, there is an `input` field with `id="email"` where you can enter an email address +1. The `#email` input field should have placeholder text to let users know what the field is for +1. The `#email` input field uses HTML5 validation to confirm that the entered text is an email address +1. Within the form, there is a submit `input` with a corresponding `id="submit"` +1. When you click the `#submit` element, the email is submitted to a static page (use this mock URL: `https://www.freecodecamp.com/email-submit`) +1. The navbar should always be at the top of the viewport +1. Your product landing page should have at least one media query +1. Your product landing page should utilize CSS flexbox at least once -**User Story#1:** La pagina di destinazione del prodotto dovrebbe avere un elemento `header` con un corrispondente `id="header"`. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**User Story #2:** Posso vedere un'immagine all'interno dell'elemento `header` con un corrispondente `id="header-img"`. Un logo aziendale qui starebbe bene. +# --hints-- -**User Story #3:** All'interno dell'elemento `#header` posso vedere un elemento `nav` con un corrispondente `id="nav-bar"`. +You should have a `header` element with an `id` of `header` -**User Story #4:** Posso vedere almeno tre elementi cliccabili all'interno dell'elemento `nav`, ognuno con la classe `nav-link`. +```js +const el = document.getElementById('header') +assert(!!el && el.tagName === 'HEADER') +``` -**User Story #5:** Quando clicco su un pulsante `.nav-link` nell'elemento `nav`, sono portato nella sezione corrispondente della pagina di destinazione. +You should have an `img` element with an `id` of `header-img` -**User Story #6:** Posso guardare un video incorportato del prodotto con `id="video"`. +```js +const el = document.getElementById('header-img') +assert(!!el && el.tagName === 'IMG') +``` -**User Story #7:** La mia pagina iniziale ha un elemento `form` con un corrispondente `id="form"`. +Your `#header-img` should be a descendant of the `#header` -**User Story #8:** All'interno del modulo c'è un campo `input` con `id="email"` dove posso inserire un indirizzo email. +```js +const els = document.querySelectorAll('#header #header-img') +assert(els.length > 0) +``` -**User Story #9:** Il campo di input `#email` dovrebbe avere un testo segnaposto per far sapere all'utente a cosa serve il campo. +Your `#header-img` should have a `src` attribute -**User Story #10:** Il campo di input `#email` utilizza la validazione HTML5 per confermare che il testo inserito è un indirizzo email. +```js +const el = document.getElementById('header-img') +assert(!!el && !!el.src) +``` -**User Story #11:** All'interno del modulo, c'è un `input` di tipo submit con un `id="submit"`. +Your `#header-img`’s `src` value should be a valid URL (starts with `http`) -**User Story #12:** Quando clicco l'elemento `#submit`, l'email viene inviata a una pagina statica (usa questo URL fittizio: ). +```js +const el = document.getElementById('header-img') +assert(!!el && /^http/.test(el.src)) +``` -**User Story #13:** La barra di navigazione dovrebbe sempre essere in cima alla viewport. +You should have a `nav` element with an `id` of `nav-bar` -**User Story #14:** La landing page del prodotto dovrebbe avere almeno una media query. +```js +const el = document.getElementById('nav-bar') +assert(!!el && el.tagName === 'NAV') +``` -**User Story #15:** La landing page del prodotto dovrebbe utilizzare la flexbox CSS almeno una volta. +Your `#nav-bar` should be a descendant of the `#header` -Puoi costruire il tuo progetto usando questo modello CodePen e cliccando `Save` per creare il tuo pen. Oppure puoi usare questo link CDN per eseguire i test in qualsiasi ambiente tu voglia: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +const els = document.querySelectorAll('#header #nav-bar') +assert(els.length > 0) +``` -Una volta fatto, invia l'URL al tuo progetto di lavoro con tutti i suoi test passati. +You should have at least 3 `.nav-link` elements within the `#nav-bar` -# --solutions-- +```js +const els = document.querySelectorAll('#nav-bar .nav-link') +assert(els.length >= 3) +``` + +Each `.nav-link` element should have an `href` attribute + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (!el.href) assert(false) +}) +assert(els.length > 0) +``` + +Each `.nav-link` element should link to a corresponding element on the landing page (has an `href` with a value of another element's id. e.g. `#footer`) + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + const linkDestination = el.getAttribute('href').slice(1) + if (!document.getElementById(linkDestination)) assert(false) +}) +assert(els.length > 0) +``` + +You should have a `video` or `iframe` element with an `id` of `video` + +```js +const el = document.getElementById('video') +assert(!!el && (el.tagName === 'VIDEO' || el.tagName === 'IFRAME')) +``` + +Your `#video` should have a `src` attribute + +```js +const el = document.getElementById('video') +assert(!!el && !!el.src) +``` + +You should have a `form` element with an `id` of `form` + +```js +const el = document.getElementById('form') +assert(!!el && el.tagName === 'FORM') +``` + +You should have an `input` element with an `id` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #email') +assert(els.length > 0) +``` + +Your `#email` should have the `placeholder` attribute with placeholder text + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should use HTML5 validation by setting its `type` to `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +You should have an `input` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#submit` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #submit') +assert(els.length > 0) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#form` should have an `action` attribute of `https://www.freecodecamp.com/email-submit` + +```js +const el = document.getElementById('form') +assert(!!el && el.action === 'https://www.freecodecamp.com/email-submit') +``` + +Your `#email` should have a `name` attribute of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.name === 'email') +``` + +Your `#nav-bar` should always be at the top of the viewport + +```js +const el = document.getElementById('nav-bar') +const top1 = el?.offsetTop +const top2 = el?.offsetTop +assert(!!el && top1 >= -15 && top1 <= 15 && top2 >= -15 && top2 <= 15) +``` + +Your Product Landing Page should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your Product Landing Page should use CSS Flexbox at least once + +```js +const stylesheet = new __helpers.CSSHelp(document).getStyleSheet() +const cssRules = new __helpers.CSSHelp(document).styleSheetToCssRulesArray(stylesheet) +const usesFlex = cssRules.find(rule => { + return rule.style?.display === 'flex' || rule.style?.display === 'inline-flex' +}) +assert(usesFlex) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Product Landing Page + + + +
+

+ Pokemon Daycare Service +

+
+

What we offer

+
+
+ +
+
Guaranteed friendly and loving staff!
+
+
+
+ +
+
+ Comfortable environment for Pokemon to explore and play! +
+
+
+
+ +
+
+ Multiple membership plans to fit your lifestyle! +
+
+
+
+

Check us out!

+ A sneak peek into our facility: +
+ +
+
+

Membership Plans

+
+
+ Basic Membership
+
    +
  • One Pokemon
  • +
  • Food and berries provided
  • +
+ $9.99/month +
+
+ Silver Membership
+
    +
  • Up to Three Pokemon
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
+ $19.99/month +
+
+ Gold Membership
+
    +
  • Up to six Pokemon!
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
  • Personal training for each Pokemon
  • +
  • Breeding and egg hatching
  • +
+ $29.99/month +
+
+
+
+

Sign up for our newsletter!

+ + +
+ +
+ + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + max-width: 750px; + margin: 50px auto; +} +input { + background-color: #92869c; +} +a:not(.nav-link) { + color: white; +} +#header-img { + max-height: 25px; +} +#nav-bar { + position: fixed; + width: 100%; + text-align: center; + top: 0%; + background-color: #92869c; +} +h1 { + text-align: center; +} +body { + text-align: center; +} +footer { + text-align: center; +} +#bullet { + max-height: 25px; +} +.flex-here { + display: flex; + justify-content: center; +} +.flex-left { + height: 25px; +} +.flex-mem { + display: flex; + justify-content: center; +} +.flex-mem-box { + background-color: #92869c; + border-color: black; + border-width: 5px; + border-style: solid; + margin: 10px; + padding: 10px; + color: black; +} +@media (max-width: 350px) { + #video { + width: 300; + height: 200; + } +} ``` diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md b/curriculum/challenges/italian/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md index b312964e381..937c4482c93 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md @@ -1,57 +1,516 @@ --- id: 587d78af367417b2b2512b03 -title: Crea un modulo di sondaggio -challengeType: 3 +title: Build a Survey Form +challengeType: 14 forumTopicId: 301145 dashedName: build-a-survey-form --- # --description-- -**Obiettivo:** Costruisci un'app [CodePen.io](https://codepen.io) funzionalmente simile a questa: . +**Objective:** Build an app that is functionally similar to https://survey-form.freecodecamp.rocks -Soddisfa le seguenti [user story](https://en.wikipedia.org/wiki/User_story) e fai passare tutti i test. Usa il tuo stile personale. +**User Stories:** -Puoi utilizzare HTML, JavaScript, e CSS per completare questo progetto. CSS è raccomandato perché è l'argomento delle lezioni viste finora e dovresti fare pratica con il CSS di base. Se lo desideri puoi anche utilizzare Bootstrap o SASS. Ulteriori tecnologie (solo per fare un esempio jQuery, React, Angular, o Vue) non sono raccomandate per questo progetto, e usarle è a tuo rischio. Altri progetti ti daranno la possibilità di lavorare con diversi stack tecnologici come React. Accetteremo e cercheremo di risolvere tutte le segnalazioni di problemi che utilizzano lo stack tecnologico suggerito per questo progetto. Happy coding! +1. You should have a page title in an `h1` element with an `id` of `title` +1. You should have a short explanation in a `p` element with an `id` of `description` +1. You should have a `form` element with an `id` of `survey-form` +1. Inside the form element, you are **required** to enter your name in an `input` field that has an `id` of `name` and a `type` of `text` +1. Inside the form element, you are **required** to enter your email in an `input` field that has an `id` of `email` +1. If you enter an email that is not formatted correctly, you will see an HTML5 validation error +1. Inside the form, you can enter a number in an `input` field that has an `id` of `number` +1. If you enter non-numbers in the number input, you will see an HTML5 validation error +1. If you enter numbers outside the range of the number input, which are defined by the `min` and `max` attributes, you will see an HTML5 validation error +1. For the name, email, and number input fields, you can see corresponding `label` elements in the form, that describe the purpose of each field with the following ids: `id="name-label"`, `id="email-label"`, and `id="number-label"` +1. For the name, email, and number input fields, you can see placeholder text that gives a description or instructions for each field +1. Inside the form element, you should have a `select` dropdown element with an `id` of `dropdown` and at least two options to choose from +1. Inside the form element, you can select an option from a group of at least two radio buttons that are grouped using the `name` attribute +1. Inside the form element, you can select several fields from a series of checkboxes, each of which must have a `value` attribute +1. Inside the form element, you are presented with a `textarea` for additional comments +1. Inside the form element, you are presented with a button with `id` of `submit` to submit all the inputs -**User Story #1:** Posso vedere un titolo con `id="title"` in un testo di dimensioni H1. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**User Story #2:** Posso vedere una breve spiegazione con `id="description"` in un testo di dimensione P. +# --hints-- -**User Story #3:** Posso vedere un `form` con `id="survey-form"`. +You should have an `h1` element with an `id` of `title` -**User Story #4:** All'interno del modulo, mi viene chiesto di inserire il mio nome in un campo con `id="name"`. +```js +const el = document.getElementById('title') +assert(!!el && el.tagName === 'H1') +``` -**User Story #5:** All'interno del modulo, mi viene chiesto di inserire un'email in un campo con `id="email"`. +Your `#title` should not be empty -**User Story #6:** Se inserisco un'email non formattata correttamente, vedrò un errore di validazione HTML5. +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) +``` -**User Story #7:** All'interno del modulo, posso inserire un numero in un campo con `id="number"`. +You should have a `p` element with an `id` of `description` -**User story #8:** Se inserisco caratteri non numerici nell'input di tipo number, vedrò un errore di validazione HTML5. +```js +const el = document.getElementById('description') +assert(!!el && el.tagName === 'P') +``` -**User story #9:** Se inserisco numeri al di fuori dell'intervallo dell'input numerico, che sono definiti dagli attributi `min` e `max`, vedrò un errore di validazione HTML5. +Your `#description` should not be empty -**User story #10:** Per il nome, l'e-mail, e i campi di input numerici all'interno del modulo posso vedere le etichette corrispondenti che descrivono lo scopo di ogni campo con i seguenti id: `id="name-label"`, `id="email-label"`e `id="number-label"`. +```js +const el = document.getElementById('description') +assert(!!el && el.innerText.length > 0) +``` -**User story#11:** Per i campi di input di nome, email e numero, posso vedere il testo segnaposto che mi dà una descrizione o delle istruzioni per ogni campo. +You should have a `form` element with an `id` of `survey-form` -**User story #12:** All'interno del modulo, posso selezionare un'opzione da un menu a discesa che ha un corrispondente `id="dropdown"`. +```js +const el = document.getElementById('survey-form') +assert(!!el && el.tagName === 'FORM') +``` -**User story #13:** All'interno del modulo, posso selezionare un campo da uno o più gruppi di pulsanti di opzione. Ogni gruppo dovrebbe essere raggruppato usando l'attributo `name`. +You should have an `input` element with an `id` of `name` -**User story #14:** All'interno del modulo, posso selezionare diversi campi da una serie di caselle di spunta, ciascuno dei quali deve avere un attributo `value`. +```js +const el = document.getElementById('name') +assert(!!el && el.tagName === 'INPUT') +``` -**User story #15:** All'interno del modulo, mi viene presentata alla fine una `textarea`, per inserire ulteriori commenti. +Your `#name` should have a `type` of `text` -**User story #16:** All'interno del modulo, mi viene presentato un pulsante con `id="submit"` per inviare tutti i miei input. +```js +const el = document.getElementById('name') +assert(!!el && el.type === 'text') +``` -Puoi costruire il tuo progetto usando questo modello CodePen e facendo click su `Save` per creare il tuo pen. Oppure puoi usare questo link CDN per eseguire i test in qualsiasi ambiente tu voglia: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +Your `#name` should require input -Una volta fatto, invia l'URL del tuo progetto di lavoro con tutti i suoi test superati. +```js +const el = document.getElementById('name') +assert(!!el && el.required) +``` -# --solutions-- +Your `#name` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name') +assert(!!el) +``` + +You should have an `input` element with an `id` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should have a `type` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +Your `#email` should require input + +```js +const el = document.getElementById('email') +assert(!!el && el.required) +``` + +Your `#email` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email') +assert(!!el) +``` + +You should have an `input` element with an `id` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#number` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number') +assert(!!el) +``` + +Your `#number` should have a `type` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.type === 'number') +``` + +Your `#number` should have a `min` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.min && isFinite(el.min)) +``` + +Your `#number` should have a `max` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.max && isFinite(el.max)) +``` + +You should have a `label` element with an `id` of `name-label` + +```js +const el = document.getElementById('name-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `email-label` + +```js +const el = document.getElementById('email-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `number-label` + +```js +const el = document.getElementById('number-label') +assert(!!el && el.tagName === 'LABEL') +``` + +Your `#name-label` should not be empty + +```js +const el = document.getElementById('name-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#email-label` should not be empty + +```js +const el = document.getElementById('email-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#number-label` should not be empty + +```js +const el = document.getElementById('number-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#name-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name-label') +assert(!!el) +``` + +Your `#email-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email-label') +assert(!!el) +``` + +Your `#number-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number-label') +assert(!!el) +``` + +Your `#name` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('name') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#number` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('number') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +You should have a `select` field with an `id` of `dropdown` + +```js +const el = document.getElementById('dropdown') +assert(!!el && el.tagName === 'SELECT') +``` + +Your `#dropdown` should have at least two selectable (not disabled) `option` elements + +```js +const els = document.querySelectorAll('#dropdown option:not([disabled])') +assert(els.length >= 2) +``` + +Your `#dropdown` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #dropdown') +assert(!!el) +``` + +You should have at least two `input` elements with a `type` of `radio` (radio buttons) + +```js +const els = document.querySelectorAll('input[type="radio"]') +assert(els.length >= 2) +``` + +You should have at least two radio buttons that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="radio"]') +assert(els.length >= 2) +``` + +All your radio buttons should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][value=""], input[type="radio"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +All your radio buttons should have a `name` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][name=""], input[type="radio"]:not([name])') +assert(els1.length > 0 && els2.length === 0) +``` + +Every radio button group should have at least 2 radio buttons + +```js +const radioButtons = document.querySelectorAll('input[type="radio"]'); +const groups = {} + +if (radioButtons) { + radioButtons.forEach(el => { + if (!groups[el.name]) groups[el.name] = [] + groups[el.name].push(el) + }) +} + +const groupKeys = Object.keys(groups) + +groupKeys.forEach(key => { + if (groups[key].length < 2) assert(false) +}) + +assert(groupKeys.length > 0) +``` + +You should have at least two `input` elements with a `type` of `checkbox` (checkboxes) that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="checkbox"]'); +assert(els.length >= 2) +``` + +All your checkboxes inside `#survey-form` should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('#survey-form input[type="checkbox"]') +const els2 = document.querySelectorAll('#survey-form input[type="checkbox"][value=""], #survey-form input[type="checkbox"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +You should have at least one `textarea` element that is a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form textarea') +assert(!!el) +``` + +You should have an `input` or `button` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && (el.tagName === 'INPUT' || el.tagName === 'BUTTON')) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#submit` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #submit') +assert(!!el) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Survey Form + + +

Survey Form

+

The card below was built as a sample survey form for freeCodeCamp.

+
+

Join the Togepi Fan Club!

+

+ Enter your information here to receive updates about club activities, + our monthly newsletter, and other email communications. +

+
+ + + + +

Who is your favourite Pokemon?

+ + + +

Which communications do you want to receive?

+ + + +

Any other information you would like to share?

+ +

+ Please note: This form is a proof of concept. Submitting the form + will not actually transmit your data. +

+ +
+
+ + + +``` + +```css +main { + text-align: center; + background-color: #92869c; + background-blend-mode: lighten; + max-width: 500px; + margin: 20px auto; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); + color: black; +} +body { + text-align: center; + background: #3a3240; + color: white; +} +input, textarea, select, button { + background: #3a3240; + color: white; +} +a { + color: white; +} ``` diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/build-a-technical-documentation-page-project/build-a-technical-documentation-page.md b/curriculum/challenges/italian/14-responsive-web-design-22/build-a-technical-documentation-page-project/build-a-technical-documentation-page.md index 517d9685a23..6c433375ba7 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/build-a-technical-documentation-page-project/build-a-technical-documentation-page.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/build-a-technical-documentation-page-project/build-a-technical-documentation-page.md @@ -1,55 +1,525 @@ --- id: 587d78b0367417b2b2512b05 -title: Creare una pagina di documentazione tecnica -challengeType: 3 +title: Build a Technical Documentation Page +challengeType: 14 forumTopicId: 301146 dashedName: build-a-technical-documentation-page --- # --description-- -**Obiettivo:** Costuire un'app [CodePen.io](https://codepen.io) funzionalmente simile a questa: . +**Objective:** Build an app that is functionally similar to https://technical-documentation-page.freecodecamp.rocks -Soddisfa le seguenti [user story](https://en.wikipedia.org/wiki/User_story) e fai passare tutti i test. Usa il tuo stile personale. +**User Stories:** -Puoi utilizzare HTML, JavaScript, e CSS per completare questo progetto. CSS è raccomandato perché è l'argomento delle lezioni viste finora e dovresti fare pratica con il CSS di base. Se lo desideri puoi anche utilizzare Bootstrap o SASS. Ulteriori tecnologie (solo per fare un esempio jQuery, React, Angular, o Vue) non sono raccomandate per questo progetto, e usarle è a tuo rischio. Altri progetti ti daranno la possibilità di lavorare con diversi stack tecnologici come React. Accetteremo e cercheremo di risolvere tutte le segnalazioni di problemi che utilizzano lo stack tecnologico suggerito per questo progetto. Happy coding! +1. You can see a `main` element with a corresponding `id="main-doc"`, which contains the page's main content (technical documentation) +1. Within the `#main-doc` element, you can see several `section` elements, each with a class of `main-section`. There should be a minimum of five +1. The first element within each `.main-section` should be a `header` element, which contains text that describes the topic of that section. +1. Each `section` element with the class of `main-section` should also have an `id` that corresponds with the text of each `header` contained within it. Any spaces should be replaced with underscores (e.g. The section that contains the header "JavaScript and Java" should have a corresponding `id="JavaScript_and_Java"`) +1. The `.main-section` elements should contain at least ten `p` elements total (not each) +1. The `.main-section` elements should contain at least five `code` elements total (not each) +1. The `.main-section` elements should contain at least five `li` items total (not each) +1. You can see a `nav` element with a corresponding `id="navbar"` +1. The navbar element should contain one `header` element which contains text that describes the topic of the technical documentation +1. Additionally, the navbar should contain link (`a`) elements with the class of `nav-link`. There should be one for every element with the class `main-section` +1. The `header` element in the `#navbar` must come before any link (`a`) elements in the navbar +1. Each element with the class of `nav-link` should contain text that corresponds to the `header` text within each `section` (e.g. if you have a "Hello world" section/header, your navbar should have an element which contains the text "Hello world") +1. When you click on a navbar element, the page should navigate to the corresponding section of the `main-doc` element (e.g. If you click on a `nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id, and contains the corresponding header) +1. On regular sized devices (laptops, desktops), the element with `id="navbar"` should be shown on the left side of the screen and should always be visible to the user +1. Your technical documentation should use at least one media query -**User Story #1:** Posso vedere un elemento `main` con un corrispondente `id="main-doc"`, che contiene il contenuto principale della pagina (documentazione tecnica). +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**User story #2:** All'interno dell'elemento `#main-doc`, posso vedere diversi elementi `section`, ciascuno con una classe `main-section`. Dovrebbero essercene almeno 5. +# --hints-- -**User Story #3:** Il primo elemento all'interno di ogni `.main-section` dovrebbe essere un elemento `header` che contiene un testo che descrive l'argomento di quella sezione. +You should have a `main` element with an `id` of `main-doc` -**User Story #4:** Ogni elemento `section` con la classe `main-section` dovrebbe avere anche un id che corrisponde al testo di ogni `header` contenuto al suo interno. Qualsiasi spazio deve essere sostituito con un underscore (ad es. La sezione `section` che contiene l'intestazione "JavaScript e Java" dovrebbe avere un corrispondente `id="JavaScript_and_Java"`). +```js +const el = document.getElementById('main-doc') +assert(!!el) +``` -**User Story #5:** Gli elementi `.main-section` dovrebbero contenere almeno 10 elementi `p` in totale (non ciascuno). +You should have at least five `section` elements with a class of `main-section` -**User Story #6:** Gli elementi `.main-section` dovrebbero contenere almeno 5 elementi `code` in totale (non ciascuno). +```js +const els = document.querySelectorAll('#main-doc section') +assert(els.length >= 5) +``` -**User story #7:** Gli elementi `.main-section` dovrebbero contenere almeno 5 elementi `li` in totale (non ciascuno). +All of your `.main-section` elements should be `section` elements -**User story #8:** Posso vedere un elemento `nav` con un corrispondente `id="navbar"`. +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (el.tagName !== 'SECTION') assert(false) +}) +assert(els.length > 0) +``` -**User Story #9:** L'elemento navbar dovrebbe contenere un elemento `header` che contiene del testo che descrive l'argomento della documentazione tecnica. +You should have at least five `.main-section` elements that are descendants of `#main-doc` -**User story #10:** Inoltre, la barra di navigazione dovrebbe contenere degli elementi link (`a`) con la classe `nav-link`. Dovrebbe essercene uno per ogni elemento di classe `main-section`. +```js +const els = document.querySelectorAll('#main-doc .main-section') +assert(els.length >= 5) +``` -**User story #11:** L'elemento `header` nella barra di navigazione deve venire prima di qualsiasi elemento link (`a`) nella barra di navigazione. +The first child of each `.main-section` should be a `header` element -**User story #12:** Ogni elemento di classe `nav-link` dovrebbe contenere un testo che corrisponde al testo `header` di ogni `section` (ad es. se hai una sezione/intestazione "Ciao mondo", la tua barra di navigazione dovrebbe avere un elemento che contiene il testo "Ciao mondo"). +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if(el.firstElementChild?.tagName !== 'HEADER') assert(false) +}) +assert(els.length > 0) +``` -**User story #13:** Quando clicco su un elemento della barra di navigazione, la pagina dovrebbe passare alla sezione corrispondente dell'elemento `main-doc` (ad es. se clicco su un elemento `nav-link` che contiene il testo "Ciao mondo", la pagina passa a un elemento `section` che ha quell'id e contiene il corrispondente `header`. +None of your `header` elements should be empty -**User story #14:** Su dispositivi di dimensioni regolari (computer portatili, desktop), l'elemento con `id="navbar"` dovrebbe essere mostrato sul lato sinistro dello schermo e dovrebbe essere sempre visibile all'utente. +```js +const els = document.querySelectorAll('header') +els.forEach(el => { + if (el.innerText?.length <= 0) assert(false) +}) +assert(els.length > 0) +``` -**User story #15:** La pagina Documentazione Tecnica dovrebbe utilizzare almeno una media query. +All of your `.main-section` elements should have an `id` -Puoi costruire il tuo progetto usando questo modello CodePen e cliccando `Save` per creare il tuo pen. Oppure puoi usare questo link CDN per eseguire i test in qualsiasi ambiente tu voglia: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (!el.id || el.id === '') assert(false) +}) +assert(els.length > 0) +``` -Una volta fatto, invia l'URL al tuo progetto di lavoro con tutti i suoi test passati. +Each `.main-section` should have an `id` that matches the text of its first child, having any spaces in the child's text replaced with underscores (`_`) for the id’s -# --solutions-- +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + const text = el.firstElementChild?.innerText?.replaceAll(' ', '_') + if (el.id?.toUpperCase() !== text?.toUpperCase()) assert(false) +}) +assert(els.length > 0) +``` + +You should have at least 10 `p` elements (total) within your `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section p') +assert(els.length >= 10) +``` + +You should have at least five `code` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section code') +assert(els.length >= 5) +``` + +You should have at least five `li` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section li') +assert(els.length >= 5) +``` + +You should have a `nav` element with an `id` of `navbar` + +```js +const el = document.getElementById('navbar') +assert(!!el && el.tagName === 'NAV') +``` + +Your `#navbar` should have exactly one `header` element within it + +```js +const els = document.querySelectorAll('#navbar header') +assert(els.length === 1) +``` + +You should have at least one `a` element with a class of `nav-link` + +```js +const els = document.querySelectorAll('a[class="nav-link"]') +assert(els.length >= 1) +``` + +All of your `.nav-link` elements should be anchor (`a`) elements + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (el.tagName !== 'A') assert(false) +}) +assert(els.length > 0) +``` + +All of your `.nav-link` elements should be in the `#navbar` + +```js +const els1 = document.querySelectorAll('.nav-link') +const els2 = document.querySelectorAll('#navbar .nav-link') +assert(els2.length > 0 && els1.length === els2.length) +``` + +You should have the same number of `.nav-link` and `.main-section` elements + +```js +const els1 = document.querySelectorAll('.main-section') +const els2 = document.querySelectorAll('.nav-link') +assert(els1.length > 0 && els2.length > 0 && els1.length === els2.length) +``` + +The `header` element in the `#navbar` should come before any link (`a`) elements also in the `#navbar` + +```js +const navLinks = document.querySelectorAll('#navbar a.nav-link'); +const header = document.querySelector('#navbar header'); +navLinks.forEach((navLink) => { + if ( + ( + header.compareDocumentPosition(navLink) & + Node.DOCUMENT_POSITION_PRECEDING + ) + ) assert(false) +}); +assert(!!header) +``` + +Each `.nav-link` should have text that corresponds to the `header` text of its related `section` (e.g. if you have a "Hello world" section/header, your `#navbar` should have a `.nav-link` which has the text "Hello world") + +```js +const headerText = Array.from(document.querySelectorAll('.main-section')).map(el => + el.firstElementChild?.innerText?.trim().toUpperCase() +) +const linkText = Array.from(document.querySelectorAll('.nav-link')).map(el => + el.innerText?.trim().toUpperCase() +) +const remainder = headerText.filter(str => linkText.indexOf(str) === -1) +assert(headerText.length > 0 && headerText.length > 0 && remainder.length === 0) +``` + +Each `.nav-link` should have an `href` attribute that links to its corresponding `.main-section` (e.g. If you click on a `.nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id) + +```js +const hrefValues = Array.from(document.querySelectorAll('.nav-link')).map(el => el.getAttribute('href')) +const mainSectionIDs = Array.from(document.querySelectorAll('.main-section')).map(el => el.id) +const missingHrefValues = mainSectionIDs.filter(str => hrefValues.indexOf('#' + str) === -1) +assert(hrefValues.length > 0 && mainSectionIDs.length > 0 && missingHrefValues.length === 0) +``` + +Your `#navbar` should always be on the left edge of the window + +```js +const el = document.getElementById('navbar') +const left1 = el?.offsetLeft +const left2 = el?.offsetLeft +assert(!!el && left1 >= -15 && left1 <= 15 && left2 >= -15 && left2 <= 15) +``` + +Your Technical Documentation project should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Technical Documentation Page + + + +
+
+
Introduction
+

+ Welcome to a basic introduction of algebra. In this tutorial, we will + review some of the more common algebraic concepts. +

+
+
+
Definitions
+

+ To start with, let's define some of the more common terms used in + algebra: +

+
    +
  • + Variable: A variable is an unknown value, usually represented + by a letter. +
  • +
  • + Expression: Essentially a mathematical object. For the + purpose of this tutorial, an expression is one part of an equation. +
  • +
  • + Equation: An equation is a mathematical argument in which two + expressions result in the same value. +
  • +
+
+
+
Examples
+

+ Sometimes it is easier to understand the definitions when you have a + physical example to look at. Here is an example of the above terms.

+ x + 5 = 12

+ In this above example, we have: +

+
    +
  • Variable: The variable in the example is "x".
  • +
  • + Expression: There are two expressions in this example. They + are "x+5" and "12". +
  • +
  • + Equation: The entire example, "x+5=12", is an equation. +
  • +
+
+
+
Solving Equations
+

+ The primary use for algebra is to determine an unknown value, the + "variable", with the information provided. Continuing to use our + example from above, we can find the value of the variable "x".

+ x + 5 = 12

+ In an equation, both sides result in the same value. So you can + manipulate the two expressions however you need, as long as you + perform the same operation (or change) to each side. You do this + because the goal when solving an equation is to + get the variable into its own expression, or by itself on one side + of the = sign.
For this example, we want to remove the "+5" so the "x" is + alone. To do this, we can subtract 5, because subtraction is + the opposite operation to addition. But remember, we have to perform + the same operation to both sides of the equation. Now our equation + looks like this.

+ x + 5 - 5 = 12 - 5

+ The equation looks like a mess right now, because we haven't completed + the operations. We can simplify this equation to make it easier + to read by performing the operations "5-5" and "12-5". The result + is:

+ x = 7

+ We now have our solution to this equation! +

+
+
+
Solving Equations II
+

+ Let us look at a slightly more challenging equation.

+ 3x + 4 = 13

+ Again we can start with subtraction. In this case, we want to subtract + 4 from each side of the equation. We will also go ahead and simplify + with each step. So now we have:

+ 3x = 9

+ "3x" translates to "3*x", where the "*" symbol indicates + multiplication. We use the "*" to avoid confusion, as the "x" is now a + variable instead of a multiplication symbol. The opposite operation + for multiplication is division, so we need to + divide each expression by 3.

+ x = 3

+ And now we have our solution! +

+
+
+
Solving Equations III
+

+ Now we are getting in to more complex operations. Here is another + equation for us to look at:

+ x^2 - 8 = 8

+ Our very first step will be to add 8 to each side. This is + different from our previous examples, where we had to subtract. But + remember, our goal is to get the variable alone by performing opposite + operations.

+ x^2 = 16

+ But what does the "^2" mean? The "^" symbol is used to denote + exponents in situations where superscript is not available. When + superscript is available, you would see it as x2. + For the sake of this project, however, we will use the "^" symbol.
+ An exponent tells you how many times the base (in our case, "x") is + multiplied by itself. So, "x^2" would be the same as "x*x". Now the + opposite function of multiplication is division, but we would have to + divide both sides by "x". We do not want to do this, as that + would put an "x" on the other side of the equation. So instead, we + need to use the root operation! For an exponent of "2", we call this + the "square root" and denote it with "√". Our equation is now: +

+ x = √9

+ Performing a root operation by hand can be a tedious process, so we + recommend using a calculator when necessary. However, we are lucky in + that "9" is a + perfect square, so we do not need to calculate anything. Instead, we find our + answer to be:

+ x = 3 +

+
+
+
System of Equations
+

+ As you explore your algebra studies further, you may start to run + across equations with more than one variable. The first such equations + will likely look like:

+ y = 3x

+ An equation like this does not have one single solution. + Rather, there are a series of values for which the equation is true. + For example, if "x=3" and "y=9", the equation is true. These equations + are usually used to plot a graph.
+ Getting more complicated, though, you may be given a pair of + equations. This is called a "system of equations", and CAN be solved. + Let's look at how we do this! Consider the following system of + equations:

+ y = 3x | y - 6 = x + A system of equations IS solvable, but it is a multi-step process. To + get started, we need to chose a variable we are solving for. Let's + solve for "x" first. From the second equation, we know that "x" equals + "y - 6", but we cannot simplify that further because we do not have a + value for "y". Except, thanks to the system of equations, we DO have a + value for "y". We know that "y" equals "3x". So, looking at our second + equation, we can replace "y" with "3x" because they have the same + value. We then get:

+ 3x - 6 = x

+ Now we can solve for "x"! We start by adding 6 to each side.

+ 3x = x + 6

+ We still need to get "x" by itself, so we subtract "x" from both sides + and get:

+ 2x = 6

+ If this confuses you, remember that "3x" is the same as "x+x+x". + Subtract an "x" from that and you get "x+x", or "2x". Now we divide + both sides by 2 and have our value for x!

+ x = 3

+ However, our work is not done yet. We still need to find the value for + "y". Let's go back to our first equation:

+ y = 3x

+ We have a value for "x" now, so let's see what happens if we put that + value in.

+ y = 3*3

+ We perform the multiplication and discover that "y=9"! Our solution to + this system of equations then is:

+ x = 3 and y = 9

+

+
+
+
Try it Yourself!
+

Coming Soon!

+

Keep an eye out for new additions!

+
+
+
More Information
+

Check out the following links for more information!

+ +
+
+ + + +``` + +```css +* { + background-color: #3a3240; +} +a { + color: #92869c; +} +a:hover { + background-color: #92869c; + color: #3a3240; +} +#navbar { + border-style: solid; + border-width: 5px; + border-color: #92869c; + height: 100%; + top: -5px; + left: -5px; + padding: 5px; + text-align: center; + color: #92869c +} +@media (min-width: 480px) { + #navbar { + position: fixed; + } +} +main { + margin-left: 220px; + color: #92869c +} +header { + font-size: 20pt; +} +code { + background-color: #92869c; + border-style: dashed; + border-width: 2px; + border-color: #92869c; + padding: 5px; + color: black; +} +footer { + text-align: center; +} ``` diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/build-a-tribute-page-project/build-a-tribute-page.md b/curriculum/challenges/italian/14-responsive-web-design-22/build-a-tribute-page-project/build-a-tribute-page.md index 64d3a3d987c..231292b4373 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/build-a-tribute-page-project/build-a-tribute-page.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/build-a-tribute-page-project/build-a-tribute-page.md @@ -1,43 +1,327 @@ --- id: bd7158d8c442eddfaeb5bd18 -title: Crea una pagina di tributo -challengeType: 3 +title: Build a Tribute Page +challengeType: 14 forumTopicId: 301147 dashedName: build-a-tribute-page --- # --description-- -**Obiettivo:** Costruisci un'app [CodePen.io](https://codepen.io) funzionalmente simile a questa: . +**Objective:** Build an app that is functionally similar to https://tribute-page.freecodecamp.rocks -Soddisfa le seguenti [user story](https://en.wikipedia.org/wiki/User_story) e fai passare tutti i test. Usa il tuo stile personale. +**User Stories:** -Puoi utilizzare HTML, JavaScript, e CSS per completare questo progetto. CSS è raccomandato perché è l'argomento delle lezioni viste finora e dovresti fare pratica con il CSS di base. Se lo desideri puoi anche utilizzare Bootstrap o SASS. Ulteriori tecnologie (solo per fare un esempio jQuery, React, Angular, o Vue) non sono raccomandate per questo progetto, e usarle è a tuo rischio. Altri progetti ti daranno la possibilità di lavorare con diversi stack tecnologici come React. Accetteremo e cercheremo di risolvere tutte le segnalazioni di problemi che utilizzano lo stack tecnologico suggerito per questo progetto. Happy coding! +1. Your tribute page should have an element with a corresponding `id="main"`, which contains all other elements +1. You should see an element with an `id` of `title`, which contains a string (i.e. text), that describes the subject of the tribute page (e.g. "Dr. Norman Borlaug") +1. You should see either a `figure` or a `div` element with an `id` of `img-div` +1. Within the `img-div` element, you should see an `img` element with a corresponding `id="image"` +1. Within the `img-div` element, you should see an element with a corresponding `id="img-caption"` that contains textual content describing the image shown in `img-div` +1. You should see an element with a corresponding `id="tribute-info"`, which contains textual content describing the subject of the tribute page +1. You should see an a element with a corresponding `id="tribute-link"`, which links to an outside site, that contains additional information about the subject of the tribute page. HINT: You must give your element an attribute of `target` and set it to `_blank` in order for your link to open in a new tab +1. Your `#image` should use `max-width` and `height` properties to resize responsively, relative to the width of its parent element, without exceeding its original size +1. Your `img` element should be centered within its parent element -**User story #1:** La mia pagina di tributo dovrebbe avere un elemento con un corrispondente `id="main"`che contiene tutti gli altri elementi. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**User Story #2:** Dovrei vedere un elemento con un corrispondente `id="title"`che contiene una stringa (cioè un testo) che descrive l'oggetto della pagina di tributo (ad esempio "Dr. Norman Borlaug"). +# --hints-- -**User story #3:** Dovrei vedere un elemento `figure` oppure un elemento `div` con un corrispondente `id="img-div"`. +You should have a `main` element with an `id` of `main` -**User story #4:** All'interno dell'elemento `img-div`, dovrei vedere un elemento `img` con un corrispondente `id="image"`. +```js +const el = document.getElementById('main') +assert(!!el && el.tagName === 'MAIN') +``` -**User story #5:** All'interno dell'elemento `img-div`, dovrei vedere un elemento con un corrispondente `id="img-caption"` che contiene un testo che descrive l'immagine mostrata in `img-div`. +Your `#img-div`, `#image`, `#img-caption`, `#tribute-info`, and `#tribute-link` should all be descendants of `#main` -**User Story #6:** Dovrei vedere un elemento con un corrispondente `id="tribute-info"`, che contiene dei testi che descrivono l'oggetto della pagina di tributo. +```js +const el1 = document.querySelector('#main #img-div') +const el2 = document.querySelector('#main #image') +const el3 = document.querySelector('#main #img-caption') +const el4 = document.querySelector('#main #tribute-info') +const el5 = document.querySelector('#main #tribute-link') +assert(!!el1 & !!el2 && !!el3 && !!el4 && !!el5) +``` -**User story #7:** Dovrei vedere un elemento `a` con un corrispondente `id="tribute-link"`, che si collega a un sito esterno che contiene ulteriori informazioni sull'oggetto della pagina di tributo. SUGGERIMENTO: Dovresti dare al tuo elemento un attributo `target` e impostarlo a `_blank` in modo che il link si apra in una nuova scheda (`target="_blank"`). +You should have an element with an `id` of `title` -**User story #8:** L'elemento `img` dovrebbe ridimensionarsi responsivamente, rispetto alla larghezza dell'elemento principale, senza superare la dimensione originale. +```js +const el = document.getElementById('title') +assert(!!el) +``` -**User story #9:** L'elemento `img` dovrebbe essere centrato all'interno del suo elemento genitore. +Your `#title` should not be empty -Puoi costruire il tuo progetto usando questo modello CodePen e facendo clic su `Save` per creare il tuo pen. Oppure puoi usare questo link CDN per eseguire i test in qualsiasi ambiente tu voglia: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`. +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) -Una volta fatto, invia l'URL del tuo progetto di lavoro con tutti i suoi test passati. +``` -# --solutions-- +You should have a `figure` or `div` element with an `id` of `img-div` + +```js +const el = document.getElementById('img-div') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGURE')) +``` + +You should have an `img` element with an `id` of `image` + +```js +const el = document.getElementById('image') +assert(!!el && el.tagName === 'IMG') +``` + +Your `#image` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #image') +assert(!!el) +``` + +You should have a `figcaption` or `div` element with an `id` of `img-caption` + +```js +const el = document.getElementById('img-caption') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGCAPTION')) +``` + +Your `#img-caption` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #img-caption') +assert(!!el) +``` + +Your `#img-caption` should not be empty + +```js +const el = document.getElementById('img-caption') +assert(!!el && el.innerText.length > 0) +``` + +You should have an element with an `id` of `tribute-info` + +```js +const el = document.getElementById('tribute-info') +assert(!!el) +``` + +Your `#tribute-info` should not be empty + +```js +const el = document.getElementById('tribute-info') +assert(!!el && el.innerText.length > 0) +``` + +You should have an `a` element with an `id` of `tribute-link` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.tagName === 'A') +``` + +Your `#tribute-link` should have an `href` attribute and value + +```js +const el = document.getElementById('tribute-link') +assert(!!el && !!el.href && el.href.length > 0) +``` + +Your `#tribute-link` should have a `target` attribute set to `_blank` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.target === '_blank') +``` + +You should use an `#image` selector in your CSS to style the `#image` and pass the next three tests + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image') +assert(!!style) +``` + +Your `#image` should have a `display` of `block` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +assert(style === 'block') +``` + +Your `#image` should have a `max-width` of `100%` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +assert(style === '100%') +``` + +Your `#image` should have a `height` of `auto` + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'); +const maxWidthValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +const displayValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +const oldDisplayValue = img?.style.getPropertyValue('display'); +const oldDisplayPriority = img?.style.getPropertyPriority('display'); +img?.style.setProperty('display', 'none', 'important'); +const heightValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('height') +img?.style.setProperty('display', oldDisplayValue, oldDisplayPriority); +assert(heightValue === 'auto') +``` + +Your `#image` should be centered within its parent + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'), + imgParent = img?.parentElement, + imgLeft = img?.getBoundingClientRect().left, + imgRight = img?.getBoundingClientRect().right, + parentLeft = imgParent?.getBoundingClientRect().left, + parentRight = imgParent?.getBoundingClientRect().right, + leftMargin = imgLeft - parentLeft, + rightMargin = parentRight - imgRight; +assert(leftMargin - rightMargin < 6 && rightMargin - leftMargin < 6) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + + + Tribute Page + + +

Tribute Page

+

The below card was designed as a tribute page for freeCodeCamp.

+
+
+ An image of Togepi +
Togepi, happy as always.
+
+

Togepi

+
+
+

+ Togepi was first discovered in the Johto region, when Ash Ketchum + discovered a mysterious egg. However, when the egg hatched, Togepi saw + Ash's friend Misty first and imprinted on her. Like many other + creatures, this imprinting process created a bond and Togepi views + Misty as his mother. +

+

+ Togepi is a very childlike Pokemon, and is very emotionally + expressive. He demonstrates extreme levels of joy and sadness. +

+
+

Battle Information

+
    +
  • Type: Fairy
  • +
  • Evolutions: Togepi -> Togetic -> Togekiss
  • +
  • Moves: Growl, Pound, Sweet Kiss, Charm
  • +
  • Weaknesses: Poison, Steel
  • +
  • Resistances: Dragon
  • +
+

+ Check out this + Bulbapedia article on Togepi + for more information on this great Pokemon. +

+
+
+ + + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + background-color: #92869c; + font-family: Lobster; + max-width: 500px; + margin: 20px auto; + color: black; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); +} +h2 { + text-align: center; + font-size: 20pt; + font-family: Pacifico; +} +body { + text-align: center; + font-size: 12pt; +} +footer { + text-align: center; + font-size: 10pt; +} +.border { + border-color: black; + border-width: 5px; + border-style: solid; +} +#image { + height: auto; + display: block; + margin: auto; + max-width: 100%; + border-radius: 50%; +} +#img-caption { + font-size: 10pt; +} +a:not(#tribute-link) { + color: white; +} +hr { + border-color: black; +} ``` diff --git a/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md b/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md index 611422a549d..0226992eec9 100644 --- a/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md +++ b/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md @@ -1,47 +1,277 @@ --- id: bd7158d8c242eddfaeb5bd13 -title: 個人ポートフォリオのウェブページを作成する -challengeType: 3 +title: Build a Personal Portfolio Webpage +challengeType: 14 forumTopicId: 301143 dashedName: build-a-personal-portfolio-webpage --- # --description-- -**目標:** こちら と同様の機能を持つ [CodePen.io](https://codepen.io) アプリを構築します。 +**Objective:** Build an app that is functionally similar to https://personal-portfolio.freecodecamp.rocks -以下の[ユーザーストーリー](https://en.wikipedia.org/wiki/User_story)を満たし、すべてのテストがパスするようにしてください。 あなた独自のスタイルを与えてください。 +**User Stories:** -このプロジェクトを完了するために、HTML、JavaScript、CSS を使用することができます。 これまでのレッスンでカバーされた純粋な CSS の練習をするため、純粋な CSS の使用を推奨します。 Bootstrap や SASS を使用しても構いません。 このプロジェクトで追加のテクノロジー (jQuery、React、Angular、Vue など) を使用することは推奨されません。使用する場合は自己責任で使用してください。 React のようなさまざまな技術スタックで作業する機会は他のプロジェクトで得られます。 このプロジェクトで推奨される一連のテクノロジーを使用している場合の不具合報告については、freeCodeCamp にて報告を受け入れ、修正するよう努めます。 ハッピーコーディング! +1. Your portfolio should have a welcome section with an `id` of `welcome-section` +1. The welcome section should have an `h1` element that contains text +1. Your portfolio should have a projects section with an `id` of `projects` +1. The projects section should contain at least one element with a `class` of `project-tile` to hold a project +1. The projects section should contain at least one link to a project +1. Your portfolio should have a navbar with an id of `navbar` +1. The navbar should contain at least one link that you can click on to navigate to different sections of the page +1. Your portfolio should have a link with an id of `profile-link`, which opens your GitHub or freeCodeCamp profile in a new tab +1. Your portfolio should have at least one media query +1. The height of the welcome section should be equal to the height of the viewport +1. The navbar should always be at the top of the viewport -**ユーザーストーリー #1:** 私のポートフォリオには、`welcome-section` の id を持つウェルカムセクションがあります。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**ユーザーストーリー #2:** ウェルカムセクションにはテキストを含む `h1` 要素があります。 +# --hints-- -**ユーザーストーリー #3:** 私のポートフォリオには、`projects` の id を持つプロジェクトセクションがあります。 +Your portfolio should have a "Welcome" section with an `id` of `welcome-section`. -**ユーザーストーリー #4:** プロジェクトセクションには、プロジェクトを入れるために少なくとも 1 つの `project-tile` クラスの要素があります。 +```js +const el = document.getElementById('welcome-section') +assert(!!el); +``` -**ユーザーストーリー #5:** プロジェクトセクションには、少なくとも 1 つのプロジェクトへのリンクが含まれている必要があります。 +Your `#welcom-section` element should contain an `h1` element. -**ユーザーストーリー #6:** 私のポートフォリオには、 `navbar` の id を持つナビゲーションバーがあります。 +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1').length, + 0, + 'Welcome section should contain an h1 element ' +); +``` -**ユーザーストーリー #7:** ナビゲーションバーには、クリックするとページ上の異なるセクションに移動できるリンクが少なくとも 1 つあります。 +You should not have any empty `h1` elements within `#welcome-section` element. -**ユーザーストーリー #8:** 私のポートフォリオには `profile-link`の id を持つリンクがあり、GitHub または FCC プロフィールを新しいタブで開くことができます。 +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1')?.[0]?.innerText?.length, + 0, + 'h1 element in welcome section should contain your name or camper ' + + 'name ' +); +``` -**ユーザーストーリー #9:** 私のポートフォリオには、少なくとも 1 つのメディアクエリがあります。 +You should have a "Projects" section with an `id` of `projects`. -**ユーザーストーリー #10:** ウェルカムセクションの高さはビューポートの高さと等しくなければなりません。 +```js +const el = document.getElementById('projects') +assert(!!el); +``` -**ユーザーストーリー #11:** ナビゲーションバーは常にビューポートの上部に表示されている必要があります。 +Your portfolio should contain at least one elment with a class of `project-tile`. -この CodePen テンプレートを使用してあなたのプロジェクトを構築することができます。`Save` をクリックすると、あなた用の pen を作成することができます。 または、この CDN リンクを使用して任意の環境でテストを実行できます: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +assert.isAbove( + document.querySelectorAll('#projects .project-tile').length, + 0 +); +``` -完了したら、すべてのテストがパスする状態の作業プロジェクトの URL を送信します。 +Your `#projects` element should contain at least one `a` element. -# --solutions-- +```js +assert.isAbove(document.querySelectorAll('#projects a').length, 0); +``` + +Your portfolio should have a navbar with an `id` of `navbar`. + +```js +const el = document.getElementById('navbar'); +assert(!!el); +``` + +Your `#navbar` element should contain at least one `a` element whose `href` attribute starts with `#`. + +```js +const links = [...document.querySelectorAll('#navbar a')].filter( + (nav) => (nav?.getAttribute('href') || '').substr(0, 1) === '#' +); + +assert.isAbove( + links.length, + 0, + 'Navbar should contain an anchor link ' +); +``` + +Your portfolio should have an `a` element with an `id` of `profile-link`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.tagName === 'A') +``` + +Your `#profile-link` element should have a `target` attribute of `_blank`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.target === '_blank') +``` + +Your portfolio should use at least one media query. + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your `#navbar` element should always be at the top of the viewport. + +```js +(async () => { + const timeout = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)); + + const navbar = document.getElementById('navbar'); + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + "Navbar's parent should be body and it should be at the top of " + + 'the viewport ' + ); + + window.scroll(0, 500); + + await timeout(1); + + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + 'Navbar should be at the top of the viewport even after ' + + 'scrolling ' + ); + window.scroll(0, 0); +})(); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Personal Portfolio + + + + + +
+
+
+

It's me!

+ +

Naomi Carrigan

+

Welcome to my portfolio page!

+

+
+

Projects

+

Here's what I've worked on!

+

+ + + + +


+
+

Contact me!

+

Use the links below to get in touch.

+

FreeCodeCamp.org | GitHub | Facebook | LinkedIn +

+ + + +``` + +```css +nav{ + position: fixed; + width: 100%; + text-align: right; + font-size: 24pt; + top: 0%; + right: 5px; + background-color: #000000; + color: #ffffff; +} +@media (max-width: 500px){ + nav{ + display: none; + } +} +a{ + color: #ffffff; +} +main{ + text-align: center; + background-color: black; + font-family:Pacifico +} +h1{ + font-size: 48pt; +} +h2{ + font-size: 24pt; +} +p{ + font-size: 12pt; +} +#welcome-section{ + background-color:#251a4a; + color: #FFFFFF; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#projects{ + background-color: #060a9c; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#contact{ + background-color: #03300b; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} ``` diff --git a/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md b/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md index b443b7e4257..cdd62359751 100644 --- a/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md +++ b/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md @@ -1,55 +1,424 @@ --- id: 587d78af367417b2b2512b04 -title: プロダクトのランディングページを作成する -challengeType: 3 +title: Build a Product Landing Page +challengeType: 14 forumTopicId: 301144 dashedName: build-a-product-landing-page --- # --description-- -**目標:** こちら と同様の機能を持つ [CodePen.io](https://codepen.io) アプリを構築します。 +**Objective:** Build an app that is functionally similar to https://product-landing-page.freecodecamp.rocks -以下の[ユーザーストーリー](https://en.wikipedia.org/wiki/User_story)を満たし、すべてのテストがパスするようにしてください。 あなた独自のスタイルを与えてください。 +**User Stories:** -このプロジェクトを完了するために、HTML、JavaScript、CSS を使用することができます。 これまでのレッスンでカバーされた純粋な CSS の練習をするため、純粋な CSS の使用を推奨します。 Bootstrap や SASS を使用しても構いません。 このプロジェクトで追加のテクノロジー (jQuery、React、Angular、Vue など) を使用することは推奨されません。使用する場合は自己責任で使用してください。 React のようなさまざまな技術スタックで作業する機会は他のプロジェクトで得られます。 このプロジェクトで推奨される一連のテクノロジーを使用している場合の不具合報告については、freeCodeCamp にて報告を受け入れ、修正するよう努めます。 ハッピーコーディング! +1. Your product landing page should have a `header` element with a corresponding `id="header"` +1. You can see an image within the `header` element with a corresponding `id="header-img"` (A logo would make a good image here) +1. Within the `#header` element, you can see a `nav` element with a corresponding `id="nav-bar"` +1. You can see at least three clickable elements inside the `nav` element, each with the class `nav-link` +1. When you click a `.nav-link` button in the `nav` element, you are taken to the corresponding section of the landing page +1. You can watch an embedded product video with `id="video"` +1. Your landing page has a `form` element with a corresponding `id="form"` +1. Within the form, there is an `input` field with `id="email"` where you can enter an email address +1. The `#email` input field should have placeholder text to let users know what the field is for +1. The `#email` input field uses HTML5 validation to confirm that the entered text is an email address +1. Within the form, there is a submit `input` with a corresponding `id="submit"` +1. When you click the `#submit` element, the email is submitted to a static page (use this mock URL: `https://www.freecodecamp.com/email-submit`) +1. The navbar should always be at the top of the viewport +1. Your product landing page should have at least one media query +1. Your product landing page should utilize CSS flexbox at least once -**ユーザーストーリー #1:** 私のプロダクトランディングページには `id="header"` を持つ `header` 要素があります。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**ユーザーストーリー #2:** `header` 要素内には `id="header-img"` を持つ画像が表示されます。 会社のロゴがあればここでいいイメージを与えることができるでしょう。 +# --hints-- -**ユーザーストーリー #3:** `#header` 要素内に `id="nav-bar"` を持つ `nav` 要素があります。 +You should have a `header` element with an `id` of `header` -**ユーザーストーリー #4:** `nav` 要素内に少なくとも 3 つのクリック可能な `nav-link` クラスの要素があります。 +```js +const el = document.getElementById('header') +assert(!!el && el.tagName === 'HEADER') +``` -**ユーザーストーリー #5:** `nav` 要素内の `.nav-link` ボタンをクリックしたら、ランディングページの対応するセクションに移動します。 +You should have an `img` element with an `id` of `header-img` -**ユーザーストーリー #6:** `id="video"` を持つプロダクトの埋め込み動画を見ることができます。 +```js +const el = document.getElementById('header-img') +assert(!!el && el.tagName === 'IMG') +``` -**ユーザーストーリー #7:** 私のランディングページには `id="form"` を持つ `form` 要素があります。 +Your `#header-img` should be a descendant of the `#header` -**ユーザーストーリー #8:** フォーム内には、Eメールアドレスが入力可能な `id="email"` を持つ `input` フィールドがあります。 +```js +const els = document.querySelectorAll('#header #header-img') +assert(els.length > 0) +``` -**ユーザーストーリー #9:** `#email` 入力フィールドには、フィールドの用途をユーザーに知らせるためのプレイスホルダ―テキストが必要です。 +Your `#header-img` should have a `src` attribute -**ユーザーストーリー #10:** `#email` 入力フィールドは、入力されたテキストがメールアドレスであるか確認するために HTML5 のバリデーションを使用します。 +```js +const el = document.getElementById('header-img') +assert(!!el && !!el.src) +``` -**ユーザーストーリー #11:** フォーム内には、`id="submit"` を持つ送信ボタンの `input` があります。 +Your `#header-img`’s `src` value should be a valid URL (starts with `http`) -**ユーザーストーリー #12:** `#submit` 要素をクリックすると、email の情報が静的ページに送信されます (このモック URL を使用してください: )。 +```js +const el = document.getElementById('header-img') +assert(!!el && /^http/.test(el.src)) +``` -**ユーザーストーリー #13:** ナビゲーションバーは常にビューポートの上部に表示されている必要があります。 +You should have a `nav` element with an `id` of `nav-bar` -**ユーザーストーリー #14:** 私のプロダクトランディングページには、少なくとも 1 つのメディアクエリがあります。 +```js +const el = document.getElementById('nav-bar') +assert(!!el && el.tagName === 'NAV') +``` -**ユーザーストーリー #15:** 私のプロダクトランディングページは、少なくとも 1 つの CSS フレックスボックスを使用しています。 +Your `#nav-bar` should be a descendant of the `#header` -この CodePen テンプレートを使用してあなたのプロジェクトを構築することができます。`Save` をクリックすると、あなた用の pen を作成することができます。 または、この CDN リンクを使用して任意の環境でテストを実行できます: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +const els = document.querySelectorAll('#header #nav-bar') +assert(els.length > 0) +``` -完了したら、すべてのテストがパスする状態の作業プロジェクトの URL を送信します。 +You should have at least 3 `.nav-link` elements within the `#nav-bar` -# --solutions-- +```js +const els = document.querySelectorAll('#nav-bar .nav-link') +assert(els.length >= 3) +``` + +Each `.nav-link` element should have an `href` attribute + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (!el.href) assert(false) +}) +assert(els.length > 0) +``` + +Each `.nav-link` element should link to a corresponding element on the landing page (has an `href` with a value of another element's id. e.g. `#footer`) + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + const linkDestination = el.getAttribute('href').slice(1) + if (!document.getElementById(linkDestination)) assert(false) +}) +assert(els.length > 0) +``` + +You should have a `video` or `iframe` element with an `id` of `video` + +```js +const el = document.getElementById('video') +assert(!!el && (el.tagName === 'VIDEO' || el.tagName === 'IFRAME')) +``` + +Your `#video` should have a `src` attribute + +```js +const el = document.getElementById('video') +assert(!!el && !!el.src) +``` + +You should have a `form` element with an `id` of `form` + +```js +const el = document.getElementById('form') +assert(!!el && el.tagName === 'FORM') +``` + +You should have an `input` element with an `id of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #email') +assert(els.length > 0) +``` + +Your `#email` should have the `placeholder` attribute with placeholder text + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should use HTML5 validation by setting its `type` to `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +You should have an `input` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#submit` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #submit') +assert(els.length > 0) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#form` should have an `action` attribute of `https://www.freecodecamp.com/email-submit` + +```js +const el = document.getElementById('form') +assert(!!el && el.action === 'https://www.freecodecamp.com/email-submit') +``` + +Your `#email` should have a `name` attribute of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.name === 'email') +``` + +Your `#nav-bar` should always be at the top of the viewport + +```js +const el = document.getElementById('nav-bar') +const top1 = el?.offsetTop +const top2 = el?.offsetTop +assert(!!el && top1 >= -15 && top1 <= 15 && top2 >= -15 && top2 <= 15) +``` + +Your Product Landing Page should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your Product Landing Page should use CSS Flexbox at least once + +```js +const stylesheet = new __helpers.CSSHelp(document).getStyleSheet() +const cssRules = new __helpers.CSSHelp(document).styleSheetToCssRulesArray(stylesheet) +const usesFlex = cssRules.find(rule => { + return rule.style?.display === 'flex' || rule.style?.display === 'inline-flex' +}) +assert(usesFlex) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Product Landing Page + + + +
+

+ Pokemon Daycare Service +

+
+

What we offer

+
+
+ +
+
Guaranteed friendly and loving staff!
+
+
+
+ +
+
+ Comfortable environment for Pokemon to explore and play! +
+
+
+
+ +
+
+ Multiple membership plans to fit your lifestyle! +
+
+
+
+

Check us out!

+ A sneak peek into our facility: +
+ +
+
+

Membership Plans

+
+
+ Basic Membership
+
    +
  • One Pokemon
  • +
  • Food and berries provided
  • +
+ $9.99/month +
+
+ Silver Membership
+
    +
  • Up to Three Pokemon
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
+ $19.99/month +
+
+ Gold Membership
+
    +
  • Up to six Pokemon!
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
  • Personal training for each Pokemon
  • +
  • Breeding and egg hatching
  • +
+ $29.99/month +
+
+
+
+

Sign up for our newsletter!

+ + +
+ +
+ + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + max-width: 750px; + margin: 50px auto; +} +input { + background-color: #92869c; +} +a:not(.nav-link) { + color: white; +} +#header-img { + max-height: 25px; +} +#nav-bar { + position: fixed; + width: 100%; + text-align: center; + top: 0%; + background-color: #92869c; +} +h1 { + text-align: center; +} +body { + text-align: center; +} +footer { + text-align: center; +} +#bullet { + max-height: 25px; +} +.flex-here { + display: flex; + justify-content: center; +} +.flex-left { + height: 25px; +} +.flex-mem { + display: flex; + justify-content: center; +} +.flex-mem-box { + background-color: #92869c; + border-color: black; + border-width: 5px; + border-style: solid; + margin: 10px; + padding: 10px; + color: black; +} +@media (max-width: 350px) { + #video { + width: 300; + height: 200; + } +} ``` diff --git a/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md b/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md index 5353fd4d4c4..937c4482c93 100644 --- a/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md +++ b/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md @@ -1,57 +1,516 @@ --- id: 587d78af367417b2b2512b03 -title: アンケートフォームを作成する -challengeType: 3 +title: Build a Survey Form +challengeType: 14 forumTopicId: 301145 dashedName: build-a-survey-form --- # --description-- -**目標:** こちら と同様の機能を持つ [CodePen.io](https://codepen.io) アプリを構築します。 +**Objective:** Build an app that is functionally similar to https://survey-form.freecodecamp.rocks -以下の[ユーザーストーリー](https://en.wikipedia.org/wiki/User_story)を満たし、すべてのテストがパスするようにしてください。 あなた独自のスタイルを与えてください。 +**User Stories:** -このプロジェクトを完了するために、HTML、JavaScript、CSS を使用することができます。 これまでのレッスンでカバーされた純粋な CSS の練習をするため、純粋な CSS の使用を推奨します。 Bootstrap や SASS を使用しても構いません。 このプロジェクトで追加のテクノロジー (jQuery、React、Angular、Vue など) を使用することは推奨されません。使用する場合は自己責任で使用してください。 React のようなさまざまな技術スタックで作業する機会は他のプロジェクトで得られます。 このプロジェクトで推奨される一連のテクノロジーを使用している場合の不具合報告については、freeCodeCamp にて報告を受け入れ、修正するよう努めます。 ハッピーコーディング! +1. You should have a page title in an `h1` element with an `id` of `title` +1. You should have a short explanation in a `p` element with an `id` of `description` +1. You should have a `form` element with an `id` of `survey-form` +1. Inside the form element, you are **required** to enter your name in an `input` field that has an `id` of `name` and a `type` of `text` +1. Inside the form element, you are **required** to enter your email in an `input` field that has an `id` of `email` +1. If you enter an email that is not formatted correctly, you will see an HTML5 validation error +1. Inside the form, you can enter a number in an `input` field that has an `id` of `number` +1. If you enter non-numbers in the number input, you will see an HTML5 validation error +1. If you enter numbers outside the range of the number input, which are defined by the `min` and `max` attributes, you will see an HTML5 validation error +1. For the name, email, and number input fields, you can see corresponding `label` elements in the form, that describe the purpose of each field with the following ids: `id="name-label"`, `id="email-label"`, and `id="number-label"` +1. For the name, email, and number input fields, you can see placeholder text that gives a description or instructions for each field +1. Inside the form element, you should have a `select` dropdown element with an `id` of `dropdown` and at least two options to choose from +1. Inside the form element, you can select an option from a group of at least two radio buttons that are grouped using the `name` attribute +1. Inside the form element, you can select several fields from a series of checkboxes, each of which must have a `value` attribute +1. Inside the form element, you are presented with a `textarea` for additional comments +1. Inside the form element, you are presented with a button with `id` of `submit` to submit all the inputs -**ユーザーストーリー #1:** `id="title"` を持つ H1 サイズテキストのタイトルがあります。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**ユーザーストーリー #2:** `id="description"` を持つ P サイズテキストの短い説明文があります。 +# --hints-- -**ユーザーストーリー #3:** `id="survey-form"` を持つ `form` があります。 +You should have an `h1` element with an `id` of `title` -**ユーザーストーリー #4:** フォーム要素内では、`id="name"` を持つフィールドに名前入力が必須となっています。 +```js +const el = document.getElementById('title') +assert(!!el && el.tagName === 'H1') +``` -**ユーザーストーリー #5:** フォーム要素内では、`id="email"` を持つフィールドにメールアドレス入力が必須となっています。 +Your `#title` should not be empty -**ユーザーストーリー #6:** メールアドレスとして正しいフォーマットでない内容を入力すると、HTML5 のバリデーションエラーが表示されます。 +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) +``` -**ユーザーストーリー #7: ** フォーム要素内では、`id="number"` を持つフィールドに数字を入力することができます。 +You should have a `p` element with an `id` of `description` -**ユーザーストーリー #8:** 数字ではない内容を入力すると、HTML5 のバリデーションエラーが表示されます。 +```js +const el = document.getElementById('description') +assert(!!el && el.tagName === 'P') +``` -**ユーザーストーリー #9:** `min` と `max` 属性で定義した範囲外の数字を入力すると、HTML5 のバリデーションエラーが表示されます。 +Your `#description` should not be empty -**ユーザーストーリー #10:** フォーム内の名前、メール、数字入力フィールドには、各フィールドの目的を説明する次のラベルが含まれます: `id="name-label"`、`id="email-label"`、`id="number-label"`。 +```js +const el = document.getElementById('description') +assert(!!el && el.innerText.length > 0) +``` -**ユーザーストーリー #11:** 名前、メール、数値の入力フィールドには、各フィールドの説明や指示を示すプレイスホルダ―テキストが表示されます。 +You should have a `form` element with an `id` of `survey-form` -**ユーザーストーリー #12:** フォーム要素内では、対応する `id="dropdown"` を持つドロップダウンからオプションを選択できます。 +```js +const el = document.getElementById('survey-form') +assert(!!el && el.tagName === 'FORM') +``` -**ユーザーストーリー #13:** フォーム要素内では、1 つ以上のグループからなるラジオボタンでフィールドを選択できます。 各グループは `name` 属性を使用してグループ化する必要があります。 +You should have an `input` element with an `id` of `name` -**ユーザーストーリー #14:** フォーム要素内では、一連のチェックボックスからいくつかのフィールドを選択することができ、それぞれは `value` 属性を持つ必要があります。 +```js +const el = document.getElementById('name') +assert(!!el && el.tagName === 'INPUT') +``` -**ユーザーストーリー #15:** フォーム要素内では、追加でコメントするために最後に `textarea` を表示します。 +Your `#name` should have a `type` of `text` -**ユーザーストーリー #16:** フォーム要素内では、すべての入力内容を送信するため `id="submit"` を持つボタンを表示します。 +```js +const el = document.getElementById('name') +assert(!!el && el.type === 'text') +``` -この CodePen テンプレートを使用してあなたのプロジェクトを構築することができます。`Save` をクリックすると、あなた用の pen を作成することができます。 または、この CDN リンクを使用して任意の環境でテストを実行できます: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +Your `#name` should require input -完了したら、すべてのテストがパスする状態の作業プロジェクトの URL を送信します。 +```js +const el = document.getElementById('name') +assert(!!el && el.required) +``` -# --solutions-- +Your `#name` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name') +assert(!!el) +``` + +You should have an `input` element with an `id` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should have a `type` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +Your `#email` should require input + +```js +const el = document.getElementById('email') +assert(!!el && el.required) +``` + +Your `#email` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email') +assert(!!el) +``` + +You should have an `input` element with an `id` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#number` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number') +assert(!!el) +``` + +Your `#number` should have a `type` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.type === 'number') +``` + +Your `#number` should have a `min` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.min && isFinite(el.min)) +``` + +Your `#number` should have a `max` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.max && isFinite(el.max)) +``` + +You should have a `label` element with an `id` of `name-label` + +```js +const el = document.getElementById('name-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `email-label` + +```js +const el = document.getElementById('email-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `number-label` + +```js +const el = document.getElementById('number-label') +assert(!!el && el.tagName === 'LABEL') +``` + +Your `#name-label` should not be empty + +```js +const el = document.getElementById('name-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#email-label` should not be empty + +```js +const el = document.getElementById('email-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#number-label` should not be empty + +```js +const el = document.getElementById('number-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#name-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name-label') +assert(!!el) +``` + +Your `#email-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email-label') +assert(!!el) +``` + +Your `#number-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number-label') +assert(!!el) +``` + +Your `#name` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('name') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#number` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('number') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +You should have a `select` field with an `id` of `dropdown` + +```js +const el = document.getElementById('dropdown') +assert(!!el && el.tagName === 'SELECT') +``` + +Your `#dropdown` should have at least two selectable (not disabled) `option` elements + +```js +const els = document.querySelectorAll('#dropdown option:not([disabled])') +assert(els.length >= 2) +``` + +Your `#dropdown` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #dropdown') +assert(!!el) +``` + +You should have at least two `input` elements with a `type` of `radio` (radio buttons) + +```js +const els = document.querySelectorAll('input[type="radio"]') +assert(els.length >= 2) +``` + +You should have at least two radio buttons that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="radio"]') +assert(els.length >= 2) +``` + +All your radio buttons should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][value=""], input[type="radio"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +All your radio buttons should have a `name` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][name=""], input[type="radio"]:not([name])') +assert(els1.length > 0 && els2.length === 0) +``` + +Every radio button group should have at least 2 radio buttons + +```js +const radioButtons = document.querySelectorAll('input[type="radio"]'); +const groups = {} + +if (radioButtons) { + radioButtons.forEach(el => { + if (!groups[el.name]) groups[el.name] = [] + groups[el.name].push(el) + }) +} + +const groupKeys = Object.keys(groups) + +groupKeys.forEach(key => { + if (groups[key].length < 2) assert(false) +}) + +assert(groupKeys.length > 0) +``` + +You should have at least two `input` elements with a `type` of `checkbox` (checkboxes) that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="checkbox"]'); +assert(els.length >= 2) +``` + +All your checkboxes inside `#survey-form` should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('#survey-form input[type="checkbox"]') +const els2 = document.querySelectorAll('#survey-form input[type="checkbox"][value=""], #survey-form input[type="checkbox"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +You should have at least one `textarea` element that is a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form textarea') +assert(!!el) +``` + +You should have an `input` or `button` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && (el.tagName === 'INPUT' || el.tagName === 'BUTTON')) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#submit` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #submit') +assert(!!el) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Survey Form + + +

Survey Form

+

The card below was built as a sample survey form for freeCodeCamp.

+
+

Join the Togepi Fan Club!

+

+ Enter your information here to receive updates about club activities, + our monthly newsletter, and other email communications. +

+
+ + + + +

Who is your favourite Pokemon?

+ + + +

Which communications do you want to receive?

+ + + +

Any other information you would like to share?

+ +

+ Please note: This form is a proof of concept. Submitting the form + will not actually transmit your data. +

+ +
+
+ + + +``` + +```css +main { + text-align: center; + background-color: #92869c; + background-blend-mode: lighten; + max-width: 500px; + margin: 20px auto; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); + color: black; +} +body { + text-align: center; + background: #3a3240; + color: white; +} +input, textarea, select, button { + background: #3a3240; + color: white; +} +a { + color: white; +} ``` diff --git a/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md b/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md index 356b44cdded..6c433375ba7 100644 --- a/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md +++ b/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md @@ -1,55 +1,525 @@ --- id: 587d78b0367417b2b2512b05 -title: テクニカルドキュメントページを作成する -challengeType: 3 +title: Build a Technical Documentation Page +challengeType: 14 forumTopicId: 301146 dashedName: build-a-technical-documentation-page --- # --description-- -**目標:** こちら と同様の機能を持つ [CodePen.io](https://codepen.io) アプリを構築します。 +**Objective:** Build an app that is functionally similar to https://technical-documentation-page.freecodecamp.rocks -以下の[ユーザーストーリー](https://en.wikipedia.org/wiki/User_story)を満たし、すべてのテストがパスするようにしてください。 あなた独自のスタイルを与えてください。 +**User Stories:** -このプロジェクトを完了するために、HTML、JavaScript、CSS を使用することができます。 これまでのレッスンでカバーされた純粋な CSS の練習をするため、純粋な CSS の使用を推奨します。 Bootstrap や SASS を使用しても構いません。 このプロジェクトで追加のテクノロジー (jQuery、React、Angular、Vue など) を使用することは推奨されません。使用する場合は自己責任で使用してください。 React のようなさまざまな技術スタックで作業する機会は他のプロジェクトで得られます。 このプロジェクトで推奨される一連のテクノロジーを使用している場合の不具合報告については、freeCodeCamp にて報告を受け入れ、修正するよう努めます。 ハッピーコーディング! +1. You can see a `main` element with a corresponding `id="main-doc"`, which contains the page's main content (technical documentation) +1. Within the `#main-doc` element, you can see several `section` elements, each with a class of `main-section`. There should be a minimum of five +1. The first element within each `.main-section` should be a `header` element, which contains text that describes the topic of that section. +1. Each `section` element with the class of `main-section` should also have an `id` that corresponds with the text of each `header` contained within it. Any spaces should be replaced with underscores (e.g. The section that contains the header "JavaScript and Java" should have a corresponding `id="JavaScript_and_Java"`) +1. The `.main-section` elements should contain at least ten `p` elements total (not each) +1. The `.main-section` elements should contain at least five `code` elements total (not each) +1. The `.main-section` elements should contain at least five `li` items total (not each) +1. You can see a `nav` element with a corresponding `id="navbar"` +1. The navbar element should contain one `header` element which contains text that describes the topic of the technical documentation +1. Additionally, the navbar should contain link (`a`) elements with the class of `nav-link`. There should be one for every element with the class `main-section` +1. The `header` element in the `#navbar` must come before any link (`a`) elements in the navbar +1. Each element with the class of `nav-link` should contain text that corresponds to the `header` text within each `section` (e.g. if you have a "Hello world" section/header, your navbar should have an element which contains the text "Hello world") +1. When you click on a navbar element, the page should navigate to the corresponding section of the `main-doc` element (e.g. If you click on a `nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id, and contains the corresponding header) +1. On regular sized devices (laptops, desktops), the element with `id="navbar"` should be shown on the left side of the screen and should always be visible to the user +1. Your technical documentation should use at least one media query -**ユーザーストーリー #1:** `id="main-doc"` を持ち、ページのメインコンテンツ (テクニカルドキュメント) を含む `main` 要素があります。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**ユーザーストーリー #2:** `#main-doc` 要素内に、それぞれのクラスが `main-section` である複数の `section` 要素があります。 最低でも 5 個必要です。 +# --hints-- -**ユーザーストーリー #3:** 各 `.main-section` 内の最初の要素は、そのセクションの主なトピックを説明するテキストを含む `header` 要素でなければなりません。 +You should have a `main` element with an `id` of `main-doc` -**ユーザーストーリー #4:** クラスが `main-section` の各 `section` 要素は、それぞれの `header` のテキストに対応する id も持つ必要があります。 すべてのスペースはアンダースコアに置き換える必要があります (例: "JavaScript and Java" ヘッダーを含む `section` には対応する `id="JavaScript_and_Java"` が必要です)。 +```js +const el = document.getElementById('main-doc') +assert(!!el) +``` -**ユーザーストーリー #5:** `.main-section` 要素は少なくとも (それぞれではなく) 合計で 10 個の `p` 要素を含む必要があります。 +You should have at least five `section` elements with a class of `main-section` -**ユーザーストーリー #6:** `.main-section` 要素は少なくとも (それぞれではなく) 合計で 5 個の `code` 要素を含む必要があります。 +```js +const els = document.querySelectorAll('#main-doc section') +assert(els.length >= 5) +``` -**ユーザーストーリー #7:** `.main-section` 要素は少なくとも (それぞれではなく) 合計で 5 個の `li` 要素を含む必要があります。 +All of your `.main-section` elements should be `section` elements -**ユーザーストーリー #8:** `id="navbar"` を持つ `nav` 要素があります。 +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (el.tagName !== 'SECTION') assert(false) +}) +assert(els.length > 0) +``` -**ユーザーストーリー #9:** navbar 要素には、テクニカルドキュメントのトピックを説明するテキストを含む `header` 要素が含まれている必要があります。 +You should have at least five `.main-section` elements that are descendants of `#main-doc` -**ユーザーストーリー #10:** さらに、ナビゲーションバーには `nav-link` のクラスを持つリンク (`a`) 要素が含まれている必要があります。 これはクラス `main-section` の各要素ごとに一つ存在する必要があります。 +```js +const els = document.querySelectorAll('#main-doc .main-section') +assert(els.length >= 5) +``` -**ユーザーストーリー #11:** ナビゲーションバーの `header` 要素は navbar のどのリンク (`a`) 要素よりも前に置かれなければなりません。 +The first child of each `.main-section` should be a `header` element -**ユーザーストーリー #12:** `nav-link` クラスの各要素には、各 `section` 内の `header` テキストに対応するテキストが含まれていなければなりません (例えば、もし "Hello world" セクション / ヘッダーがあるならば、ナビゲーションバーには "Hello world" テキストを含む要素が必要です) 。 +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if(el.firstElementChild?.tagName !== 'HEADER') assert(false) +}) +assert(els.length > 0) +``` -**ユーザーストーリー #13:** ナビゲーションバーの要素をクリックしたとき、ページは `main-doc` 要素の対応するセクションに移動しなければなりません (例えば、"Hello world" テキストを含む `nav-link` 要素をクリックしたならば、その id を持ち、対応する `header` を含む `section` 要素に移動しなければなりません)。 +None of your `header` elements should be empty -**ユーザーストーリー #14:** 通常サイズのデバイス上 (ラップトップ、デスクトップ) では、`id="navbar"` を持つ要素は画面の左側に表示され、常にユーザーから見える状態にしなければなりません。 +```js +const els = document.querySelectorAll('header') +els.forEach(el => { + if (el.innerText?.length <= 0) assert(false) +}) +assert(els.length > 0) +``` -**ユーザーストーリー #15:** 私のテクニカルドキュメントページは、少なくとも 1 つのメディアクエリを使う必要があります。 +All of your `.main-section` elements should have an `id` -この CodePen テンプレートを使用してあなたのプロジェクトを構築することができます。`Save` をクリックすると、あなた用の pen を作成することができます。 または、この CDN リンクを使用して任意の環境でテストを実行できます: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (!el.id || el.id === '') assert(false) +}) +assert(els.length > 0) +``` -完了したら、すべてのテストがパスする状態の作業プロジェクトの URL を送信します。 +Each `.main-section` should have an `id` that matches the text of its first child, having any spaces in the child's text replaced with underscores (`_`) for the id’s -# --solutions-- +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + const text = el.firstElementChild?.innerText?.replaceAll(' ', '_') + if (el.id?.toUpperCase() !== text?.toUpperCase()) assert(false) +}) +assert(els.length > 0) +``` + +You should have at least 10 `p` elements (total) within your `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section p') +assert(els.length >= 10) +``` + +You should have at least five `code` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section code') +assert(els.length >= 5) +``` + +You should have at least five `li` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section li') +assert(els.length >= 5) +``` + +You should have a `nav` element with an `id` of `navbar` + +```js +const el = document.getElementById('navbar') +assert(!!el && el.tagName === 'NAV') +``` + +Your `#navbar` should have exactly one `header` element within it + +```js +const els = document.querySelectorAll('#navbar header') +assert(els.length === 1) +``` + +You should have at least one `a` element with a class of `nav-link` + +```js +const els = document.querySelectorAll('a[class="nav-link"]') +assert(els.length >= 1) +``` + +All of your `.nav-link` elements should be anchor (`a`) elements + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (el.tagName !== 'A') assert(false) +}) +assert(els.length > 0) +``` + +All of your `.nav-link` elements should be in the `#navbar` + +```js +const els1 = document.querySelectorAll('.nav-link') +const els2 = document.querySelectorAll('#navbar .nav-link') +assert(els2.length > 0 && els1.length === els2.length) +``` + +You should have the same number of `.nav-link` and `.main-section` elements + +```js +const els1 = document.querySelectorAll('.main-section') +const els2 = document.querySelectorAll('.nav-link') +assert(els1.length > 0 && els2.length > 0 && els1.length === els2.length) +``` + +The `header` element in the `#navbar` should come before any link (`a`) elements also in the `#navbar` + +```js +const navLinks = document.querySelectorAll('#navbar a.nav-link'); +const header = document.querySelector('#navbar header'); +navLinks.forEach((navLink) => { + if ( + ( + header.compareDocumentPosition(navLink) & + Node.DOCUMENT_POSITION_PRECEDING + ) + ) assert(false) +}); +assert(!!header) +``` + +Each `.nav-link` should have text that corresponds to the `header` text of its related `section` (e.g. if you have a "Hello world" section/header, your `#navbar` should have a `.nav-link` which has the text "Hello world") + +```js +const headerText = Array.from(document.querySelectorAll('.main-section')).map(el => + el.firstElementChild?.innerText?.trim().toUpperCase() +) +const linkText = Array.from(document.querySelectorAll('.nav-link')).map(el => + el.innerText?.trim().toUpperCase() +) +const remainder = headerText.filter(str => linkText.indexOf(str) === -1) +assert(headerText.length > 0 && headerText.length > 0 && remainder.length === 0) +``` + +Each `.nav-link` should have an `href` attribute that links to its corresponding `.main-section` (e.g. If you click on a `.nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id) + +```js +const hrefValues = Array.from(document.querySelectorAll('.nav-link')).map(el => el.getAttribute('href')) +const mainSectionIDs = Array.from(document.querySelectorAll('.main-section')).map(el => el.id) +const missingHrefValues = mainSectionIDs.filter(str => hrefValues.indexOf('#' + str) === -1) +assert(hrefValues.length > 0 && mainSectionIDs.length > 0 && missingHrefValues.length === 0) +``` + +Your `#navbar` should always be on the left edge of the window + +```js +const el = document.getElementById('navbar') +const left1 = el?.offsetLeft +const left2 = el?.offsetLeft +assert(!!el && left1 >= -15 && left1 <= 15 && left2 >= -15 && left2 <= 15) +``` + +Your Technical Documentation project should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Technical Documentation Page + + + +
+
+
Introduction
+

+ Welcome to a basic introduction of algebra. In this tutorial, we will + review some of the more common algebraic concepts. +

+
+
+
Definitions
+

+ To start with, let's define some of the more common terms used in + algebra: +

+
    +
  • + Variable: A variable is an unknown value, usually represented + by a letter. +
  • +
  • + Expression: Essentially a mathematical object. For the + purpose of this tutorial, an expression is one part of an equation. +
  • +
  • + Equation: An equation is a mathematical argument in which two + expressions result in the same value. +
  • +
+
+
+
Examples
+

+ Sometimes it is easier to understand the definitions when you have a + physical example to look at. Here is an example of the above terms.

+ x + 5 = 12

+ In this above example, we have: +

+
    +
  • Variable: The variable in the example is "x".
  • +
  • + Expression: There are two expressions in this example. They + are "x+5" and "12". +
  • +
  • + Equation: The entire example, "x+5=12", is an equation. +
  • +
+
+
+
Solving Equations
+

+ The primary use for algebra is to determine an unknown value, the + "variable", with the information provided. Continuing to use our + example from above, we can find the value of the variable "x".

+ x + 5 = 12

+ In an equation, both sides result in the same value. So you can + manipulate the two expressions however you need, as long as you + perform the same operation (or change) to each side. You do this + because the goal when solving an equation is to + get the variable into its own expression, or by itself on one side + of the = sign.
For this example, we want to remove the "+5" so the "x" is + alone. To do this, we can subtract 5, because subtraction is + the opposite operation to addition. But remember, we have to perform + the same operation to both sides of the equation. Now our equation + looks like this.

+ x + 5 - 5 = 12 - 5

+ The equation looks like a mess right now, because we haven't completed + the operations. We can simplify this equation to make it easier + to read by performing the operations "5-5" and "12-5". The result + is:

+ x = 7

+ We now have our solution to this equation! +

+
+
+
Solving Equations II
+

+ Let us look at a slightly more challenging equation.

+ 3x + 4 = 13

+ Again we can start with subtraction. In this case, we want to subtract + 4 from each side of the equation. We will also go ahead and simplify + with each step. So now we have:

+ 3x = 9

+ "3x" translates to "3*x", where the "*" symbol indicates + multiplication. We use the "*" to avoid confusion, as the "x" is now a + variable instead of a multiplication symbol. The opposite operation + for multiplication is division, so we need to + divide each expression by 3.

+ x = 3

+ And now we have our solution! +

+
+
+
Solving Equations III
+

+ Now we are getting in to more complex operations. Here is another + equation for us to look at:

+ x^2 - 8 = 8

+ Our very first step will be to add 8 to each side. This is + different from our previous examples, where we had to subtract. But + remember, our goal is to get the variable alone by performing opposite + operations.

+ x^2 = 16

+ But what does the "^2" mean? The "^" symbol is used to denote + exponents in situations where superscript is not available. When + superscript is available, you would see it as x2. + For the sake of this project, however, we will use the "^" symbol.
+ An exponent tells you how many times the base (in our case, "x") is + multiplied by itself. So, "x^2" would be the same as "x*x". Now the + opposite function of multiplication is division, but we would have to + divide both sides by "x". We do not want to do this, as that + would put an "x" on the other side of the equation. So instead, we + need to use the root operation! For an exponent of "2", we call this + the "square root" and denote it with "√". Our equation is now: +

+ x = √9

+ Performing a root operation by hand can be a tedious process, so we + recommend using a calculator when necessary. However, we are lucky in + that "9" is a + perfect square, so we do not need to calculate anything. Instead, we find our + answer to be:

+ x = 3 +

+
+
+
System of Equations
+

+ As you explore your algebra studies further, you may start to run + across equations with more than one variable. The first such equations + will likely look like:

+ y = 3x

+ An equation like this does not have one single solution. + Rather, there are a series of values for which the equation is true. + For example, if "x=3" and "y=9", the equation is true. These equations + are usually used to plot a graph.
+ Getting more complicated, though, you may be given a pair of + equations. This is called a "system of equations", and CAN be solved. + Let's look at how we do this! Consider the following system of + equations:

+ y = 3x | y - 6 = x + A system of equations IS solvable, but it is a multi-step process. To + get started, we need to chose a variable we are solving for. Let's + solve for "x" first. From the second equation, we know that "x" equals + "y - 6", but we cannot simplify that further because we do not have a + value for "y". Except, thanks to the system of equations, we DO have a + value for "y". We know that "y" equals "3x". So, looking at our second + equation, we can replace "y" with "3x" because they have the same + value. We then get:

+ 3x - 6 = x

+ Now we can solve for "x"! We start by adding 6 to each side.

+ 3x = x + 6

+ We still need to get "x" by itself, so we subtract "x" from both sides + and get:

+ 2x = 6

+ If this confuses you, remember that "3x" is the same as "x+x+x". + Subtract an "x" from that and you get "x+x", or "2x". Now we divide + both sides by 2 and have our value for x!

+ x = 3

+ However, our work is not done yet. We still need to find the value for + "y". Let's go back to our first equation:

+ y = 3x

+ We have a value for "x" now, so let's see what happens if we put that + value in.

+ y = 3*3

+ We perform the multiplication and discover that "y=9"! Our solution to + this system of equations then is:

+ x = 3 and y = 9

+

+
+
+
Try it Yourself!
+

Coming Soon!

+

Keep an eye out for new additions!

+
+
+
More Information
+

Check out the following links for more information!

+ +
+
+ + + +``` + +```css +* { + background-color: #3a3240; +} +a { + color: #92869c; +} +a:hover { + background-color: #92869c; + color: #3a3240; +} +#navbar { + border-style: solid; + border-width: 5px; + border-color: #92869c; + height: 100%; + top: -5px; + left: -5px; + padding: 5px; + text-align: center; + color: #92869c +} +@media (min-width: 480px) { + #navbar { + position: fixed; + } +} +main { + margin-left: 220px; + color: #92869c +} +header { + font-size: 20pt; +} +code { + background-color: #92869c; + border-style: dashed; + border-width: 2px; + border-color: #92869c; + padding: 5px; + color: black; +} +footer { + text-align: center; +} ``` diff --git a/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md b/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md index d0dfc30b6ef..231292b4373 100644 --- a/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md +++ b/curriculum/challenges/japanese/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md @@ -1,43 +1,327 @@ --- id: bd7158d8c442eddfaeb5bd18 -title: トリビュートページを作成する -challengeType: 3 +title: Build a Tribute Page +challengeType: 14 forumTopicId: 301147 dashedName: build-a-tribute-page --- # --description-- -**目標:** こちら と同様の機能を持つ [CodePen.io](https://codepen.io) アプリを構築します。 +**Objective:** Build an app that is functionally similar to https://tribute-page.freecodecamp.rocks -以下の[ユーザーストーリー](https://en.wikipedia.org/wiki/User_story)を満たし、すべてのテストがパスするようにしてください。 あなた独自のスタイルを与えてください。 +**User Stories:** -このプロジェクトを完了するために、HTML、JavaScript、CSS を使用することができます。 これまでのレッスンでカバーされた純粋な CSS の練習をするため、純粋な CSS の使用を推奨します。 Bootstrap や SASS を使用しても構いません。 このプロジェクトで追加のテクノロジー (jQuery、React、Angular、Vue など) を使用することは推奨されません。使用する場合は自己責任で使用してください。 React のようなさまざまな技術スタックで作業する機会は他のプロジェクトで得られます。 このプロジェクトで推奨される一連のテクノロジーを使用している場合の不具合報告については、freeCodeCamp にて報告を受け入れ、修正するよう努めます。 ハッピーコーディング! +1. Your tribute page should have an element with a corresponding `id="main"`, which contains all other elements +1. You should see an element with an `id` of `title`, which contains a string (i.e. text), that describes the subject of the tribute page (e.g. "Dr. Norman Borlaug") +1. You should see either a `figure` or a `div` element with an `id` of `img-div` +1. Within the `img-div` element, you should see an `img` element with a corresponding `id="image"` +1. Within the `img-div` element, you should see an element with a corresponding `id="img-caption"` that contains textual content describing the image shown in `img-div` +1. You should see an element with a corresponding `id="tribute-info"`, which contains textual content describing the subject of the tribute page +1. You should see an a element with a corresponding `id="tribute-link"`, which links to an outside site, that contains additional information about the subject of the tribute page. HINT: You must give your element an attribute of `target` and set it to `_blank` in order for your link to open in a new tab +1. Your `#image` should use `max-width` and `height` properties to resize responsively, relative to the width of its parent element, without exceeding its original size +1. Your `img` element should be centered within its parent element -**ユーザーストーリー #1:** 私のトリビュートページには `id="main"` を持つ要素があり、その中に他のすべての要素が含まれます。 +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**ユーザーストーリー #2:** `id="title"` を持つ要素があり、これにはトリビュートページで取り上げる対象者 (例: "Dr. Norman Borlaug) を説明する文字列 (すなわちテキスト) が記載されています。 +# --hints-- -**ユーザーストーリー #3:** `id="img-div"` を持つ、`figure` または `div` 要素のどちらかが表示される必要があります。 +You should have a `main` element with an `id` of `main` -**ユーザーストーリー #4:** `img-div` 要素内に、`id="image"` を持つ `img` 要素があります。 +```js +const el = document.getElementById('main') +assert(!!el && el.tagName === 'MAIN') +``` -**ユーザーストーリー #5:** `img-div` 要素内には、`id="img-caption"` を持つ要素があり、`img-div` 内に表示されている画像を説明するテキストコンテンツを含みます。 +Your `#img-div`, `#image`, `#img-caption`, `#tribute-info`, and `#tribute-link` should all be descendants of `#main` -**ユーザーストーリー #6:** `id="tribute-info"` を持つ要素があり、これにはトリビュートページの対象者を説明するテキストコンテンツが含まれます。 +```js +const el1 = document.querySelector('#main #img-div') +const el2 = document.querySelector('#main #image') +const el3 = document.querySelector('#main #img-caption') +const el4 = document.querySelector('#main #tribute-info') +const el5 = document.querySelector('#main #tribute-link') +assert(!!el1 & !!el2 && !!el3 && !!el4 && !!el5) +``` -**ユーザーストーリー #7:** `id="tribute-link"` を持つ `a` 要素があり、これはトリビュートページの対象者に関する追加情報を含む外部サイトへのリンクです。 ヒント: リンクを新しいタブで開くためには、要素に `target` 属性を与え、その値に `_blank` を設定しなければなりません (つまり `target="_blank"` となります)。 +You should have an element with an `id` of `title` -**ユーザーストーリー #8:** `img` 要素は、オリジナルのサイズを超えることなく、親要素の幅に応じてレスポンシブにサイズが変更される必要があります。 +```js +const el = document.getElementById('title') +assert(!!el) +``` -**ユーザーストーリー #9:** `img` 要素は、その親要素内で中央に配置される必要があります。 +Your `#title` should not be empty -この CodePen テンプレートを使用してあなたのプロジェクトを構築することができます。`Save` をクリックすると、あなた用の pen (CodePen 上の作品) を作成することができます。 または、この CDN リンクを使用して任意の環境でテストを実行できます: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) -完了したら、すべてのテストがパスする状態の作業プロジェクトの URL を送信します。 +``` -# --solutions-- +You should have a `figure` or `div` element with an `id` of `img-div` + +```js +const el = document.getElementById('img-div') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGURE')) +``` + +You should have an `img` element with an `id` of `image` + +```js +const el = document.getElementById('image') +assert(!!el && el.tagName === 'IMG') +``` + +Your `#image` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #image') +assert(!!el) +``` + +You should have a `figcaption` or `div` element with an `id` of `img-caption` + +```js +const el = document.getElementById('img-caption') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGCAPTION')) +``` + +Your `#img-caption` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #img-caption') +assert(!!el) +``` + +Your `#img-caption` should not be empty + +```js +const el = document.getElementById('img-caption') +assert(!!el && el.innerText.length > 0) +``` + +You should have an element with an `id` of `tribute-info` + +```js +const el = document.getElementById('tribute-info') +assert(!!el) +``` + +Your `#tribute-info` should not be empty + +```js +const el = document.getElementById('tribute-info') +assert(!!el && el.innerText.length > 0) +``` + +You should have an `a` element with an `id` of `tribute-link` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.tagName === 'A') +``` + +Your `#tribute-link` should have an `href` attribute and value + +```js +const el = document.getElementById('tribute-link') +assert(!!el && !!el.href && el.href.length > 0) +``` + +Your `#tribute-link` should have a `target` attribute set to `_blank` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.target === '_blank') +``` + +You should use an `#image` selector in your CSS to style the `#image` and pass the next three tests + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image') +assert(!!style) +``` + +Your `#image` should have a `display` of `block` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +assert(style === 'block') +``` + +Your `#image` should have a `max-width` of `100%` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +assert(style === '100%') +``` + +Your `#image` should have a `height` of `auto` + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'); +const maxWidthValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +const displayValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +const oldDisplayValue = img?.style.getPropertyValue('display'); +const oldDisplayPriority = img?.style.getPropertyPriority('display'); +img?.style.setProperty('display', 'none', 'important'); +const heightValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('height') +img?.style.setProperty('display', oldDisplayValue, oldDisplayPriority); +assert(heightValue === 'auto') +``` + +Your `#image` should be centered within its parent + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'), + imgParent = img?.parentElement, + imgLeft = img?.getBoundingClientRect().left, + imgRight = img?.getBoundingClientRect().right, + parentLeft = imgParent?.getBoundingClientRect().left, + parentRight = imgParent?.getBoundingClientRect().right, + leftMargin = imgLeft - parentLeft, + rightMargin = parentRight - imgRight; +assert(leftMargin - rightMargin < 6 && rightMargin - leftMargin < 6) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + + + Tribute Page + + +

Tribute Page

+

The below card was designed as a tribute page for freeCodeCamp.

+
+
+ An image of Togepi +
Togepi, happy as always.
+
+

Togepi

+
+
+

+ Togepi was first discovered in the Johto region, when Ash Ketchum + discovered a mysterious egg. However, when the egg hatched, Togepi saw + Ash's friend Misty first and imprinted on her. Like many other + creatures, this imprinting process created a bond and Togepi views + Misty as his mother. +

+

+ Togepi is a very childlike Pokemon, and is very emotionally + expressive. He demonstrates extreme levels of joy and sadness. +

+
+

Battle Information

+
    +
  • Type: Fairy
  • +
  • Evolutions: Togepi -> Togetic -> Togekiss
  • +
  • Moves: Growl, Pound, Sweet Kiss, Charm
  • +
  • Weaknesses: Poison, Steel
  • +
  • Resistances: Dragon
  • +
+

+ Check out this + Bulbapedia article on Togepi + for more information on this great Pokemon. +

+
+
+ + + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + background-color: #92869c; + font-family: Lobster; + max-width: 500px; + margin: 20px auto; + color: black; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); +} +h2 { + text-align: center; + font-size: 20pt; + font-family: Pacifico; +} +body { + text-align: center; + font-size: 12pt; +} +footer { + text-align: center; + font-size: 10pt; +} +.border { + border-color: black; + border-width: 5px; + border-style: solid; +} +#image { + height: auto; + display: block; + margin: auto; + max-width: 100%; + border-radius: 50%; +} +#img-caption { + font-size: 10pt; +} +a:not(#tribute-link) { + color: white; +} +hr { + border-color: black; +} ``` diff --git a/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-personal-portfolio-webpage-project/build-a-personal-portfolio-webpage.md b/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-personal-portfolio-webpage-project/build-a-personal-portfolio-webpage.md deleted file mode 100644 index d026ce9ba69..00000000000 --- a/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-personal-portfolio-webpage-project/build-a-personal-portfolio-webpage.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -id: bd7158d8c242eddfaeb5bd13 -title: 個人ポートフォリオのウェブページを作成する -challengeType: 3 -forumTopicId: 301143 -dashedName: build-a-personal-portfolio-webpage ---- - -# --description-- - -**目標:** こちら と同様の機能を持つ [CodePen.io](https://codepen.io) アプリを構築します。 - -以下の[ユーザーストーリー](https://en.wikipedia.org/wiki/User_story)を満たし、すべてのテストがパスするようにしてください。 あなた独自のスタイルを与えてください。 - -このプロジェクトを完了するために、HTML、JavaScript、CSS を使用することができます。 これまでのレッスンでカバーされた純粋な CSS の練習をするため、純粋な CSS の使用を推奨します。 Bootstrap や SASS を使用しても構いません。 このプロジェクトで追加のテクノロジー (jQuery、React、Angular、Vue など) を使用することは推奨されません。使用する場合は自己責任で使用してください。 React のようなさまざまな技術スタックで作業する機会は他のプロジェクトで得られます。 このプロジェクトで推奨される一連のテクノロジーを使用している場合の不具合報告については、freeCodeCamp にて報告を受け入れ、修正するよう努めます。 ハッピーコーディング! - -**ユーザーストーリー #1:** 私のポートフォリオには、`welcome-section` の id を持つウェルカムセクションがあります。 - -**ユーザーストーリー #2:** ウェルカムセクションにはテキストを含む `h1` 要素があります。 - -**ユーザーストーリー #3:** 私のポートフォリオには、`projects` の id を持つプロジェクトセクションがあります。 - -**ユーザーストーリー #4:** プロジェクトセクションには、プロジェクトを入れるために少なくとも 1 つの `project-tile` クラスの要素があります。 - -**ユーザーストーリー #5:** プロジェクトセクションには、少なくとも 1 つのプロジェクトへのリンクが含まれている必要があります。 - -**ユーザーストーリー #6:** 私のポートフォリオには、 `navbar` の id を持つナビゲーションバーがあります。 - -**ユーザーストーリー #7:** ナビゲーションバーには、クリックするとページ上の異なるセクションに移動できるリンクが少なくとも 1 つあります。 - -**ユーザーストーリー #8:** 私のポートフォリオには `profile-link` の id を持つリンクがあり、GitHub または FCC プロフィールを新しいタブで開くことができます。 - -**ユーザーストーリー #9:** 私のポートフォリオには、少なくとも 1 つのメディアクエリがあります。 - -**ユーザーストーリー #10:** ウェルカムセクションの高さはビューポートの高さと等しくなければなりません。 - -**ユーザーストーリー #11:** ナビゲーションバーは常にビューポートの上部に表示されている必要があります。 - -この CodePen テンプレートを使用してあなたのプロジェクトを構築することができます。`Save` をクリックすると、あなた用の pen を作成することができます。 または、この CDN リンクを使用して任意の環境でテストを実行できます: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` - -完了したら、すべてのテストがパスする状態の作業プロジェクトの URL を送信します。 - -# --solutions-- - -```html -// solution required -``` diff --git a/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-product-landing-page-project/build-a-product-landing-page.md b/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-product-landing-page-project/build-a-product-landing-page.md deleted file mode 100644 index ffbde30b611..00000000000 --- a/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-product-landing-page-project/build-a-product-landing-page.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -id: 587d78af367417b2b2512b04 -title: プロダクトのランディングページを作成する -challengeType: 3 -forumTopicId: 301144 -dashedName: build-a-product-landing-page ---- - -# --description-- - -**目標:** こちら と同様の機能を持つ [CodePen.io](https://codepen.io) アプリを構築します。 - -以下の[ユーザーストーリー](https://en.wikipedia.org/wiki/User_story)を満たし、すべてのテストがパスするようにしてください。 あなた独自のスタイルを与えてください。 - -このプロジェクトを完了するために、HTML、JavaScript、CSS を使用することができます。 これまでのレッスンでカバーされた純粋な CSS の練習をするため、純粋な CSS の使用を推奨します。 Bootstrap や SASS を使用しても構いません。 このプロジェクトで追加のテクノロジー (jQuery、React、Angular、Vue など) を使用することは推奨されません。使用する場合は自己責任で使用してください。 React のようなさまざまな技術スタックで作業する機会は他のプロジェクトで得られます。 このプロジェクトで推奨される一連のテクノロジーを使用している場合の不具合報告については、freeCodeCamp にて報告を受け入れ、修正するよう努めます。 ハッピーコーディング! - -**ユーザーストーリー #1:** 私のプロダクトランディングページには `id="header"` を持つ `header` 要素があります。 - -**ユーザーストーリー #2:** `header` 要素内には `id="header-img"` を持つ画像が表示されます。 会社のロゴがあればここでいいイメージを与えることができるでしょう。 - -**ユーザーストーリー #3:** `#header` 要素内に `id="nav-bar"` を持つ `nav` 要素があります。 - -**ユーザーストーリー #4:** `nav` 要素内に少なくとも 3 つのクリック可能な `nav-link` クラスの要素があります。 - -**ユーザーストーリー #5:** `nav` 要素内の `.nav-link` ボタンをクリックしたら、ランディングページの対応するセクションに移動します。 - -**ユーザーストーリー #6:** `id="video"` を持つプロダクトの埋め込み動画を見ることができます。 - -**ユーザーストーリー #7:** 私のランディングページには `id="form"` を持つ `form` 要素があります。 - -**ユーザーストーリー #8:** フォーム内には、E メールアドレスが入力可能な `id="email"` を持つ `input` フィールドがあります。 - -**ユーザーストーリー #9:** `#email` 入力フィールドには、フィールドの用途をユーザーに知らせるためのプレイスホルダ―テキストが必要です。 - -**ユーザーストーリー #10:** `#email` 入力フィールドは、入力されたテキストがメールアドレスであるか確認するために HTML5 のバリデーションを使用します。 - -**ユーザーストーリー #11:** フォーム内には、`id="submit"` を持つ送信ボタンの `input` があります。 - -**ユーザーストーリー #12:** `#submit` 要素をクリックすると、email の情報が静的ページに送信されます (このモック URL を使用してください: )。 - -**ユーザーストーリー #13:** ナビゲーションバーは常にビューポートの上部に表示されている必要があります。 - -**ユーザーストーリー #14:** 私のプロダクトランディングページには、少なくとも 1 つのメディアクエリがあります。 - -**ユーザーストーリー #15:** 私のプロダクトランディングページは、少なくとも 1 つの CSS フレックスボックスを使用しています。 - -この CodePen テンプレートを使用してあなたのプロジェクトを構築することができます。`Save` をクリックすると、あなた用の pen を作成することができます。 または、この CDN リンクを使用して任意の環境でテストを実行できます: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` - -完了したら、すべてのテストがパスする状態の作業プロジェクトの URL を送信します。 - -# --solutions-- - -```html -// solution required -``` diff --git a/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md b/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md deleted file mode 100644 index 6ba3b7caca0..00000000000 --- a/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -id: 587d78af367417b2b2512b03 -title: アンケートフォームを作成する -challengeType: 3 -forumTopicId: 301145 -dashedName: build-a-survey-form ---- - -# --description-- - -**目標:** こちら と同様の機能を持つ [CodePen.io](https://codepen.io) アプリを構築します。 - -以下の[ユーザーストーリー](https://en.wikipedia.org/wiki/User_story)を満たし、すべてのテストがパスするようにしてください。 あなた独自のスタイルを与えてください。 - -このプロジェクトを完了するために、HTML、JavaScript、CSS を使用することができます。 これまでのレッスンでカバーされた純粋な CSS の練習をするため、純粋な CSS の使用を推奨します。 Bootstrap や SASS を使用しても構いません。 このプロジェクトで追加のテクノロジー (jQuery、React、Angular、Vue など) を使用することは推奨されません。使用する場合は自己責任で使用してください。 React のようなさまざまな技術スタックで作業する機会は他のプロジェクトで得られます。 このプロジェクトで推奨される一連のテクノロジーを使用している場合の不具合報告については、freeCodeCamp にて報告を受け入れ、修正するよう努めます。 ハッピーコーディング! - -**ユーザーストーリー #1:** `id="title"` を持つ H1 サイズテキストのタイトルがあります。 - -**ユーザーストーリー #2:** `id="description"` を持つ P サイズテキストの短い説明文があります。 - -**ユーザーストーリー #3:** `id="survey-form"` を持つ `form` があります。 - -**ユーザーストーリー #4:** フォーム要素内では、`id="name"` を持つフィールドに名前入力が必須となっています。 - -**ユーザーストーリー #5:** フォーム要素内では、`id="email"` を持つフィールドにメールアドレスを入力することが必須となっています。 - -**ユーザーストーリー #6:** メールアドレスとして正しいフォーマットでない内容を入力すると、HTML5 のバリデーションエラーが表示されます。 - -**ユーザーストーリー #7: ** フォーム要素内では、`id="number"` を持つフィールドに数字を入力することができます。 - -**ユーザーストーリー #8:** 数字ではない内容を入力すると、HTML5 のバリデーションエラーが表示されます。 - -**ユーザーストーリー #9:** `min` と `max` 属性で定義した範囲外の数字を入力すると、HTML5 のバリデーションエラーが表示されます。 - -**ユーザーストーリー #10:** フォーム内の名前、メール、数字入力フィールドには、以下の id で各フィールドの目的を説明するラベルが含まれます: `id="name-label"`、`id="email-label"`、`id="number-label"` - -**ユーザーストーリー #11:** 名前、メール、数値の入力フィールドには、各フィールドの説明や指示を示すプレイスホルダ―テキストが表示されます。 - -**ユーザーストーリー #12:** フォーム要素内では、対応する `id="dropdown"` を持つドロップダウンからオプションを選択できます。 - -**ユーザーストーリー #13:** フォーム要素内では、1 つ以上のグループからなるラジオボタンでフィールドを選択できます。 各グループは `name` 属性を使用してグループ化する必要があります。 - -**ユーザーストーリー #14:** フォーム要素内では、一連のチェックボックスからいくつかのフィールドを選択することができ、それぞれは `value` 属性を持つ必要があります。 - -**ユーザーストーリー #15:** フォーム要素内では、追加でコメントするために最後に `textarea` を表示します。 - -**ユーザーストーリー #16:** フォーム要素内では、すべての入力内容を送信するため `id="submit"` を持つボタンを表示します。 - -この CodePen テンプレートを使用してあなたのプロジェクトを構築することができます。`Save` をクリックすると、あなた用の pen (CodePen 上の作品) を作成することができます。 または、この CDN リンクを使用して任意の環境でテストを実行できます: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` - -完了したら、すべてのテストがパスする状態の作業プロジェクトの URL を送信します。 - -# --solutions-- - -```html -// solution required -``` diff --git a/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-technical-documentation-page-project/build-a-technical-documentation-page.md b/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-technical-documentation-page-project/build-a-technical-documentation-page.md deleted file mode 100644 index 356b44cdded..00000000000 --- a/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-technical-documentation-page-project/build-a-technical-documentation-page.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -id: 587d78b0367417b2b2512b05 -title: テクニカルドキュメントページを作成する -challengeType: 3 -forumTopicId: 301146 -dashedName: build-a-technical-documentation-page ---- - -# --description-- - -**目標:** こちら と同様の機能を持つ [CodePen.io](https://codepen.io) アプリを構築します。 - -以下の[ユーザーストーリー](https://en.wikipedia.org/wiki/User_story)を満たし、すべてのテストがパスするようにしてください。 あなた独自のスタイルを与えてください。 - -このプロジェクトを完了するために、HTML、JavaScript、CSS を使用することができます。 これまでのレッスンでカバーされた純粋な CSS の練習をするため、純粋な CSS の使用を推奨します。 Bootstrap や SASS を使用しても構いません。 このプロジェクトで追加のテクノロジー (jQuery、React、Angular、Vue など) を使用することは推奨されません。使用する場合は自己責任で使用してください。 React のようなさまざまな技術スタックで作業する機会は他のプロジェクトで得られます。 このプロジェクトで推奨される一連のテクノロジーを使用している場合の不具合報告については、freeCodeCamp にて報告を受け入れ、修正するよう努めます。 ハッピーコーディング! - -**ユーザーストーリー #1:** `id="main-doc"` を持ち、ページのメインコンテンツ (テクニカルドキュメント) を含む `main` 要素があります。 - -**ユーザーストーリー #2:** `#main-doc` 要素内に、それぞれのクラスが `main-section` である複数の `section` 要素があります。 最低でも 5 個必要です。 - -**ユーザーストーリー #3:** 各 `.main-section` 内の最初の要素は、そのセクションの主なトピックを説明するテキストを含む `header` 要素でなければなりません。 - -**ユーザーストーリー #4:** クラスが `main-section` の各 `section` 要素は、それぞれの `header` のテキストに対応する id も持つ必要があります。 すべてのスペースはアンダースコアに置き換える必要があります (例: "JavaScript and Java" ヘッダーを含む `section` には対応する `id="JavaScript_and_Java"` が必要です)。 - -**ユーザーストーリー #5:** `.main-section` 要素は少なくとも (それぞれではなく) 合計で 10 個の `p` 要素を含む必要があります。 - -**ユーザーストーリー #6:** `.main-section` 要素は少なくとも (それぞれではなく) 合計で 5 個の `code` 要素を含む必要があります。 - -**ユーザーストーリー #7:** `.main-section` 要素は少なくとも (それぞれではなく) 合計で 5 個の `li` 要素を含む必要があります。 - -**ユーザーストーリー #8:** `id="navbar"` を持つ `nav` 要素があります。 - -**ユーザーストーリー #9:** navbar 要素には、テクニカルドキュメントのトピックを説明するテキストを含む `header` 要素が含まれている必要があります。 - -**ユーザーストーリー #10:** さらに、ナビゲーションバーには `nav-link` のクラスを持つリンク (`a`) 要素が含まれている必要があります。 これはクラス `main-section` の各要素ごとに一つ存在する必要があります。 - -**ユーザーストーリー #11:** ナビゲーションバーの `header` 要素は navbar のどのリンク (`a`) 要素よりも前に置かれなければなりません。 - -**ユーザーストーリー #12:** `nav-link` クラスの各要素には、各 `section` 内の `header` テキストに対応するテキストが含まれていなければなりません (例えば、もし "Hello world" セクション / ヘッダーがあるならば、ナビゲーションバーには "Hello world" テキストを含む要素が必要です) 。 - -**ユーザーストーリー #13:** ナビゲーションバーの要素をクリックしたとき、ページは `main-doc` 要素の対応するセクションに移動しなければなりません (例えば、"Hello world" テキストを含む `nav-link` 要素をクリックしたならば、その id を持ち、対応する `header` を含む `section` 要素に移動しなければなりません)。 - -**ユーザーストーリー #14:** 通常サイズのデバイス上 (ラップトップ、デスクトップ) では、`id="navbar"` を持つ要素は画面の左側に表示され、常にユーザーから見える状態にしなければなりません。 - -**ユーザーストーリー #15:** 私のテクニカルドキュメントページは、少なくとも 1 つのメディアクエリを使う必要があります。 - -この CodePen テンプレートを使用してあなたのプロジェクトを構築することができます。`Save` をクリックすると、あなた用の pen を作成することができます。 または、この CDN リンクを使用して任意の環境でテストを実行できます: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` - -完了したら、すべてのテストがパスする状態の作業プロジェクトの URL を送信します。 - -# --solutions-- - -```html -// solution required -``` diff --git a/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-tribute-page-project/build-a-tribute-page.md b/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-tribute-page-project/build-a-tribute-page.md deleted file mode 100644 index 9e3e9669fcd..00000000000 --- a/curriculum/challenges/japanese/14-responsive-web-design-22/build-a-tribute-page-project/build-a-tribute-page.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -id: bd7158d8c442eddfaeb5bd18 -title: トリビュートページを作成する -challengeType: 3 -forumTopicId: 301147 -dashedName: build-a-tribute-page ---- - -# --description-- - -**目標:** こちら と同様の機能を持つ [CodePen.io](https://codepen.io) アプリを構築します。 - -以下の[ユーザーストーリー](https://en.wikipedia.org/wiki/User_story)を満たし、すべてのテストがパスするようにしてください。 あなた独自のスタイルを与えてください。 - -このプロジェクトを完了するために、HTML、JavaScript、CSS を使用することができます。 これまでのレッスンでカバーされた純粋な CSS の練習をするため、純粋な CSS の使用を推奨します。 Bootstrap や SASS を使用しても構いません。 このプロジェクトで追加のテクノロジー (jQuery、React、Angular、Vue など) を使用することは推奨されません。使用する場合は自己責任で使用してください。 React のようなさまざまな技術スタックで作業する機会は他のプロジェクトで得られます。 このプロジェクトで推奨される一連のテクノロジーを使用している場合の不具合報告については、freeCodeCamp にて報告を受け入れ、修正するよう努めます。 ハッピーコーディング! - -**ユーザーストーリー #1:** 私のトリビュートページには `id="main"` を持つ要素があり、その中に他のすべての要素が含まれます。 - -**ユーザーストーリー #2:** `id="title"` を持つ要素があり、これにはトリビュートページで取り上げる対象者 (例: "Dr. Norman Borlaug") を説明する文字列 (すなわちテキスト) が記載されています。 - -**ユーザーストーリー #3:** `id="img-div"` を持つ、`figure` または `div` 要素のどちらかが表示される必要があります。 - -**ユーザーストーリー #4:** `img-div` 要素内に、`id="image"` を持つ `img` 要素があります。 - -**ユーザーストーリー #5:** `img-div` 要素内には、`id="img-caption"` を持つ要素があり、`img-div` 内に表示されている画像を説明するテキストコンテンツを含みます。 - -**ユーザーストーリー #6:** `id="tribute-info"` を持つ要素があり、これにはトリビュートページの対象者を説明するテキストコンテンツが含まれます。 - -**ユーザーストーリー #7:** `id="tribute-link"` を持つ `a` 要素があり、これはトリビュートページの対象者に関する追加情報を含む外部サイトへのリンクです。 ヒント: リンクを新しいタブで開くためには、要素に `target` 属性を与え、その値に `_blank` を設定しなければなりません (つまり `target="_blank"` となります)。 - -**ユーザーストーリー #8:** `img` 要素は、オリジナルのサイズを超えることなく、親要素の幅に応じてレスポンシブにサイズが変更される必要があります。 - -**ユーザーストーリー #9:** `img` 要素は、その親要素内で中央に配置される必要があります。 - -この CodePen テンプレートを使用して あなたのプロジェクトを構築することができます。`Save` をクリックすると、あなた用の pen を作成することができます。 または、この CDN リンクを使用して任意の環境でテストを実行できます: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` - -完了したら、すべてのテストがパスする状態の作業プロジェクトの URL を送信します。 - -# --solutions-- - -```html -// solution required -``` diff --git a/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md b/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md index 98406d0b059..0226992eec9 100644 --- a/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md +++ b/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-personal-portfolio-webpage.md @@ -1,47 +1,277 @@ --- id: bd7158d8c242eddfaeb5bd13 -title: Створіть веб-сторінку персонального портфоліо -challengeType: 3 +title: Build a Personal Portfolio Webpage +challengeType: 14 forumTopicId: 301143 dashedName: build-a-personal-portfolio-webpage --- # --description-- -**Мета:** Створити [CodePen.io](https://codepen.io) застосунок, який за своїми функціями нагадує цей: . +**Objective:** Build an app that is functionally similar to https://personal-portfolio.freecodecamp.rocks -Заповніть [ історії користувачів ](https://en.wikipedia.org/wiki/User_story), розміщені нижче, і отримайте доступ до всіх тестів, які потрібно пройти. Виконайте завдання у власному стилі. +**User Stories:** -Ви можете використати HTML, JavaScript, and CSS для виконання цього проєкту. Рекомендовано використовувати звичайний CSS, тому що саме про це розповідається на уроках і вам варто попрактикуватися зі звичайним CSS. Якщо обираєте Bootstrap або SASS, можете користуватися ними. Не бажано використовувати додаткові технології (наприклад: jQuery, React, Angular або Vue), в іншому разі, це лише під вашу власну відповідальність. Під час роботи над іншими проєктами ви зможете попрацювати з різними технологічними стеками, як-от React. Ми візьмемо до уваги і спробуємо виправити всі звіти, що використовують запропонований технологічний стек у цьому проєкті. Вдалого програмування! +1. Your portfolio should have a welcome section with an `id` of `welcome-section` +1. The welcome section should have an `h1` element that contains text +1. Your portfolio should have a projects section with an `id` of `projects` +1. The projects section should contain at least one element with a `class` of `project-tile` to hold a project +1. The projects section should contain at least one link to a project +1. Your portfolio should have a navbar with an id of `navbar` +1. The navbar should contain at least one link that you can click on to navigate to different sections of the page +1. Your portfolio should have a link with an id of `profile-link`, which opens your GitHub or freeCodeCamp profile in a new tab +1. Your portfolio should have at least one media query +1. The height of the welcome section should be equal to the height of the viewport +1. The navbar should always be at the top of the viewport -**Історія користувача #1:** На моєму портфоліо повинен бути розділ-вітання з наступним id `welcome-section`. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**Історія користувача #2:** Розділ для вітання повинен містити елемент `h1` з текстом. +# --hints-- -**Історія користувача #3:** На моєму портфоліо повинен бути розділ з проєктами з id `projects`. +Your portfolio should have a "Welcome" section with an `id` of `welcome-section`. -**Історія користувача #4:** Розділ з проєктами повинен містити щонайменше один елемент класу `project-tile` для зберігання проєктів. +```js +const el = document.getElementById('welcome-section') +assert(!!el); +``` -**Історія користувача #5:** Розділ з проєктами повинен містити щонайменше одне посилання на проєкт. +Your `#welcom-section` element should contain an `h1` element. -**Історія користувача #6:** На моєму портфоліо повинна бути навігаційна панель з id `navbar`. +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1').length, + 0, + 'Welcome section should contain an h1 element ' +); +``` -**Історія користувача #7:** Навігаційна панель повинна містити щонайменше одне посилання, завдяки якому ми могли б перейти на інші розділи сторінки. +You should not have any empty `h1` elements within `#welcome-section` element. -**Історія користувача #8:** На моєму портфоліо повинно бути посилання з id `profile-link`, завдяки якому можна перейти на мої профілі GitHub і FCC у новій вкладці. +```js +assert.isAbove( + document.querySelectorAll('#welcome-section h1')?.[0]?.innerText?.length, + 0, + 'h1 element in welcome section should contain your name or camper ' + + 'name ' +); +``` -**Історія користувача #9:** На моєму портфоліо повинен бути щонайменше один медіа-запит. +You should have a "Projects" section with an `id` of `projects`. -**Історія користувача #10:** Висота розділу з вітанням повинна збігатися з висотою вікна перегляду. +```js +const el = document.getElementById('projects') +assert(!!el); +``` -**Історія користувача #11:** Навігаційна панель повинна розміщуватися у верхній частині вікна перегляду. +Your portfolio should contain at least one elment with a class of `project-tile`. -Ви можете створити проєкт за допомогою using this CodePen template й натиснути `Save` для створення власного фрагмента. Або ж ви можете скористатися цим CDN посиланням для проходження тестів у будь-якому комфортному для вас середовищі:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +assert.isAbove( + document.querySelectorAll('#projects .project-tile').length, + 0 +); +``` -Після завершення прикріпіть URL-адресу із пройденими тестами до проєкту, над яким працюєте. +Your `#projects` element should contain at least one `a` element. -# --solutions-- +```js +assert.isAbove(document.querySelectorAll('#projects a').length, 0); +``` + +Your portfolio should have a navbar with an `id` of `navbar`. + +```js +const el = document.getElementById('navbar'); +assert(!!el); +``` + +Your `#navbar` element should contain at least one `a` element whose `href` attribute starts with `#`. + +```js +const links = [...document.querySelectorAll('#navbar a')].filter( + (nav) => (nav?.getAttribute('href') || '').substr(0, 1) === '#' +); + +assert.isAbove( + links.length, + 0, + 'Navbar should contain an anchor link ' +); +``` + +Your portfolio should have an `a` element with an `id` of `profile-link`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.tagName === 'A') +``` + +Your `#profile-link` element should have a `target` attribute of `_blank`. + +```js +const el = document.getElementById('profile-link'); +assert(!!el && el.target === '_blank') +``` + +Your portfolio should use at least one media query. + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your `#navbar` element should always be at the top of the viewport. + +```js +(async () => { + const timeout = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)); + + const navbar = document.getElementById('navbar'); + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + "Navbar's parent should be body and it should be at the top of " + + 'the viewport ' + ); + + window.scroll(0, 500); + + await timeout(1); + + assert.approximately( + navbar?.getBoundingClientRect().top, + 0, + 15, + 'Navbar should be at the top of the viewport even after ' + + 'scrolling ' + ); + window.scroll(0, 0); +})(); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Personal Portfolio + + + + + +
+
+
+

It's me!

+ +

Naomi Carrigan

+

Welcome to my portfolio page!

+

+
+

Projects

+

Here's what I've worked on!

+

+ + + + +


+
+

Contact me!

+

Use the links below to get in touch.

+

FreeCodeCamp.org | GitHub | Facebook | LinkedIn +

+ + + +``` + +```css +nav{ + position: fixed; + width: 100%; + text-align: right; + font-size: 24pt; + top: 0%; + right: 5px; + background-color: #000000; + color: #ffffff; +} +@media (max-width: 500px){ + nav{ + display: none; + } +} +a{ + color: #ffffff; +} +main{ + text-align: center; + background-color: black; + font-family:Pacifico +} +h1{ + font-size: 48pt; +} +h2{ + font-size: 24pt; +} +p{ + font-size: 12pt; +} +#welcome-section{ + background-color:#251a4a; + color: #FFFFFF; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#projects{ + background-color: #060a9c; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} +#contact{ + background-color: #03300b; + color: #ffffff; + display: table-cell; + vertical-align: middle; + width: 100vw; + height: 100vh; +} ``` diff --git a/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md b/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md index af987d32877..cdd62359751 100644 --- a/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md +++ b/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-product-landing-page.md @@ -1,55 +1,424 @@ --- id: 587d78af367417b2b2512b04 -title: Створіть цільову сторінку продукту -challengeType: 3 +title: Build a Product Landing Page +challengeType: 14 forumTopicId: 301144 dashedName: build-a-product-landing-page --- # --description-- -**Objective:** Створіть застосунок [CodePen.io](https://codepen.io), функціонально схожий на цей: . +**Objective:** Build an app that is functionally similar to https://product-landing-page.freecodecamp.rocks -Заповніть [ історії користувачів ](https://en.wikipedia.org/wiki/User_story), розміщені нижче, і отримайте доступ до всіх тестів, які потрібно пройти. Проявіть при цьому свій власний стиль. +**User Stories:** -Ви можете використати HTML, JavaScript, and CSS для виконання цього проєкту. Рекомендується використовувати звичайну CSS, тому що саме цю мову ви розглядали на уроках раніше і вам потрібно більше попрактикуватися. Якщо обираєте Bootstrap або SASS, можете користуватися ними. Не бажано використовувати додаткові технології (наприклад: jQuery, React, Angular або Vue), в іншому разі, це лише під вашу власну відповідальність. Під час роботи над іншими проєктами ви зможете попрацювати з різними технологічними стеками, як-от React. Ми звернемо увагу на усі запити щодо проблем стосовно рекомендованої технологічної теки для цього проєкту та спробуємо їх вирішити. Вдалого програмування! +1. Your product landing page should have a `header` element with a corresponding `id="header"` +1. You can see an image within the `header` element with a corresponding `id="header-img"` (A logo would make a good image here) +1. Within the `#header` element, you can see a `nav` element with a corresponding `id="nav-bar"` +1. You can see at least three clickable elements inside the `nav` element, each with the class `nav-link` +1. When you click a `.nav-link` button in the `nav` element, you are taken to the corresponding section of the landing page +1. You can watch an embedded product video with `id="video"` +1. Your landing page has a `form` element with a corresponding `id="form"` +1. Within the form, there is an `input` field with `id="email"` where you can enter an email address +1. The `#email` input field should have placeholder text to let users know what the field is for +1. The `#email` input field uses HTML5 validation to confirm that the entered text is an email address +1. Within the form, there is a submit `input` with a corresponding `id="submit"` +1. When you click the `#submit` element, the email is submitted to a static page (use this mock URL: `https://www.freecodecamp.com/email-submit`) +1. The navbar should always be at the top of the viewport +1. Your product landing page should have at least one media query +1. Your product landing page should utilize CSS flexbox at least once -**Історія користувача #1:** На моїй цільовій сторінці продукту повинен бути `header` елемент з відповідним `id="header"`. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**Історія користувача #2:** Я бачу зображення з `header` елементом з відповідним `id="header-img"`. Логотип компанії тут чудово пасуватиме. +# --hints-- -**Історія користувача #3:** У межах `#header` елементу, мені потрібно бачити `nav` елемент з відповідним `id="nav-bar"`. +You should have a `header` element with an `id` of `header` -**Історія користувача #4:** Я бачу щонайменше три клікабельні елементи в `nav` елементі, кожен з яких класу `nav-link`. +```js +const el = document.getElementById('header') +assert(!!el && el.tagName === 'HEADER') +``` -**Історія користувача #5:** Після натискання кнопки `.nav-link` у `nav` елементі я переходжу до відповідного розділу цільової сторінки. +You should have an `img` element with an `id` of `header-img` -**Історія користувача #6:** Я можу переглянути вкладений відеоматеріал з `id="video"`. +```js +const el = document.getElementById('header-img') +assert(!!el && el.tagName === 'IMG') +``` -**Історія користувача #7:** На моїй цільовій сторінці повинен бути `form` елемент з відповідним `id="form"`. +Your `#header-img` should be a descendant of the `#header` -**Історія користувача #8:** У формі наявне `input` поле з `id="email"`, де можна ввести адресу електронної пошти. +```js +const els = document.querySelectorAll('#header #header-img') +assert(els.length > 0) +``` -**Історія користувача #9:** На `#email` полі введення повинно бути місце для заповнення тексту, щоб користувач розумів, для чого це поле. +Your `#header-img` should have a `src` attribute -**Історія користувача #10:** `#email` Поле введення використовує перевірку HTML5, щоб переконатися, що введений текст є електронною поштою. +```js +const el = document.getElementById('header-img') +assert(!!el && !!el.src) +``` -**Історія користувача #11:** У формі є можливість підтвердження `input` з відповідним `id="submit"`. +Your `#header-img`’s `src` value should be a valid URL (starts with `http`) -**Історія користувача #12:** Після натискання `#submit` елементу, електронна пошта відправляють на статичну сторінку (використовуйте цю альтернативну URL-адресу: ). +```js +const el = document.getElementById('header-img') +assert(!!el && /^http/.test(el.src)) +``` -**Історія користувача #13:** Навігаційна панель повинна розміщуватися у верхній частині вікна перегляду. +You should have a `nav` element with an `id` of `nav-bar` -**Історія користувача #14:** На моїй цільовій сторінці продукту повинен бути щонайменше один медіа-запит. +```js +const el = document.getElementById('nav-bar') +assert(!!el && el.tagName === 'NAV') +``` -**Історія користувача #15:** Моя цільова сторінка продукту повинна використовувати CSS Flexbox щонайменше один раз. +Your `#nav-bar` should be a descendant of the `#header` -Ви можете створити свій проєкт using this CodePen template і натиснувши `Save`, аби створити власний фрагмент. Або ви можете використати це посилання CDN для запуску тестів у будь-якому середовищі, яке вам подобається: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +const els = document.querySelectorAll('#header #nav-bar') +assert(els.length > 0) +``` -Після завершення прикріпіть URL адресу із пройденими тестами до проєкту, над яким працюєте. +You should have at least 3 `.nav-link` elements within the `#nav-bar` -# --solutions-- +```js +const els = document.querySelectorAll('#nav-bar .nav-link') +assert(els.length >= 3) +``` + +Each `.nav-link` element should have an `href` attribute + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (!el.href) assert(false) +}) +assert(els.length > 0) +``` + +Each `.nav-link` element should link to a corresponding element on the landing page (has an `href` with a value of another element's id. e.g. `#footer`) + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + const linkDestination = el.getAttribute('href').slice(1) + if (!document.getElementById(linkDestination)) assert(false) +}) +assert(els.length > 0) +``` + +You should have a `video` or `iframe` element with an `id` of `video` + +```js +const el = document.getElementById('video') +assert(!!el && (el.tagName === 'VIDEO' || el.tagName === 'IFRAME')) +``` + +Your `#video` should have a `src` attribute + +```js +const el = document.getElementById('video') +assert(!!el && !!el.src) +``` + +You should have a `form` element with an `id` of `form` + +```js +const el = document.getElementById('form') +assert(!!el && el.tagName === 'FORM') +``` + +You should have an `input` element with an `id of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #email') +assert(els.length > 0) +``` + +Your `#email` should have the `placeholder` attribute with placeholder text + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should use HTML5 validation by setting its `type` to `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +You should have an `input` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#submit` should be a descendant of the `#form` + +```js +const els = document.querySelectorAll('#form #submit') +assert(els.length > 0) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#form` should have an `action` attribute of `https://www.freecodecamp.com/email-submit` + +```js +const el = document.getElementById('form') +assert(!!el && el.action === 'https://www.freecodecamp.com/email-submit') +``` + +Your `#email` should have a `name` attribute of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.name === 'email') +``` + +Your `#nav-bar` should always be at the top of the viewport + +```js +const el = document.getElementById('nav-bar') +const top1 = el?.offsetTop +const top2 = el?.offsetTop +assert(!!el && top1 >= -15 && top1 <= 15 && top2 >= -15 && top2 <= 15) +``` + +Your Product Landing Page should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +Your Product Landing Page should use CSS Flexbox at least once + +```js +const stylesheet = new __helpers.CSSHelp(document).getStyleSheet() +const cssRules = new __helpers.CSSHelp(document).styleSheetToCssRulesArray(stylesheet) +const usesFlex = cssRules.find(rule => { + return rule.style?.display === 'flex' || rule.style?.display === 'inline-flex' +}) +assert(usesFlex) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Product Landing Page + + + +
+

+ Pokemon Daycare Service +

+
+

What we offer

+
+
+ +
+
Guaranteed friendly and loving staff!
+
+
+
+ +
+
+ Comfortable environment for Pokemon to explore and play! +
+
+
+
+ +
+
+ Multiple membership plans to fit your lifestyle! +
+
+
+
+

Check us out!

+ A sneak peek into our facility: +
+ +
+
+

Membership Plans

+
+
+ Basic Membership
+
    +
  • One Pokemon
  • +
  • Food and berries provided
  • +
+ $9.99/month +
+
+ Silver Membership
+
    +
  • Up to Three Pokemon
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
+ $19.99/month +
+
+ Gold Membership
+
    +
  • Up to six Pokemon!
  • +
  • Food and berries provided
  • +
  • Grooming and accessories included
  • +
  • Personal training for each Pokemon
  • +
  • Breeding and egg hatching
  • +
+ $29.99/month +
+
+
+
+

Sign up for our newsletter!

+ + +
+ +
+ + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + max-width: 750px; + margin: 50px auto; +} +input { + background-color: #92869c; +} +a:not(.nav-link) { + color: white; +} +#header-img { + max-height: 25px; +} +#nav-bar { + position: fixed; + width: 100%; + text-align: center; + top: 0%; + background-color: #92869c; +} +h1 { + text-align: center; +} +body { + text-align: center; +} +footer { + text-align: center; +} +#bullet { + max-height: 25px; +} +.flex-here { + display: flex; + justify-content: center; +} +.flex-left { + height: 25px; +} +.flex-mem { + display: flex; + justify-content: center; +} +.flex-mem-box { + background-color: #92869c; + border-color: black; + border-width: 5px; + border-style: solid; + margin: 10px; + padding: 10px; + color: black; +} +@media (max-width: 350px) { + #video { + width: 300; + height: 200; + } +} ``` diff --git a/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md b/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md index 797744c72d5..937c4482c93 100644 --- a/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md +++ b/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-survey-form.md @@ -1,57 +1,516 @@ --- id: 587d78af367417b2b2512b03 -title: Створіть форму для опитування -challengeType: 3 +title: Build a Survey Form +challengeType: 14 forumTopicId: 301145 dashedName: build-a-survey-form --- # --description-- -**Objective:** Створіть застосунок [CodePen.io](https://codepen.io), функціонально схожий на цей: . +**Objective:** Build an app that is functionally similar to https://survey-form.freecodecamp.rocks -Заповніть нижче [ історії користувача](https://en.wikipedia.org/wiki/User_story) та отримаєте тести для проходження. Проявіть при цьому свій власний стиль. +**User Stories:** -Ви можете використовувати HTML, JavaScript, та CSS, щоб завершити цей проєкт. Рекомендується використовувати звичайну CSS, тому що саме цю мову ви розглядали на уроках раніше і вам потрібно більше попрактикуватися. Якщо обираєте Bootstrap або SASS, можете користуватися ними. Для цього проєкту не рекомендовані додаткові застосунки (як наприклад, jQuery, React, Angular, чи Vue). Ви ризикуєте, використовуючи їх. Під час роботи над іншими проєктами ви зможете попрацювати з різними технологічними стеками, як-от React. Ми візьмемо до уваги і спробуємо виправити всі звіти, що використовують запропонований технологічний стек у цьому проєкті. Вдалого кодування! +1. You should have a page title in an `h1` element with an `id` of `title` +1. You should have a short explanation in a `p` element with an `id` of `description` +1. You should have a `form` element with an `id` of `survey-form` +1. Inside the form element, you are **required** to enter your name in an `input` field that has an `id` of `name` and a `type` of `text` +1. Inside the form element, you are **required** to enter your email in an `input` field that has an `id` of `email` +1. If you enter an email that is not formatted correctly, you will see an HTML5 validation error +1. Inside the form, you can enter a number in an `input` field that has an `id` of `number` +1. If you enter non-numbers in the number input, you will see an HTML5 validation error +1. If you enter numbers outside the range of the number input, which are defined by the `min` and `max` attributes, you will see an HTML5 validation error +1. For the name, email, and number input fields, you can see corresponding `label` elements in the form, that describe the purpose of each field with the following ids: `id="name-label"`, `id="email-label"`, and `id="number-label"` +1. For the name, email, and number input fields, you can see placeholder text that gives a description or instructions for each field +1. Inside the form element, you should have a `select` dropdown element with an `id` of `dropdown` and at least two options to choose from +1. Inside the form element, you can select an option from a group of at least two radio buttons that are grouped using the `name` attribute +1. Inside the form element, you can select several fields from a series of checkboxes, each of which must have a `value` attribute +1. Inside the form element, you are presented with a `textarea` for additional comments +1. Inside the form element, you are presented with a button with `id` of `submit` to submit all the inputs -**Історія користувача #1: **Я можу бачити заголовок `id="title"` текстом розміром Н1. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**Історія користувача #2: ** Я можу бачити коротке пояснення `id="description"` текстом розміром P. +# --hints-- -** історія користувача #3:** я бачу форму `` с `id="survey-form"`. +You should have an `h1` element with an `id` of `title` -**Історія користувача #4:** Всередині елементу форми, мені необхідно ввести ім'я в поле з `id="name"`. +```js +const el = document.getElementById('title') +assert(!!el && el.tagName === 'H1') +``` -**Історія користувача #5:** Всередині елементу форми, мені необхідно ввести електронну пошту у полі з `id="email"`. +Your `#title` should not be empty -**Історія користувача #6:** Якщо я введу електронну пошту, неправильно відформатовану, я побачу помилку перевірки HTML5. +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) +``` -**Історія користувача #7:** Всередині форми я можу ввести число у полі `id="number"`. +You should have a `p` element with an `id` of `description` -**Історія користувача #8:** Якщо я введу не числа з номером введення, я побачу помилку перевірки HTML5. +```js +const el = document.getElementById('description') +assert(!!el && el.tagName === 'P') +``` -**Історія користувача #9:** Якщо я введу числа поза межами діапазону введення, що позначені по `min` and `max` атрибутам, я побачу помилку перевірки HTML5. +Your `#description` should not be empty -**Історія користувача #10:** Для назви, електронної пошти і поля введення чисел у межах форми, я можу побачити, що відповідні ярлики, які описують призначення кожного поля, супроводжуються певними ідентифікаторами: `id="name-label"`, `id="email-label"`, й `id="number-label"`. +```js +const el = document.getElementById('description') +assert(!!el && el.innerText.length > 0) +``` -**Історія користувача #11:** У полі введення назви, електронної пошти та ін., я можу побачити надані текстом заповнювача описи або інструкції для кожного з полів. +You should have a `form` element with an `id` of `survey-form` -**Історія користувача #12:** Всередині елементу форми я можу обрати варіант зі спадного списку зі відповідним `id="dropdown"`. +```js +const el = document.getElementById('survey-form') +assert(!!el && el.tagName === 'FORM') +``` -**Історія користувача #13:** У межах форми кожного елементу я можу обрати поля з однієї чи більше групи радіокнопок. Кожна група повинна бути згрупована зі використанням `name` атрибуту. +You should have an `input` element with an `id` of `name` -**Історія користувача #14:** Я можу обрати декілька полів всередині форми елементу зі серії прапорців, кожен з яких повинен мати атрибут `value`. +```js +const el = document.getElementById('name') +assert(!!el && el.tagName === 'INPUT') +``` -**Історія користувача #15:** Всередині форми елементу наприкінці я надаю `textarea` для додаткових коментарів. +Your `#name` should have a `type` of `text` -**Історія користувача #16:** Я можу затвердити усі внесені дані у форму елементу за допомогою кнопки `id="submit"`. +```js +const el = document.getElementById('name') +assert(!!el && el.type === 'text') +``` -Ви можете створити проєкт за допомогою using this CodePen template й натиснути `Save` для створення власного фрагмента. Або ви можете використати CDN посилання для проведення тесту у будь-якому середовищі: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +Your `#name` should require input -Після завершення надайте посилання до вашого проєкту з усіма пройденими тестами. +```js +const el = document.getElementById('name') +assert(!!el && el.required) +``` -# --solutions-- +Your `#name` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name') +assert(!!el) +``` + +You should have an `input` element with an `id` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#email` should have a `type` of `email` + +```js +const el = document.getElementById('email') +assert(!!el && el.type === 'email') +``` + +Your `#email` should require input + +```js +const el = document.getElementById('email') +assert(!!el && el.required) +``` + +Your `#email` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email') +assert(!!el) +``` + +You should have an `input` element with an `id` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.tagName === 'INPUT') +``` + +Your `#number` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number') +assert(!!el) +``` + +Your `#number` should have a `type` of `number` + +```js +const el = document.getElementById('number') +assert(!!el && el.type === 'number') +``` + +Your `#number` should have a `min` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.min && isFinite(el.min)) +``` + +Your `#number` should have a `max` attribute with a numeric value + +```js +const el = document.getElementById('number') +assert(!!el && el.max && isFinite(el.max)) +``` + +You should have a `label` element with an `id` of `name-label` + +```js +const el = document.getElementById('name-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `email-label` + +```js +const el = document.getElementById('email-label') +assert(!!el && el.tagName === 'LABEL') +``` + +You should have a `label` element with an `id` of `number-label` + +```js +const el = document.getElementById('number-label') +assert(!!el && el.tagName === 'LABEL') +``` + +Your `#name-label` should not be empty + +```js +const el = document.getElementById('name-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#email-label` should not be empty + +```js +const el = document.getElementById('email-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#number-label` should not be empty + +```js +const el = document.getElementById('number-label') +assert(!!el && el.innerText.length > 0) +``` + +Your `#name-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #name-label') +assert(!!el) +``` + +Your `#email-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #email-label') +assert(!!el) +``` + +Your `#number-label` should be a descedant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #number-label') +assert(!!el) +``` + +Your `#name` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('name') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#email` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('email') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +Your `#number` should have a `placeholder` attribute and value + +```js +const el = document.getElementById('number') +assert(!!el && !!el.placeholder && el.placeholder.length > 0) +``` + +You should have a `select` field with an `id` of `dropdown` + +```js +const el = document.getElementById('dropdown') +assert(!!el && el.tagName === 'SELECT') +``` + +Your `#dropdown` should have at least two selectable (not disabled) `option` elements + +```js +const els = document.querySelectorAll('#dropdown option:not([disabled])') +assert(els.length >= 2) +``` + +Your `#dropdown` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #dropdown') +assert(!!el) +``` + +You should have at least two `input` elements with a `type` of `radio` (radio buttons) + +```js +const els = document.querySelectorAll('input[type="radio"]') +assert(els.length >= 2) +``` + +You should have at least two radio buttons that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="radio"]') +assert(els.length >= 2) +``` + +All your radio buttons should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][value=""], input[type="radio"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +All your radio buttons should have a `name` attribute and value + +```js +const els1 = document.querySelectorAll('input[type="radio"]') +const els2 = document.querySelectorAll('input[type="radio"][name=""], input[type="radio"]:not([name])') +assert(els1.length > 0 && els2.length === 0) +``` + +Every radio button group should have at least 2 radio buttons + +```js +const radioButtons = document.querySelectorAll('input[type="radio"]'); +const groups = {} + +if (radioButtons) { + radioButtons.forEach(el => { + if (!groups[el.name]) groups[el.name] = [] + groups[el.name].push(el) + }) +} + +const groupKeys = Object.keys(groups) + +groupKeys.forEach(key => { + if (groups[key].length < 2) assert(false) +}) + +assert(groupKeys.length > 0) +``` + +You should have at least two `input` elements with a `type` of `checkbox` (checkboxes) that are descendants of `#survey-form` + +```js +const els = document.querySelectorAll('#survey-form input[type="checkbox"]'); +assert(els.length >= 2) +``` + +All your checkboxes inside `#survey-form` should have a `value` attribute and value + +```js +const els1 = document.querySelectorAll('#survey-form input[type="checkbox"]') +const els2 = document.querySelectorAll('#survey-form input[type="checkbox"][value=""], #survey-form input[type="checkbox"]:not([value])') +assert(els1.length > 0 && els2.length === 0) +``` + +You should have at least one `textarea` element that is a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form textarea') +assert(!!el) +``` + +You should have an `input` or `button` element with an `id` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && (el.tagName === 'INPUT' || el.tagName === 'BUTTON')) +``` + +Your `#submit` should have a `type` of `submit` + +```js +const el = document.getElementById('submit') +assert(!!el && el.type === 'submit') +``` + +Your `#submit` should be a descendant of `#survey-form` + +```js +const el = document.querySelector('#survey-form #submit') +assert(!!el) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Survey Form + + +

Survey Form

+

The card below was built as a sample survey form for freeCodeCamp.

+
+

Join the Togepi Fan Club!

+

+ Enter your information here to receive updates about club activities, + our monthly newsletter, and other email communications. +

+
+ + + + +

Who is your favourite Pokemon?

+ + + +

Which communications do you want to receive?

+ + + +

Any other information you would like to share?

+ +

+ Please note: This form is a proof of concept. Submitting the form + will not actually transmit your data. +

+ +
+
+ + + +``` + +```css +main { + text-align: center; + background-color: #92869c; + background-blend-mode: lighten; + max-width: 500px; + margin: 20px auto; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); + color: black; +} +body { + text-align: center; + background: #3a3240; + color: white; +} +input, textarea, select, button { + background: #3a3240; + color: white; +} +a { + color: white; +} ``` diff --git a/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md b/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md index 3742fd729bc..6c433375ba7 100644 --- a/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md +++ b/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-technical-documentation-page.md @@ -1,55 +1,525 @@ --- id: 587d78b0367417b2b2512b05 -title: Створіть сторінку технічної документації -challengeType: 3 +title: Build a Technical Documentation Page +challengeType: 14 forumTopicId: 301146 dashedName: build-a-technical-documentation-page --- # --description-- -**Objective:** Створіть застосунок [CodePen.io](https://codepen.io), функціонально схожий на цей: . +**Objective:** Build an app that is functionally similar to https://technical-documentation-page.freecodecamp.rocks -Заповніть [user stories](https://en.wikipedia.org/wiki/User_story), розміщені нижче, та отримайте доступ до тестів, які потрібно пройти. Проявіть при цьому свій власний стиль. +**User Stories:** -Ви можете використати HTML, JavaScript, and CSS для виконання цього проєкту. Рекомендується використовувати звичайну CSS, тому що саме цю мову ви розглядали на уроках раніше і вам потрібно більше відповідної практики. Якщо обираєте Bootstrap або SASS, можете користуватися ними. Не бажано використовувати додаткові технології (наприклад: jQuery, React, Angular або Vue), в іншому разі, це лише під вашу власну відповідальність. Під час роботи над іншими проєктами ви зможете попрацювати з різними технологічними стеками, як-от React. Ми візьмемо до уваги і спробуємо виправити всі звіти, що використовують запропонований технологічний стек у цьому проєкті. Вдалого програмування! +1. You can see a `main` element with a corresponding `id="main-doc"`, which contains the page's main content (technical documentation) +1. Within the `#main-doc` element, you can see several `section` elements, each with a class of `main-section`. There should be a minimum of five +1. The first element within each `.main-section` should be a `header` element, which contains text that describes the topic of that section. +1. Each `section` element with the class of `main-section` should also have an `id` that corresponds with the text of each `header` contained within it. Any spaces should be replaced with underscores (e.g. The section that contains the header "JavaScript and Java" should have a corresponding `id="JavaScript_and_Java"`) +1. The `.main-section` elements should contain at least ten `p` elements total (not each) +1. The `.main-section` elements should contain at least five `code` elements total (not each) +1. The `.main-section` elements should contain at least five `li` items total (not each) +1. You can see a `nav` element with a corresponding `id="navbar"` +1. The navbar element should contain one `header` element which contains text that describes the topic of the technical documentation +1. Additionally, the navbar should contain link (`a`) elements with the class of `nav-link`. There should be one for every element with the class `main-section` +1. The `header` element in the `#navbar` must come before any link (`a`) elements in the navbar +1. Each element with the class of `nav-link` should contain text that corresponds to the `header` text within each `section` (e.g. if you have a "Hello world" section/header, your navbar should have an element which contains the text "Hello world") +1. When you click on a navbar element, the page should navigate to the corresponding section of the `main-doc` element (e.g. If you click on a `nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id, and contains the corresponding header) +1. On regular sized devices (laptops, desktops), the element with `id="navbar"` should be shown on the left side of the screen and should always be visible to the user +1. Your technical documentation should use at least one media query -**Історія користувача #1:** Я бачу `main` елемент з відповідним `id="main-doc"`, який містить основний вміст сторінки (технічна документація). +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -**Історія користувача #2:** У межах `#main-doc` елементу, я бачу декілька `section` елементів, кожен з яких класу `main-section`. Їх повинно бути щонайменше 5. +# --hints-- -**Історія користувача #3:** Перший елемент у межах кожного `.main-section` повинен бути `header` елементом, який містить текст, що описує тему конкретного розділу. +You should have a `main` element with an `id` of `main-doc` -**Історія користувача #4:** Кожен `section` елемент класу `main-section` також повинен мати id, який за текстом відповідає кожному `header`, що міститься в ньому. Будь-який пробіл потрібно замінити знаком підкреслення (наприклад `section`, який містить заголовок "JavaScript і Java", повинен мати відповідний `id="JavaScript_and_Java"`). +```js +const el = document.getElementById('main-doc') +assert(!!el) +``` -**Історія користувача #5:** `.main-section` елементи повинні містити щонайменше 10 `p` елементів загалом (не кожен). +You should have at least five `section` elements with a class of `main-section` -**Історія користувача #6:** `.main-section` елементи повинні містити щонайменше 5 `code` елементів загалом (не кожен). +```js +const els = document.querySelectorAll('#main-doc section') +assert(els.length >= 5) +``` -**Історія користувача #7:** `.main-section` елементи повинні містити щонайменше 5 `li` елементів загалом (не кожен). +All of your `.main-section` elements should be `section` elements -** Історія користувача #8:** Я бачу `nav` елемент з відповідними `id="navbar"`. +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (el.tagName !== 'SECTION') assert(false) +}) +assert(els.length > 0) +``` -**Історія користувача #9:** Елемент панелі навігації повинен містити один `header` елемент, який включає текст, що описує тему технічної документації. +You should have at least five `.main-section` elements that are descendants of `#main-doc` -**Історія користувача #10:** Крім того, навігаційна панель повинна містити (`a`) елементи посилань класу `nav-link`. На кожен елемент класу `main-section` має бути одне посилання. +```js +const els = document.querySelectorAll('#main-doc .main-section') +assert(els.length >= 5) +``` -**Історія користувача #11:**`header` елемент в межах навігаційної панелі повинен розміщуватися перед елементами (`a`) посилань. +The first child of each `.main-section` should be a `header` element -**Історія користувача #12:** Кожен елемент класу `nav-link` повинен містити текст, який відповідає `header` тексту у кожній `section` (наприклад, якщо у вас є розділ/заголовок "Вітаю, світе", ваша навігаційна панель повинна мати елемент, що містить текст "Вітаю, світе"). +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if(el.firstElementChild?.tagName !== 'HEADER') assert(false) +}) +assert(els.length > 0) +``` -**Історія користувача #13:** При натисканні на елемент навігаційної панелі, сторінка повинна скеровувати до відповідного розділу `main-doc` елементу (наприклад, у разі натискання на `nav-link` елемент, що містить текст "Вітаю, світе", сторінка скеровує до `section` елементу із таким же id та відповідним `header`. +None of your `header` elements should be empty -**Історія користувача #14:** На пристроях типової величини (ноутбуки, комп'ютери) елемент з `id="navbar"` повинен відображатися ліворуч на екрані і завжди бути видимим для користувача. +```js +const els = document.querySelectorAll('header') +els.forEach(el => { + if (el.innerText?.length <= 0) assert(false) +}) +assert(els.length > 0) +``` -**Історія користувача #15:** Моя сторінка технічної документації повинна використовувати щонайменше один медіа-запит. +All of your `.main-section` elements should have an `id` -Ви можете створити свій проєкт за допомогою , використовуючи цей CodePen зразок і натиснувши `Save`, щоб створити власний фрагмент. Або ви можете використати це посилання CDN для запуску тестів у будь-якому середовищі, яке вам подобається: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + if (!el.id || el.id === '') assert(false) +}) +assert(els.length > 0) +``` -Після завершення прикріпіть URL адресу із пройденими тестами до проєкту, над яким працюєте. +Each `.main-section` should have an `id` that matches the text of its first child, having any spaces in the child's text replaced with underscores (`_`) for the id’s -# --solutions-- +```js +const els = document.querySelectorAll('.main-section') +els.forEach(el => { + const text = el.firstElementChild?.innerText?.replaceAll(' ', '_') + if (el.id?.toUpperCase() !== text?.toUpperCase()) assert(false) +}) +assert(els.length > 0) +``` + +You should have at least 10 `p` elements (total) within your `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section p') +assert(els.length >= 10) +``` + +You should have at least five `code` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section code') +assert(els.length >= 5) +``` + +You should have at least five `li` elements that are descendants of `.main-section` elements + +```js +const els = document.querySelectorAll('.main-section li') +assert(els.length >= 5) +``` + +You should have a `nav` element with an `id` of `navbar` + +```js +const el = document.getElementById('navbar') +assert(!!el && el.tagName === 'NAV') +``` + +Your `#navbar` should have exactly one `header` element within it + +```js +const els = document.querySelectorAll('#navbar header') +assert(els.length === 1) +``` + +You should have at least one `a` element with a class of `nav-link` + +```js +const els = document.querySelectorAll('a[class="nav-link"]') +assert(els.length >= 1) +``` + +All of your `.nav-link` elements should be anchor (`a`) elements + +```js +const els = document.querySelectorAll('.nav-link') +els.forEach(el => { + if (el.tagName !== 'A') assert(false) +}) +assert(els.length > 0) +``` + +All of your `.nav-link` elements should be in the `#navbar` + +```js +const els1 = document.querySelectorAll('.nav-link') +const els2 = document.querySelectorAll('#navbar .nav-link') +assert(els2.length > 0 && els1.length === els2.length) +``` + +You should have the same number of `.nav-link` and `.main-section` elements + +```js +const els1 = document.querySelectorAll('.main-section') +const els2 = document.querySelectorAll('.nav-link') +assert(els1.length > 0 && els2.length > 0 && els1.length === els2.length) +``` + +The `header` element in the `#navbar` should come before any link (`a`) elements also in the `#navbar` + +```js +const navLinks = document.querySelectorAll('#navbar a.nav-link'); +const header = document.querySelector('#navbar header'); +navLinks.forEach((navLink) => { + if ( + ( + header.compareDocumentPosition(navLink) & + Node.DOCUMENT_POSITION_PRECEDING + ) + ) assert(false) +}); +assert(!!header) +``` + +Each `.nav-link` should have text that corresponds to the `header` text of its related `section` (e.g. if you have a "Hello world" section/header, your `#navbar` should have a `.nav-link` which has the text "Hello world") + +```js +const headerText = Array.from(document.querySelectorAll('.main-section')).map(el => + el.firstElementChild?.innerText?.trim().toUpperCase() +) +const linkText = Array.from(document.querySelectorAll('.nav-link')).map(el => + el.innerText?.trim().toUpperCase() +) +const remainder = headerText.filter(str => linkText.indexOf(str) === -1) +assert(headerText.length > 0 && headerText.length > 0 && remainder.length === 0) +``` + +Each `.nav-link` should have an `href` attribute that links to its corresponding `.main-section` (e.g. If you click on a `.nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id) + +```js +const hrefValues = Array.from(document.querySelectorAll('.nav-link')).map(el => el.getAttribute('href')) +const mainSectionIDs = Array.from(document.querySelectorAll('.main-section')).map(el => el.id) +const missingHrefValues = mainSectionIDs.filter(str => hrefValues.indexOf('#' + str) === -1) +assert(hrefValues.length > 0 && mainSectionIDs.length > 0 && missingHrefValues.length === 0) +``` + +Your `#navbar` should always be on the left edge of the window + +```js +const el = document.getElementById('navbar') +const left1 = el?.offsetLeft +const left2 = el?.offsetLeft +assert(!!el && left1 >= -15 && left1 <= 15 && left2 >= -15 && left2 <= 15) +``` + +Your Technical Documentation project should use at least one media query + +```js +assert.isAtLeast(new __helpers.CSSHelp(document).getCSSRules('media')?.length, 1); +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + Technical Documentation Page + + + +
+
+
Introduction
+

+ Welcome to a basic introduction of algebra. In this tutorial, we will + review some of the more common algebraic concepts. +

+
+
+
Definitions
+

+ To start with, let's define some of the more common terms used in + algebra: +

+
    +
  • + Variable: A variable is an unknown value, usually represented + by a letter. +
  • +
  • + Expression: Essentially a mathematical object. For the + purpose of this tutorial, an expression is one part of an equation. +
  • +
  • + Equation: An equation is a mathematical argument in which two + expressions result in the same value. +
  • +
+
+
+
Examples
+

+ Sometimes it is easier to understand the definitions when you have a + physical example to look at. Here is an example of the above terms.

+ x + 5 = 12

+ In this above example, we have: +

+
    +
  • Variable: The variable in the example is "x".
  • +
  • + Expression: There are two expressions in this example. They + are "x+5" and "12". +
  • +
  • + Equation: The entire example, "x+5=12", is an equation. +
  • +
+
+
+
Solving Equations
+

+ The primary use for algebra is to determine an unknown value, the + "variable", with the information provided. Continuing to use our + example from above, we can find the value of the variable "x".

+ x + 5 = 12

+ In an equation, both sides result in the same value. So you can + manipulate the two expressions however you need, as long as you + perform the same operation (or change) to each side. You do this + because the goal when solving an equation is to + get the variable into its own expression, or by itself on one side + of the = sign.
For this example, we want to remove the "+5" so the "x" is + alone. To do this, we can subtract 5, because subtraction is + the opposite operation to addition. But remember, we have to perform + the same operation to both sides of the equation. Now our equation + looks like this.

+ x + 5 - 5 = 12 - 5

+ The equation looks like a mess right now, because we haven't completed + the operations. We can simplify this equation to make it easier + to read by performing the operations "5-5" and "12-5". The result + is:

+ x = 7

+ We now have our solution to this equation! +

+
+
+
Solving Equations II
+

+ Let us look at a slightly more challenging equation.

+ 3x + 4 = 13

+ Again we can start with subtraction. In this case, we want to subtract + 4 from each side of the equation. We will also go ahead and simplify + with each step. So now we have:

+ 3x = 9

+ "3x" translates to "3*x", where the "*" symbol indicates + multiplication. We use the "*" to avoid confusion, as the "x" is now a + variable instead of a multiplication symbol. The opposite operation + for multiplication is division, so we need to + divide each expression by 3.

+ x = 3

+ And now we have our solution! +

+
+
+
Solving Equations III
+

+ Now we are getting in to more complex operations. Here is another + equation for us to look at:

+ x^2 - 8 = 8

+ Our very first step will be to add 8 to each side. This is + different from our previous examples, where we had to subtract. But + remember, our goal is to get the variable alone by performing opposite + operations.

+ x^2 = 16

+ But what does the "^2" mean? The "^" symbol is used to denote + exponents in situations where superscript is not available. When + superscript is available, you would see it as x2. + For the sake of this project, however, we will use the "^" symbol.
+ An exponent tells you how many times the base (in our case, "x") is + multiplied by itself. So, "x^2" would be the same as "x*x". Now the + opposite function of multiplication is division, but we would have to + divide both sides by "x". We do not want to do this, as that + would put an "x" on the other side of the equation. So instead, we + need to use the root operation! For an exponent of "2", we call this + the "square root" and denote it with "√". Our equation is now: +

+ x = √9

+ Performing a root operation by hand can be a tedious process, so we + recommend using a calculator when necessary. However, we are lucky in + that "9" is a + perfect square, so we do not need to calculate anything. Instead, we find our + answer to be:

+ x = 3 +

+
+
+
System of Equations
+

+ As you explore your algebra studies further, you may start to run + across equations with more than one variable. The first such equations + will likely look like:

+ y = 3x

+ An equation like this does not have one single solution. + Rather, there are a series of values for which the equation is true. + For example, if "x=3" and "y=9", the equation is true. These equations + are usually used to plot a graph.
+ Getting more complicated, though, you may be given a pair of + equations. This is called a "system of equations", and CAN be solved. + Let's look at how we do this! Consider the following system of + equations:

+ y = 3x | y - 6 = x + A system of equations IS solvable, but it is a multi-step process. To + get started, we need to chose a variable we are solving for. Let's + solve for "x" first. From the second equation, we know that "x" equals + "y - 6", but we cannot simplify that further because we do not have a + value for "y". Except, thanks to the system of equations, we DO have a + value for "y". We know that "y" equals "3x". So, looking at our second + equation, we can replace "y" with "3x" because they have the same + value. We then get:

+ 3x - 6 = x

+ Now we can solve for "x"! We start by adding 6 to each side.

+ 3x = x + 6

+ We still need to get "x" by itself, so we subtract "x" from both sides + and get:

+ 2x = 6

+ If this confuses you, remember that "3x" is the same as "x+x+x". + Subtract an "x" from that and you get "x+x", or "2x". Now we divide + both sides by 2 and have our value for x!

+ x = 3

+ However, our work is not done yet. We still need to find the value for + "y". Let's go back to our first equation:

+ y = 3x

+ We have a value for "x" now, so let's see what happens if we put that + value in.

+ y = 3*3

+ We perform the multiplication and discover that "y=9"! Our solution to + this system of equations then is:

+ x = 3 and y = 9

+

+
+
+
Try it Yourself!
+

Coming Soon!

+

Keep an eye out for new additions!

+
+
+
More Information
+

Check out the following links for more information!

+ +
+
+ + + +``` + +```css +* { + background-color: #3a3240; +} +a { + color: #92869c; +} +a:hover { + background-color: #92869c; + color: #3a3240; +} +#navbar { + border-style: solid; + border-width: 5px; + border-color: #92869c; + height: 100%; + top: -5px; + left: -5px; + padding: 5px; + text-align: center; + color: #92869c +} +@media (min-width: 480px) { + #navbar { + position: fixed; + } +} +main { + margin-left: 220px; + color: #92869c +} +header { + font-size: 20pt; +} +code { + background-color: #92869c; + border-style: dashed; + border-width: 2px; + border-color: #92869c; + padding: 5px; + color: black; +} +footer { + text-align: center; +} ``` diff --git a/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md b/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md index 4c10de277d0..231292b4373 100644 --- a/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md +++ b/curriculum/challenges/ukrainian/01-responsive-web-design/responsive-web-design-projects/build-a-tribute-page.md @@ -1,43 +1,327 @@ --- id: bd7158d8c442eddfaeb5bd18 -title: Створіть пам'ятну сторінку -challengeType: 3 +title: Build a Tribute Page +challengeType: 14 forumTopicId: 301147 dashedName: build-a-tribute-page --- # --description-- -**Завдання:** Створіть [CodePen.io](https://codepen.io) застосунок, який схожий за функціями на:. +**Objective:** Build an app that is functionally similar to https://tribute-page.freecodecamp.rocks -Нижче заповніть [ історії користувачів ](https://en.wikipedia.org/wiki/User_story) і отримайте доступ до тестів, котрі потрібно пройти. Виконайте завдання у власному стилі. +**User Stories:** -Ви можете використати HTML, JavaScript, and CSS для завершення цього проєкту. Рекомендується використовувати звичайну CSS, тому що саме цю мову ви розглядали на уроках раніше і вам потрібно більше попрактикуватися. Якщо ви оберете Bootstrap або SASS, то можете користуватися ними. Не бажано використовувати додаткові технології (наприклад: jQuery, React, Angular або Vue), в іншому разі, це лише під вашу власну відповідальність. Під час роботи над іншими проєктами ви зможете попрацювати з різними технологічними стеками, як-от React. Ми візьмемо до уваги і спробуємо виправити всі звіти, що використовують запропонований технологічний стек у цьому проєкті. Вдалого програмування! +1. Your tribute page should have an element with a corresponding `id="main"`, which contains all other elements +1. You should see an element with an `id` of `title`, which contains a string (i.e. text), that describes the subject of the tribute page (e.g. "Dr. Norman Borlaug") +1. You should see either a `figure` or a `div` element with an `id` of `img-div` +1. Within the `img-div` element, you should see an `img` element with a corresponding `id="image"` +1. Within the `img-div` element, you should see an element with a corresponding `id="img-caption"` that contains textual content describing the image shown in `img-div` +1. You should see an element with a corresponding `id="tribute-info"`, which contains textual content describing the subject of the tribute page +1. You should see an a element with a corresponding `id="tribute-link"`, which links to an outside site, that contains additional information about the subject of the tribute page. HINT: You must give your element an attribute of `target` and set it to `_blank` in order for your link to open in a new tab +1. Your `#image` should use `max-width` and `height` properties to resize responsively, relative to the width of its parent element, without exceeding its original size +1. Your `img` element should be centered within its parent element -** Історія користувача #1:** Моя пам'ятна сторінка повинна містити елемент з відповідним `id="main"`, котрий містить усі інші елементи. +Fulfill the user stories and pass all the tests below to complete this project. Give it your own personal style. Happy Coding! -** Історія користувача #2: ** Мені потрібно бачити елемент з відповідним `id="title"`, котрий містить рядок (наприклад текст) і описує тему пам'ятної сторінки. (наприклад "Лікар Норман Борлау"). +# --hints-- -** Історія користувача #3:** Мені потрібно бачити або `figure`, або `div` елемент з відповідними `id="img-div"`. +You should have a `main` element with an `id` of `main` -**Історія користувача #4:** У межах `img-div` елементу, мені потрібно бачити `img` елемент з відповідним `id="image"`. +```js +const el = document.getElementById('main') +assert(!!el && el.tagName === 'MAIN') +``` -**Історія користувача #5:** У межах `img-div` елементу, мені потрібно бачити елемент з відповідним `id="img-caption"`, котрий містить текстовий контент, який описує зображення яке показується в `img-div`. +Your `#img-div`, `#image`, `#img-caption`, `#tribute-info`, and `#tribute-link` should all be descendants of `#main` -**Історія користувача #6:** Мені потрібно бачити елемент з відповідним `id="tribute-info"`, котрий містить текстовий контент, який описує пам'ятну сторінку. +```js +const el1 = document.querySelector('#main #img-div') +const el2 = document.querySelector('#main #image') +const el3 = document.querySelector('#main #img-caption') +const el4 = document.querySelector('#main #tribute-info') +const el5 = document.querySelector('#main #tribute-link') +assert(!!el1 & !!el2 && !!el3 && !!el4 && !!el5) +``` -**Історія користувача#7:** Мені потрібно бачити `a` елемент з відповідним `id="tribute-link"`, котрий дає посилання на зовнішній сайт, який містить додаткову інформацію про тему пам'ятної сторінки. ПІДКАЗКА: Ви повинні надати вашому елементу атрибут у формі `target` і налаштувати його до `_blank` для того щоб ваше посилання відкрилося у новій вкладці(т.к. `target="_blank"`). +You should have an element with an `id` of `title` -**Історія користувача #8:**Елемент`img`повинен у відповідь змінити свій розмір, у зв'язку з шириною його початкового елементу, без перевищення його оригінального розміру. +```js +const el = document.getElementById('title') +assert(!!el) +``` -**Історія користувача#9:** Елемент `img` повинен знаходитись у центрі в межах його початкового елементу. +Your `#title` should not be empty -Ви можете створити проєкт за допомогою using this CodePen template й натиснути `Save` для створення власного фрагмента. Або ж ви можете скористатися цим CDN посиланням для проходження тестів у будь-якому комфортному для вас середовищі:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`. +```js +const el = document.getElementById('title') +assert(!!el && el.innerText.length > 0) -Після того як ви завершили, прикріпіть URL до вашому проєкту, над яким ви працюєте, з усіма пройденими тестами. +``` -# --solutions-- +You should have a `figure` or `div` element with an `id` of `img-div` + +```js +const el = document.getElementById('img-div') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGURE')) +``` + +You should have an `img` element with an `id` of `image` + +```js +const el = document.getElementById('image') +assert(!!el && el.tagName === 'IMG') +``` + +Your `#image` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #image') +assert(!!el) +``` + +You should have a `figcaption` or `div` element with an `id` of `img-caption` + +```js +const el = document.getElementById('img-caption') +assert(!!el && (el.tagName === 'DIV' || el.tagName === 'FIGCAPTION')) +``` + +Your `#img-caption` should be a descendant of `#img-div` + +```js +const el = document.querySelector('#img-div #img-caption') +assert(!!el) +``` + +Your `#img-caption` should not be empty + +```js +const el = document.getElementById('img-caption') +assert(!!el && el.innerText.length > 0) +``` + +You should have an element with an `id` of `tribute-info` + +```js +const el = document.getElementById('tribute-info') +assert(!!el) +``` + +Your `#tribute-info` should not be empty + +```js +const el = document.getElementById('tribute-info') +assert(!!el && el.innerText.length > 0) +``` + +You should have an `a` element with an `id` of `tribute-link` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.tagName === 'A') +``` + +Your `#tribute-link` should have an `href` attribute and value + +```js +const el = document.getElementById('tribute-link') +assert(!!el && !!el.href && el.href.length > 0) +``` + +Your `#tribute-link` should have a `target` attribute set to `_blank` + +```js +const el = document.getElementById('tribute-link') +assert(!!el && el.target === '_blank') +``` + +You should use an `#image` selector in your CSS to style the `#image` and pass the next three tests + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image') +assert(!!style) +``` + +Your `#image` should have a `display` of `block` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +assert(style === 'block') +``` + +Your `#image` should have a `max-width` of `100%` + +```js +const style = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +assert(style === '100%') +``` + +Your `#image` should have a `height` of `auto` + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'); +const maxWidthValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('max-width') +const displayValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('display') +const oldDisplayValue = img?.style.getPropertyValue('display'); +const oldDisplayPriority = img?.style.getPropertyPriority('display'); +img?.style.setProperty('display', 'none', 'important'); +const heightValue = new __helpers.CSSHelp(document).getStyle('#image')?.getPropertyValue('height') +img?.style.setProperty('display', oldDisplayValue, oldDisplayPriority); +assert(heightValue === 'auto') +``` + +Your `#image` should be centered within its parent + +```js +// taken from the testable-projects repo +const img = document.getElementById('image'), + imgParent = img?.parentElement, + imgLeft = img?.getBoundingClientRect().left, + imgRight = img?.getBoundingClientRect().right, + parentLeft = imgParent?.getBoundingClientRect().left, + parentRight = imgParent?.getBoundingClientRect().right, + leftMargin = imgLeft - parentLeft, + rightMargin = parentRight - imgRight; +assert(leftMargin - rightMargin < 6 && rightMargin - leftMargin < 6) +``` + +# --seed-- + +## --seed-contents-- ```html -// solution required + +``` + +```css + +``` + +## --solutions-- + +```html + + + + + + + + Tribute Page + + +

Tribute Page

+

The below card was designed as a tribute page for freeCodeCamp.

+
+
+ An image of Togepi +
Togepi, happy as always.
+
+

Togepi

+
+
+

+ Togepi was first discovered in the Johto region, when Ash Ketchum + discovered a mysterious egg. However, when the egg hatched, Togepi saw + Ash's friend Misty first and imprinted on her. Like many other + creatures, this imprinting process created a bond and Togepi views + Misty as his mother. +

+

+ Togepi is a very childlike Pokemon, and is very emotionally + expressive. He demonstrates extreme levels of joy and sadness. +

+
+

Battle Information

+
    +
  • Type: Fairy
  • +
  • Evolutions: Togepi -> Togetic -> Togekiss
  • +
  • Moves: Growl, Pound, Sweet Kiss, Charm
  • +
  • Weaknesses: Poison, Steel
  • +
  • Resistances: Dragon
  • +
+

+ Check out this + Bulbapedia article on Togepi + for more information on this great Pokemon. +

+
+
+ + + +``` + +```css +body { + background-color: #3a3240; + color: white; +} +main { + background-color: #92869c; + font-family: Lobster; + max-width: 500px; + margin: 20px auto; + color: black; + border-radius: 50px; + box-shadow: 10px 10px rgba(0, 0, 0, 0.5); +} +h2 { + text-align: center; + font-size: 20pt; + font-family: Pacifico; +} +body { + text-align: center; + font-size: 12pt; +} +footer { + text-align: center; + font-size: 10pt; +} +.border { + border-color: black; + border-width: 5px; + border-style: solid; +} +#image { + height: auto; + display: block; + margin: auto; + max-width: 100%; + border-radius: 50%; +} +#img-caption { + font-size: 10pt; +} +a:not(#tribute-link) { + color: white; +} +hr { + border-color: black; +} ```