step by step guide css in 44 minuteshipermedios.gilbertoleon.io/css_in_44_minutes.pdf · the...

Post on 16-Jun-2020

18 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Build your own webpagefrom scratch

Build your own webpagefrom scratch

CSS in44 minutes

CSS in44 minutes

Jeremy ThomasWritten by

S T E P B Y S T E P G U I D E

© Copyright 2018 – Jeremy Thomas

Class TrainingPatricia Pinedo - Web Development Program

1Introduction

Thisbookisastepbystepguidethatwillteachyouhowtobuildthiswebpagefromscratch:

It'sthewebpageofafictionaltechrecruitercalledAlexJefferson.AllimagescomefromUnsplash.Asyou

followthisguide,feelfreetochangethestylesandcontentthewayyouwant.

Whoisthisbookfor

Anyonecanreadthisbook!Nopriorwebdevelopmentorprogrammingknowledgeisrequired,sinceIwill

tellyouwhattodo,linebyline.

Whatyouwillbuild

Thiswebpagewillusethefollowingfiles:

1HTML5file

3CSSfiles

4images(provided)

1JavaScriptfile

Itwillalsomakeuseoftwothirdpartyservices:FontAwesomeandGoogleFonts.

Whatyouwilllearn

Throughthisguide,Iwillteachyouhowto:

SetupavalidHTML5document

Writesemanticmarkup

InsertresponsiveRetina-friendlyimages

LearnhowtostructureyourCSScorrectly

Designa100%responsivepage

Understandhowmediaquerieswork

UseCSSFlexboxtolayoutyourcomponents

Styleyourtextwithtypographyproperties

AddvisualfeedbackwithCSSTransitions

BringyourpagetolifewithCSSAnimations

MakeuseofGoogleFonts

IncludeandstyleFontAwesomeicons

Whatyouneedtostart

Youonlyneedtoinstall2programs:

adecenttexteditororIDEwithsyntaxhighlighting.IrecommendSublimeTextbutyoucanuse

Notepad++,Vim,Emacs,IntelliJ,Atom…

amodernwebbrowser.IuseGoogleChromebutyoucanuseFirefox,Safari,Opera,orEdge.

YoualsoneedafewfilesthatIhaveprovided:

1CSSfile: minireset.min.css

7images:

alex.jpg

alex@2x.jpg

alex@3x.jpg

austria.jpg

1x.png

2x.png

3x.png

Havethemavailableandreadytobeused.

2WritingtheHTML5content

Openyourtexteditor,createanewfileandpastethiscodesnippet:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Alex Jefferson – Tech Recruiter</title>

</head>

<body>

<h1>Hello world!</h1>

</body>

</html>

Savethisfileas index.html ,openitinyourbrowser,andyouwillseethefollowingpage:

Makesuretohavethe .html fileextension.Here'showtodoitonWindowsandMacOS.

AvalidandresponsiveHTML5document

ThispageisavalidresponsiveHTML5pagebecauseitsatisfiesthefollowingrequirements.

<!DOCTYPE html>

ThislinetellsthebrowserthatthiswebpageisanHTML5documentandshouldbeinterpretedassuch.

<meta name="viewport" content="width=device-width, initial-scale=1">

Thisistheresponsivemetatag.Ittellsthebrowsertosetthecontentwidthtotheviewportone,ensuring

forthecontenttoadaptautomatically.Italsotellsthebrowsertosetthezoomlevelto1initially,whilestill

allowingtheusertozoomin(especiallyonmobilephones).

Also,eachHTMLtag( <html> , <head> , <body> …)isopenedandclosedintherightorder.Onlythe

<meta> tagsneedtobeself-closing.

AddingtheCSSreset

Beforedesigningyourpage,youwanttostartwithacleancanvas.Sinceeachbrowsercomeswithitsown

defaultstyles,youwanttoremovethemfirst,otherwisethesestyleswillclashwithyours.Thisprocessis

thepurposeofaCSSreset.

Bestpractice

Separatecontentandstyling

YouwanttochooseanHTMLtagforitssemanticmeaning,notitsappearance.

Ifchanginganelement'staginyourHTMLchangesitsappearance,thenyou’reessentiallystylingyour

webpageintheHTML,whichiswhatwewanttoavoid.

MostcurrentCSSresetsareeithercomplicatedoroutdated,soIcreatedasmallonecalledminireset.css.I

useitforallmyprojects,andit'sincludedbydefaultinBulmatoo.

Theonlytworealrequirementsareto:

removethemarginsandpaddingsfromallblockelements

use box-sizing: border-box

Feelfreetoreadthroughthesourcecode.

Alongsideyour index.html file,createa /css folder,andmovethe minireset.min.css fileinit.

Let'slinkourCSSfilefromtheHTMLfile.Justbelowthe <title> ,addthisline:

<title>Alex Jefferson – Tech Recruiter</title>

<link rel="stylesheet" type="text/css" href="css/minireset.min.css">

Thetext "Hello world!" isnowunstyled.

YourownCSS

Inthe /css folder,createanewemptyfilecalled main.css .

YounowhavetoincludethisCSSinyourpage.In index.html ,rightbelowtheminireset,linkyour

main.css file.Younowhave2CSSfiles:

<link rel="stylesheet" type="text/css" href="css/minireset.min.css">

<link rel="stylesheet" type="text/css" href="css/main.css">

ToseeiftheCSSwascorrectlyincluded,addthisto main.css :

html {

background-color: blue;

}

Ifyourscreendoesn'tturnblue,makesureyour index.html fileisalongsideyour /css folder:

TheCSSnowworkssoyoucanremovethebluebackgroundfromtheCSS.BeforewritinganyCSS,you

havetostartwiththemostimportantofawebpage:thecontent.

Writingcontent

Thepurposeofdesignistoenhancethepresentationofthecontentit'sappliedto.Itmightsoundobvious,

butcontentbeingtheprimaryelementofawebsite,itshouldnotbeestablishedasanafterthought.Written

contentmakesupformorethan90%oftheWeb.

Remove "Hello world!" fromyourpage,andputthiscodeinsidethe <body> :

<div class="wallpaper"></div>

<div class="content">

<aside class="side">

<figure class="picture">

<div class="picture-shadow"></div>

<img id="pictureImage" class="picture-image"

src="images/alex.jpg"

srcset="images/alex.jpg 1x,

images/alex@2x.jpg 2x,

images/alex@3x.jpg 3x"

alt="Portrait of Alex Jefferson"

width="320"

height="320">

</figure>

</aside>

<main class="about">

<h1 class="name">

Hi, I'm Alex Jefferson

</h1>

<p class="job">

Tech recruiter

</p>

<hr class="hr">

<div class="description">

<p>

I spend my time traveling the world,

helping startups and tech businesses

hire the best people.

</p>

</div>

<div class="contact">

<a class="button" href="mailto:youremail@example.com">

Get in touch

</a>

</div>

</main>

</div>

Asyoucansee,HTMLisnoisy:thereislotscodefornotmuchcontentonscreen.ButalltheseHTMLtags

arehereforsemanticreasons,andalltheseCSSclassnamesareherefor(future)stylingpurposes.

HTMLstructure

The wallpaper willdisplayatransparentimageinthebackground,coveringthewholepage.

The content isthecontainerforthereadablepartofthewebpage,andwillcoverthewholepageaswell.

Ontheright,the side willdisplaytheportraitimage.

Ontheleft,the about sectionisawrapperforalltext.The button actsasalinkforvisitorstoclick,so

makesuretoreplace youremail@example.com withyourownemailaddress.

ResponsiveandRetina-friendlyimages

Asyoucansee,sincethe alex.jpg imageismissing,thebrowserisshowingthe alt text"Portraitof

AlexJefferson"asafallback.Tofixthis,createan /image folderalongsidethe /css one,andmovethe4

images( alex.jpg , alex@2x.jpg , alex@3x.jpg and alex@4x.jpg )inside:

Wewanttodisplaythisimageatamaximumof 320x320 pixels.Butscreenshavedifferentpixelratios,

especiallymobilephones.Forexample,theSonyXperiaShasapixelratioof 2 ,theAppleiPhoneX 3 ,

andtheSamsungGalaxyS8 4 .

Wecouldshowthe 1280x1280 versiontoeveryoneandresizeitto 320x320 .Butwewouldpenalize

userswhoownadevicewithapixelratioof 1 becausetheywouldendupdownloadinganimage10

timesthesizethattheirdevicecanactuallydisplay.

Thesolutionisto:

showtheuserthehighestqualityimagepossibletheirdevicecansupport

preventthebrowserfromdownloadingtheotherimages

Thisispossiblethankstothe srcset attributewhichtellsthebrowserthelistofimagealternatives

availableforeachpixeldensity,andlethimfigureoutwhichimagetodisplay.

Ifthebrowserdoesn'tsupport srcset ,itwilluse src asafallback.

Thisisallthecontentthatyouneedfornow:

aportraitimage

aname

ajobtitle

adescription

acontactbutton

Thiscontentwillbeextendedfurthermorelater.It'stimetoaddyourfirstlinesofCSS.

3SettingupaCSSbase

Beforestylingindividualelements,youneedtosetaglobalbasestyleforyourwebpage.

Thehtmlstyles

Thegeneralstylingofawebpageisdonethroughstylesappliedtothe html elementbecausemostof

themarecascadedthroughalltheotherchildelements.

Inyourempty main.css file,addthiscode:

/* 1. Base */

html {

background-color: #5f45bb;

background-image: linear-gradient(to bottom right, #180cac, #d054e4);

color: #fff;

font-family: "Quicksand", sans-serif;

font-size: 16px;

-moz-osx-font-smoothing: grayscale;

-webkit-font-smoothing: antialiased;

line-height: 1.5;

min-height: 100vh;

min-width: 300px;

overflow-x: hidden;

text-shadow: 0 3px 5px rgba(0, 0, 0, 0.1);

}

Thisrule-setisbasicbutdoesthejob:

the background and color declarationssettheoveralltone

the font and text-shadow setthebasetypography

the line-height andbrowser-specific font-smoothing declarationsmakethepagemorereadable

thedimensionsandoverflowvaluesensurethatthepagefillsupthewholeviewport

Bestpractice

OrderyourCSSrulesalphabetically

WheneditingaCSSfile,findingthedeclarationtochangecanbetimeconsuming.

Toreducethecognitiveloadwhenbothreadingandwritingrules,writethemalphabetically.

It'stheonlysortingrulethatisfuture-proofbecauseit'sopinionless.

Whenyouwillhavemorethan10CSSdeclarationsinarule,youwillbegladtoknowwheretofindwhatyou

werelookingforinasplitsecond!

The background-color usuallyactsasafallbackifthe background-image doesn'tload,butsincewe're

usinga linear-gradient() itwillalmostalwaysappear.Thisgradientappearsontopofthesingle-

coloredbackground,hencewhyweonlyseethegradient.

Thefont-familypropertytakesalistofpossiblefamilies.IftheQuicksandfontisnotavailable,thebrowser

willusethefallbackfontprovided: sans-serif .ThisusuallymeansArialorHelveticaonWindows

machines,SanFranciscoonMacOS,andUbuntuonLinuxmachines.Sinceyourvisitorswillprobablynot

havethatfont,wewillincludeitusingGoogleFonts.

The line-height hasaunitlessvalueof 1.5 .Itmeanseachlineoftextwillbe1.5timestheelement's

currentfontsize.Formostofthepage,andcombinedwiththe font-size: 16px declaration,thiswill

makeeachlineoftext 24px high.

Ialwayshavea min-width: 300px thatpreventsthepagefrombeingtoonarrowtobereadable.

The min-height: 100vh ensuresthepagetobeatleastastallas100%oftheviewportheight( vh ).

The overflow-x: hidden declarationpreventsthepagefromscrollinghorizontallywhilepreservingthe

usualverticalscroll.

AddingtheGooglefonts

In index.html ,beforeincluding minireset.min.css ,addthisCSSfromGoogleFonts.Younowhave3

CSSfiles:

<link href="https://fonts.googleapis.com/css?family=Montserrat|Quicksand" rel="stylesheet">

<link rel="stylesheet" type="text/css" href="css/minireset.min.css">

<link rel="stylesheet" type="text/css" href="css/main.css">

Thisaddstwofontstoyourpage:QuicksandandMontserrat,bothinregularfontweightonly(valueof

400 ).Reloadthepagetoseethefontsinaction:

Stylinglinks

Linksarebydefaultblueandunderlined.AddthisinyourCSS:

a {

color: currentColor;

cursor: pointer;

text-decoration: none;

}

Using currentColor ispreferedbecauseitwillpickupthecolorsetby html before: color: #fff .

Updatingthecolorofbothonlyrequiresasinglelinechange.

Sometimes,thehandcursordoesn'tshowupwhenhoveringalink.That'swhyIalwaysadd cursor:

pointer toforcethehandtoshowup.

"Getintouch"isnowwhiteaswell:

4Definingthelayout

Thewallpaper

Attheendof main.css addthissnippet:

/* 2. Shared */

.wallpaper {

display: block;

height: 100%;

left: 0;

top: 0;

width: 100%;

}

Thisisthe 2. Shared sectionoftheCSS.Here,differentselectorswillsharethesamesetofrules.Wewill

extendthissectionasweneedalongtheway.

Fornow,thisruleensuresthatthewallpapercoversthewholepage.

Wenowenterthe 3. Specific sectionwherewewillstyleeachelementindividually.Addthe

austria.jpg filetothe /images folder:

Thenaddthissnippetattheendof main.css :

/* 3. Specific */

.wallpaper {

background-image: url("../images/austria.jpg");

background-position: center;

background-size: cover;

opacity: 0.2;

position: fixed;

}

Thisimageisnotdisplayedwithan <img> tagbecauseitspurposeisdecorativeandbelongsintheCSS.

Thankstothefixedpositioning,thewallpaperwillnotscrollwiththepage.

Bestpractice

Avoidtheshorthandnotation

We'reusingeach background-* propertyinsteadoftheshorthand background one.

Ifyouuse background: red ,youareessentiallysetting background-color: red andresetingallother

propertiestotheir initial value.

Itbecomesaproblemwhenyouactuallyoverrideadeclarationyouhadpreviouslywritten,andyouwonder

whyyourCSSlinedoesn'twork!

If background-color hadbeensetearlier,itwouldhavebeenundonehere.

Theonlyusefulshorthandpropertiesare margin , padding and border .

Mainlayout

The content elementisparenttoboth:

side withtheportraitimage

about withthetextcontent

We'regonnauseCSSFlexboxtosetthegloballayoutofthepage.

.content {

display: flex;

position: relative;

min-height: 100vh;

}

.side {

max-height: 20rem;

max-width: 20rem;

}

.about {

max-width: 26rem;

}

WeenableFlexboxonthe .content bysimplyusing display: flex .Thismakesboth .side and

.about Flexboxitems.

The position: relative allows .content toappearabove .wallpaper ,andthe min-height is

heretomakesure .content coversthewholepage.

Theuseof max-width isverypractical:itjustmeansthatatanypointwedon'twantanelementtoby

widerthanacertainvalue.Forreadabilityreasonswewantthe .about sectiontonevergobeyond

26rem inwidth(whichis 26 x 16px = 676px ).Sinceit'sablockelement,itwillusethewholewidth

availableuptoacertainpoint.Dependingonthelengthofyourwrittencontent,youcanplaywiththevalue

here.

Bestpractice

Avoidz-indexwhenpossible

Allpositionedelements( absolute , fixed ,or relative )canhavea z-index valuetostackthem

relativelytoeachother.

ButelementsarealreadystackedbasedontheirlocationwithintheHTMLcode.

Because .wallpaper and .content aresiblings,thesecondone .content willappearabove(onlyifit's

positionedtoo).

Andchildelementswillappearabovetheirparent.

It'sbettertoplacethemasyouwantinyourHTML,otherwiseyou'llhavetokeeptrackofall z-index values

throughoutyourCSS.

Makingthelayoutresponsive

Wewantourlayouttoberesponsive,meaningthatitwillbedifferentonsmallerviewports(below 800px )

thanonwiderones( 800px andabove):

onmobile,we'rehavingacenteredverticallayout

ondesktop,we'rehavingacenteredhorizontallayout

We'regonnawriteamediaquery:anyCSSwritteninsidethatblockwillonlybeactiveifalltheitemsinthe

mediaquerylist( screen and (max-width: 799px) )aretrue.Inthiscase,wearetargettingmobile

deviceswhohaveaviewportnarrowerorequalto 799px .

Luckily,evenonyourdesktopyoucansimplyresizeyourbrowsertoseeitinaction.

/* 4. Responsiveness */

@media screen and (max-width: 799px) {

.content {

flex-direction: column;

justify-content: center;

align-items: center;

padding: 5rem 3rem;

}

.side {

margin-bottom: 3rem;

width: 100%;

}

}

Resizeyourbrowsertoseeitinaction.

We'reusingthefollowingFlexboxproperties:

flex-direction: column makesthelayoutvertical

justify-content: center makesthecontentcenteredonthemainaxis(vertical)

align-items: center makesthecontentcenteredonthecrossaxis(horizontal)

The padding preventsthecontentfromtouchingtheviewportedges,givingitsomespacetobreath.

The .side (whichcomesfirst)hasa margin-bottom toseparateitfromthe .content (whichcomes

second).

Desktopview

Ondesktop,wewantthelayouttobehorizontalinstead:

@media screen and (min-width: 800px) {

.content {

align-items: center;

justify-content: space-around;

justify-content: space-evenly;

padding: 4rem;

}

.side {

flex-grow: 0;

flex-shrink: 0;

height: 20rem;

margin-left: 4rem;

order: 2;

width: 20rem;

}

.about {

flex-grow: 1;

flex-shrink: 1;

}

}

The .content usesthedefaultvalueof flex-direction whichis row ,meaningtheitems( .side

and .about )arespreadouthorizontally. justify-content appearstwicebecausethe space-evenly

valueisnotavailableinallbrowsers,soweuse space-around asareasonablefallback.

The .side element(whichcontainstheimage),hasfixeddimensionsofa 20rem by 20rem square.If

there'smorehorizontalspaceavailable,wedon'twantittogrow,hencethe flex-grow: 0 .Ontheother

hand,wealsodon'twantittoshrinkatall,otherwise,theimagewouldbesquased.That'swhy flex-

shrink: 0 isusedheretoo.Webasicallywantthe .side tobe 20rem by 20rem atalltimes.Wealso

wantittoappearafterthetextcontent,whichiswhyweuse order: 2 .

Forthe .about ,wedowantittousetheremainingspaceavailable,inbothdirections,whichiswhy

flex-grow and flex-shrink havebothavalueof 1 .

Bestpractice

Inmediaqueries,don’tundo,justdo

Withmobile-firstapproaches,it'seasytomakealayoutworkwellonnarrowscreens,andthen"undo"mostof

itondesktop.Butthat'strickybecauseyouhavetokeeptrackofwhathasbeendoneoutsideofmediaqueries,

andresetthosevaluesinsidethedesktopmediaquery.YoualsoendupwritingalotofCSSjusttoreset

values,andyoucanendupleavingCSSlike margin-bottom: 0 youarenotsurewhat.

The margin-bottom setforthe .side elementshouldonlyappearonmobile.

Insteadofapplyingamarginbydefaultonallscreens,andremovingitondesktop,weonlyapplyitonmobile.

5Stylingallelements

Thepicture

Theshadowisseparatedfromtheimagebecausewearegoingtoanimatethemseparatelylateron.

Inthe 2. Shared sectionoftheCSS,updatethelistofselectorsandaddboth .picture-shadow and

.picture-image :

.wallpaper,

.picture-shadow,

.picture-image {

display: block;

height: 100%;

left: 0;

top: 0;

width: 100%;

}

Attheendofthe 3. Specific sectionoftheCSS,addthefollowingstyles:

.picture {

padding-top: 100%;

position: relative;

width: 100%;

}

.picture-shadow {

border-radius: 290486px;

background-image: radial-gradient(#000 0%, rgba(0, 0, 0, 0) 70%);

position: absolute;

top: 10%;

}

.picture-image {

border-radius: 290486px;

position: absolute;

}

The padding-top: 100% isatechniquethatmakesthe .picture ashighasitiswidemakingitsquare

atalltimes.Italsohasa position: relative sothatitactsasareferencepointforitstwoabsolutely

positionedchildren.

Theshadowusesasemi-transparent radial-gradient() .It'sslightlyoffsettowardsthebottomwith

top: 10% .

The border-radius issettotheveryhighvalueof 290486px toensuretheelementstoberounded.You

canuseanyextremelyhighvalue.Ipersonalyuse 290486px asatrademarkbecauseit'smydateofbirth.

It'squiteinterestingtoseeitshowupinotherpeople'scode!

Thename

Thenameisthemostimportantinformationofthepage.That'swhyitusesthe <h1> HTMLtag,whichhas

thestrongestsemanticvalue.Toreflectthisprominencevisuallyaswell,wearegonnamakeitbigger:

.name {

font-size: 2.25rem;

line-height: 1.125;

margin-bottom: 0.5rem;

}

Thefontsizeusesthe rem unit:it'stherootvalue,equaltothefontsizesetonthe html element,which

wepreviouslysetto 16px .So 2.25rem isessentially 36px .Using rem isusefulbecauseitreferences

acommonvalue,andwecanupdatethe html valuetosetallinstancesof rem values.

The line-height issetto 1.125 It'shardtoseeitspurposeifthetextistooshort(resizeyourbrowser

toreachtwolines),butkeepingthepagevalueof 1.5 makesthetwolinestoospacedout.

Bestpractice

Setline-heightfirst,margin/paddingsecond

Somedevelopersusetheline-heightasawaytogivespacetoanelement.Butasitsnamesuggests,it's

meanttodefinetheheightofasingleline,notthespacebetweeneachline.

Theline-heightvalueshouldbesetforreadabilitypurposesonly.

Ifyouneedtogivemorebreathingspacetoanelement,justuseabitofmargin(orsometimespadding),which

iswhatwe'redoingherewith margin-bottom .

Jobtitle

Wewantthejobtitletostandoutabit.That'swhywearegoingtouseoursecondaryfont:Montserrat.

Thisfontworkswellwhenthelettersareuppercaseandslightlyspacedout.

Inthe 2. Shared section,addthissnippet:

.job,

.button {

font-family: "Montserrat", "Quicksand", sans-serif;

letter-spacing: 0.3em;

text-transform: uppercase;

}

Thisstyleisgoingtobeusedforourbuttonaswell,solet'saddbothselectorsrightnow.

Inthe 3. Specific section,addthefollowing:

.job {

color: #ffe479;

font-size: 0.75rem;

}

Theuppercasestylemakesthetextquite"inyourface",sowe'rereducingthefontsizeabit,andalso

applyingashadeofyellow.

Thehrline

Thehorizontalrule( hr )definesasemanticbreakbetweenblocksoftext.Whilekeepingthissemantic

valueintact,wewanttomakethislinemoresubtle:

.hr {

background-color: #ff470f;

border: none;

content: "";

height: 1px;

margin-bottom: 1.5rem;

margin-top: 1.5rem;

transform-origin: center left;

width: 4rem;

}

Formorecontrol,we'reremovingthe border andusingthe background-color withaheightof 1px to

defineathinshortline.

The transform-origin willbeusedwhenweanimatethewidthlateron.

Description

Thedescriptiononlyneedstobeslightlymoreprominent.Let'sincreasethefontsize:

.description {

font-size: 1.5rem;

}

Contactbutton

.contact {

display: inline-block;

margin-top: 1.5rem;

vertical-align: top;

}

Byusing display: inline-block wecombinetwobehaviors:

inline makessurethewidthisequaltoitscontent(thebutton)

block makessuresurroundingelementswillappearaboveandbelow

italsoallowsustouse margin-top

And vertical-align: top ensurestheelementtoonlyusetheverticalspacerequired,andkeepsthe

spacingtight.

WefirstneedtoaddsomeCSSinthe 2. Shared section:

.button,

.social a {

transform-origin: center;

transition-duration: 100ms;

}

We'resettingsometransformationandtransitionvaluessharedbetweenthebuttonandthesociallinks

(whicharecominglater).

The transition-duration issharedsoweonlyneedtoreplacethevalueinasinglelocationifneeded.

Wecannowfocusonthe 3. Specific sectionforthebuttonitself,whichisthemostelaborateelement

wehave:

.button {

background-color: #fff;

border-radius: 290486px;

box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.2);

color: #9013fe;

display: inline-block;

font-size: 0.875rem;

line-height: 1;

padding: 1.25em 2em;

text-shadow: none;

transition-property: box-shadow, transform;

user-select: none;

vertical-align: top;

white-space: nowrap;

will-change: box-shadow, transform;

}

Thebuttonusesthesame inline-block techniqueasitsparent.

Theheightofthebuttonisproportionaltothefontsize,andequalto 3.5 timesthefontsizevalue:

theunitless line-height isequalto 1 or 0.875rem

theverticalpaddings(topandbottom)aresetto 1.25em each,or 1.25 timesthefontsize

The em unitisequaltothecurrentfontsize.Inthiscase,it'ssimilartotheunitlesslineheightvalue.

Ifyouplayaroundwiththe font-size value,bysetting 2rem forexample,you'llnoticethatthebutton

willresizeproportionally.Thisisveryusefulbecauseweonlyneedtoupdateasinglevalueto

increase/decreasethesizeofthebutton,whilemaintainingaperfectratio.

Wealsoapplysomeotherstyles:

becauseofthecoloredbackgroundandthedarkertextcolor,weremovethetext-shadow

weuse user-select: none sothetextcontentcan'tbeselected,whichcanhappenwhenclicking

repeatedlyonthebutton

tomakesurethetextneverisdisplayedontwolines,weuse white-space: nowrap

The transition-property and will-change valuesareforthebuttonstates.

Buttonstates

Thebuttonisthemaininteractionelementofthepage.Visitorscanhoverthebuttonandclickonit.

.button:hover {

box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.2);

transform: scale(1.02) translateY(-4px);

}

Theboxshadowistransparentsoitcanworkonanybackgroundcolor.Forthetransformation,weincrease

thebutton'ssizeby2%with scale(1.02) andmoveitupwardsbyafewpixelswith

translateY(-4px) .

Whenclickingthebutton,wewanttomakeitlookasifitwaspresseddownwards.

.button:active {

box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.3);

transform: scale(0.98) translateY(-2px);

}

We'rejustplayingwiththesamepropertiesbutwithdifferentvalues.Theshadowisstrongerandsmaller

becausethebuttonappearsclosertothe"ground".

Playwiththe transition-duration valuesetinthe 2. Shared sectiontoseeitslowerorfaster.

6ImportingFontAwesomeicons

FontAwesomeisaniconlibrarythatallowsyoutoeasilyincludeiconsinyourwebpage.Whatitprovidesis

essentiallyaniconfontwhichsimplyisatextfontwhereallthecharactershavebeenreplacedwithicons.

Soinsteadoftypingshapesoflettersyou'reessentiallytypingshapesoficons.Thisworksbecauseletters

arevectorshapesthemselves.Wejusthappentobeabletoreadthem!

WeareincludingthewholeFontAwesomelibrarydirectlyfromtheCDN.Thebenefitisthatalliconsare

available.Thedisadvantageisthatthefilesloadedaremuchbiggerinsize.Youcanuseaniconfontgenerator

likeIcoMoonorFontellotoonlyincludetheiconsyouactuallyneed.Thiswillreducethesizeofthefontfiles.

OneotheroptionistouseSVGimagesdirectly,butthat'strickier!

ImportingtheFontAwesomelibrary

Justbeforetheclosing </head> tagin index.html ,includethefollowingscript:

<script defer src="https://use.fontawesome.com/releases/v5.0.0/js/all.js"></script>

Rightafterthe <div class="contact"> ,addthesesocialicons:

<ul class="social">

<li>

<a>

<i class="fab fa-twitter"></i>

</a>

</li>

<li>

<a>

<i class="fab fa-github"></i>

</a>

</li>

<li>

<a>

<i class="fab fa-linkedin"></i>

</a>

</li>

</ul>

Iftheiconsdon'tshowup,makesureyouareconnectedtotheinternetandthatyouhaveJavaScriptenabled.

Stylingtheicons

Ifyoureloadthepagerepeatedly,youmightnoticethatthelayout"jumps"forasplitsecond.That'sbecause

atfirst,theiconsarenotloaded,andthepageonlydisplaysthetextandtheimages.Then,whentheicons

finallyload,thepopup,andcausethepagetoberedrawn,hencethejump.

Toavoidthisjump,we'regonnasetasquareareaof 2rem by 2rem foreach <li> listitem:

.social {

display: flex;

margin-top: 1.5rem;

}

.social li {

height: 2rem;

margin-right: 0.5rem;

text-align: center;

width: 2rem;

}

The <ul> listactsasaFlexboxcontainerforeachsquarelistitem.Wecannowstyletheinnerlinks:

.social a {

align-items: center;

display: flex;

font-size: 1.5rem;

height: 2rem;

justify-content: center;

opacity: 0.5;

transition-property: opacity, transform;

width: 2rem;

will-change: opacity, transform;

}

Eachlinkitemisasquareaswell,inwhichtheFontAwesomeiconisbothverticallyandhorizontally

centered.

Becausetheiconsaretext,wecanusethe font-size propertytoincreasetheicon'ssize.Andsince

we'vesetall <a> tagstousethe currentColor ,itpicksupthewhitecolorsetforthepage.

We'realsosettingtheopacitytohalftransparent,whichisconvenientbecauseit'svalidforanycolorwe

woulduse.

Asforthebutton,we'regonnaaddsomehoverandactivestyles:

.social a:hover {

opacity: 1;

transform: scale(1.25);

}

.social a:active {

opacity: 1;

transform: scale(1.1);

}

7CreatingCSSAnimations

AnimatinginCSSisbasicallychangingasetofvaluesovertime.Forexample,fadinginanelementisdone

bysettingthe opacity tozero 0 ,andgraduallyincrementingit( 0.1 , 0.2 , 0.3 …)untilyoufinally

reachthevalueof 1 .

Itwouldtakeawhiletofigurealltheintermediatevalues.LuckilyinCSS,youonlyneedtoset2values:

thestartvalues,withthekeyword from

theendvalues,withthekeyword to

Everythinginbetweenwillbedeterminedby:

the animation-duration :howlongittakestogofromthestarttotheend

the animation-timing-function :howthevaluesinbetweenarecalculated(basedonacurve)

CSSAnimationsaretriggeredwhenthepageloads,orwhenaclassnamechanges.

AddinganewCSSfile

WritingCSSAnimationstakesquitealotofspace,solet'screateanewfileinthe /css folder,andcallit

animations.css .

AddittothelistofCSSincluded.Youshouldnowhave4stylesheets:

<link href="https://fonts.googleapis.com/css?family=Montserrat|Quicksand" rel="stylesheet">

<link rel="stylesheet" type="text/css" href="css/minireset.min.css">

<link rel="stylesheet" type="text/css" href="css/main.css">

<link rel="stylesheet" type="text/css" href="css/animations.css">

Keyframes

A @keyframes statementcontainsalistofkeyframes,whicharealltheintermediatestepsofananimation.

We'regonnausethesimpleversionwhereweonlyneedtosettwokeyframes:

from isthekeyframeatthestartoftheanimation

to isthekeyframeattheendoftheanimation

Youcanhavemorethan2keyframes,ifyouusepercentagesinstead.

Here'sthefirstkeyframewe'regonnause.Additto animations.css :

@keyframes bounceIn {

from {

opacity: 0;

transform: scale(0.5);

}

to {

opacity: 1;

transform: scale(1);

}

}

This bounceIn animationcompletestwochangessimultaneously:

fadingin,fromcompletelytransparenttocompletelyopaque

scalingup,fromhalfthesizetotheoriginalsize

We'regonnawrite7keyframestatementsintotal:

zoomOut forthewallpaper

picImage forthepictureimage

picShadow forthepictureshadow

slideDown forthename

slideUp forallothertextelements

fillUp forthehrline

bounceIn forthecontactbutton

Shareddeclarations

LikewithourmainCSS,we'regonnashareafewdeclarationsbetweenmultipleselectors.

.wallpaper,

.picture-shadow,

.picture-image,

.name,

.job,

.hr,

.description,

.contact,

.social li {

animation-duration: 1s;

animation-timing-function: cubic-bezier(0, 0.5, 0, 1);

animation-fill-mode: both;

}

Thedurationissettoonesecond( 1s ).

The animation-fill-mode setto both tellsthebrowsertousethe from valuesbeforetheanimation,

andtokeepthe to valuesaftertheanimationhasended.Otherwise,theelementwouldreverttotheir

non-animatedstyles.

Tomaketheanimationmoreinterestingandsnappier,we'reusingacustomcubicbeziercurve.Seeitin

action!

Animatingthecontactbutton

Forananimationtobetriggeredautomatically,youonlyrequirethedurationandthename.Let'saddthe

name:

.contact {

animation-name: bounceIn;

}

ClicktoseetheButtonBounceininaction

Otherkeyframes

Herearetheother6keyframestatementswe'regonnaneed:

@keyframes fillUp {

from {

transform: scaleX(0);

}

to {

transform: scaleX(1);

}

}

@keyframes picImage {

from {

opacity: 0;

transform: scale(1.2) translateY(-1rem);

}

to {

opacity: 1;

transform: scale(1) translateY(0);

}

}

@keyframes picShadow {

from {

opacity: 0;

transform: scale(1.2) translateY(4rem);

}

to {

opacity: 1;

transform: scale(1.1) translateY(0);

}

}

@keyframes slideDown {

from {

opacity: 0;

transform: translateY(-1rem);

}

to {

opacity: 1;

transform: translateY(0);

}

}

@keyframes slideUp {

from {

opacity: 0;

transform: translateY(1rem);

}

to {

opacity: 1;

transform: translateY(0);

}

}

@keyframes zoomOut {

from {

opacity: 0;

transform: scale(1.05);

}

to {

opacity: 0.2;

transform: scale(1);

}

}

Otheranimations

Boththepicture'sshadowanimageneedaslightlyfasteranimation,andadifferentanimationcurve:

.picture-shadow,

.picture-image {

animation-duration: 750ms;

animation-timing-function: cubic-bezier(0, 0.5, 0.25, 1.25);

}

Wecannowtriggerallanimationsbyusing animation-name forallofthem,whilemakingsomeother

adjustmentstoo:

.wallpaper {

animation-name: zoomOut;

animation-timing-function: ease-out;

}

.picture-shadow {

animation-name: picShadow;

}

.picture-image {

animation-name: picImage;

}

.name {

animation-name: slideDown;

}

.job {

animation-name: slideUp;

}

.hr {

animation-name: fillUp;

}

.description {

animation-name: slideUp;

}

.social li {

animation-duration: 500ms;

animation-name: slideUp;

animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1.5);

}

The .wallpaper doesn'tuseacubicbeziercurve,butratherthe ease-out keyword.

Thesocialitemshaveanevenfasteranimation(500milliseconds,orhalfasecond)anddifferentcurvetoo.

Reloadyourpageandseeallanimationstriggeredatonce!

ClicktoseetheSimultaneousAnimationsinaction

Delayingeachanimation

Becauseallanimationsarehappeningsimultaneously,it'sdifficulttoseetheeffectofeachofthem.What

wesimplyneedtodo,istotriggertheminsequence.

Byusingatriggerdelay,wecanachievealot!

.name {

animation-delay: 100ms;

}

.job {

animation-delay: 200ms;

}

.hr {

animation-delay: 300ms;

}

.description {

animation-delay: 400ms;

}

.picture-image {

animation-delay: 500ms;

}

.picture-shadow {

animation-delay: 500ms;

}

.contact {

animation-delay: 600ms;

}

Forthesocialicons,wewanttodelaythemindividually.Wecanusethe :nth-child pseudoselectorto

selectthem:

.social li:nth-child(1) {

animation-delay: 800ms;

}

.social li:nth-child(2) {

animation-delay: 900ms;

}

.social li:nth-child(3) {

animation-delay: 1s;

}

.social li:nth-child(4) {

animation-delay: 1.1s;

}

.social li:nth-child(5) {

animation-delay: 1.2s;

}

Ifyouhavemorethan5icons,justincrementby 0.1s eachtime.

Reloadyourpageandseeyourwholepageanimated!

ClicktoseetheSequencedAnimationsinaction

8TriggeringanimationswithJavaScript

Sinceyou'vebeendevelopinglocally,bothimages( alex.jpg and austria.jpg )loadinstantly.Butona

productionserver,theseimageswilltakeafewsecondstoload.Sincetheanimationstartsinstantly,and

onlytakes1secondtocomplete,itwillhaveendedbeforetheimagehasloaded.

Toseeitinactiononyourlocalmachine,simulateaslowconnectionusingtheGoogleChromeDevTools:

openthe "Developer Tools" (with Ctrl+Shift+I or Cmd+Opt+I onMac)

gotothe "Network" tab

enablethe "Disable cache" checkbox

inthe "Online" dropdownchoose "Slow 3G"

Reloadyourpageandseehowtheimagestakeawhiletoload.

AddingaJavaScriptfile

Createanewfoldercalled /js ,andinsidecreateafilecalled main.js .

In main.js ,typethefollowing:

alert('Hello JS!');

Inthe <head> ofyourHTML,beforetheFontAwesomescript,includeyourownscript.Younowhave2

scripts:

<script defer type="text/javascript" src="js/main.js"></script>

<script defer src="https://use.fontawesome.com/releases/v5.0.0/js/all.js"></script>

Reloadyourpage.Youshouldseeanalertboxappear!

Youcannowremovethe alert() function.

EditingtheHTML

WeneedtoprepareourHTMLtointeractwithourJS,byusing:

idattributes,toselectelementswithinourJScode

dataattributes,topassdatafromtheHTMLtotheJS

Locatethe wallpaper elementandaddthe id and data-image attributes:

<div id="wallpaper" class="wallpaper" data-image="images/austria.jpg"></div>

Addan id tothe picture element:

<figure id="picture" class="picture">

Addanother id tothe picture-image element:

<img id="pictureImage"

class="picture-image"

src="images/alex.jpg"

srcset="images/alex.jpg 1x,

images/alex@2x.jpg 2x,

images/alex@3x.jpg 3x"

alt="Portrait of Alex Jefferson"

width="320"

height="320">

AppendingaCSSclassonload

We'regonnacreateaJSfunctionthatwill:

getanHTMLelement

gettheimagesourceattachedtothatelement

createanewimagefromthatsource

loadthatimage

whentheimageisloaded,addanewCSSclasstotheelement

function loadImage(id, targetId) {

var el = document.getElementById(id);

var targetEl = targetId ? document.getElementById(targetId) : el;

var imageToLoad;

if (el.dataset.image) {

imageToLoad = el.dataset.image;

} else if (typeof el.currentSrc === 'undefined') {

imageToLoad = el.src;

} else {

imageToLoad = el.currentSrc;

}

if (imageToLoad) {

var img = new Image();

img.src = imageToLoad;

img.onload = function() {

targetEl.classList.add('is-loaded');

};

}

}

Let'sgothroughthisfunctionstepbystep.First,wedefineafunctionthatcantaketwoparameterscalled

id and targetId :

function loadImage(id, targetId) {}

WethenfetchtheHTMLelementbyusingthevalueof id :

var el = document.getElementById(id);

Wesimilarlyfetchatargetelementtoaddaclassto,butonlyifa targetId isprovided.Otherwise,we

reverttotheelementabove:

var targetEl = targetId ? document.getElementById(targetId) : el;

Weinstantiatethe imageToLoad variable:

var imageToLoad;

Thereare3(mutuallyexclusive)casestosetthevalueof imageToLoad :

if data-image isprovided,weusethatvalue

ifthebrowserdoesn'tsupport srcset and currentSrc ,weusethe src valueofthe <img>

otherwisewecansimplyuse currentSrc

if (el.dataset.image) {

imageToLoad = el.dataset.image;

} else if (typeof el.currentSrc === 'undefined') {

imageToLoad = el.src;

} else {

imageToLoad = el.currentSrc;

}

Wecheckif imageToLoad holdsavalue:

if (imageToLoad)

Wethencreateanewimagefromwhichthe src isthevalueofthe imageToLoad :

var img = new Image();

img.src = imageToLoad;

Finally,whentheimageiscompletelyloadedbythebrowser,weaddtheCSSclass is-loaded tothe

targetelement:

img.onload = function() {

targetEl.classList.add('is-loaded');

};

Wenowneedtoaddthose is-loaded styles.

Settingtheloadedstyles

Theanimationsforthe wallpaper andthe picture-* elementsarestilltriggeredautomatically,solet's

removethemfirst.

.wallpaper {

animation-name: zoomOut;

animation-timing-function: ease-out;

}

.picture-shadow {

animation-name: picShadow;

}

.picture-image {

animation-name: picImage;

}

Andreplacethemwiththefollowing:

.wallpaper {

animation-timing-function: ease-out;

}

.wallpaper.is-loaded {

animation-delay: 1s;

animation-name: zoomOut;

}

.picture.is-loaded .picture-shadow {

animation-name: picShadow;

}

.picture.is-loaded .picture-image {

animation-name: picImage;

}

Wealsoneedtosettheinitialstateofthoseelements,byhidingthematthestart.Addthefollowing:

.wallpaper,

.picture-shadow,

.picture-image {

opacity: 0;

}

Ifyounowreloadthepage,thewallpaperandpicturearehidden:

theopacityissettozero 0

theanimationthatfadestheminisnottriggered

Let'snowtriggertheanimationswithJS.

Usingthefunction

WehavesetuptheCSStotriggertheanimationwhenthe is-loaded .Andwehavedefineda

loadImage() function,butwehaven'tcalledityet.Let'stryitout!

Attheendof main.js ,callthefunctiontwice:

document.addEventListener('DOMContentLoaded', function() {

loadImage('wallpaper');

loadImage('pictureImage', 'picture');

});

We'rewaitingforthewholedocumenttobeloadedbeforecallingthe loadImage() twice,withdifferent

parameters.

Yourpageshouldnowworkperfecly!Trytosetthenetworkconnectionto "Slow 3G" again,andnotice

howtheanimationswaitfortheimagestoloadbeforebeingtriggered.

Edgecase:noscript

Ifforsomereasonthevisitordoesn'thaveJSenabled,youstillwanttoshowthemtheimages.The

experiencewillnotbeasgreat,butit'sbetterthanshowingnoimagesatall.

InyourHTML,justbeforethe </body> closingtag,addthis <noscript> tag:

<noscript>

<style type="text/css">

.wallpaper {

animation-name: zoomOut;

}

.picture {

animation-name: dropIn;

}

</style>

</noscript>

IfJSisdisabled,wesimplytriggertheanimations.Younowhavethebestofbothworlds:

ifJSisenabled,thebrowserwaitsfortheimagestobeloadedbeforetriggertheanimations

ifJSisdisabled,thebrowserstillshowstheimagesbytriggeringtheanimations

9Nextsteps

ExploreHTMLandCSS

Whilewe'vecovered90%ofwhatyouwillneedtobuildwebpageswithHTMLandCSS,thereareother

tagsandfeaturesavailable.YoucanfindthemontheMozillaDeveloperNetwork.Ifyouwantasimpler

version,trythefreeresourcesI'vebuilt:HTMLReferenceandCSSReference.

LearnSass

SassisaCSSpreprocessorthatallowsyoutowriteCSSmoreeasily.Itcomeswithlotsoffeatures,but

mostnotablyvariables(forsettingvalueslikecolors,sizes,durations…),mixins(likeJSfunctionsbutforyour

CSS)orextends(sharedeclarationsbyextendinganotherselector).YoucanreadmyfreeMarkSheet

chapteronSassasastart.

LearnJavaScript

Whilewe'vecoveredabitofJS,thereisalotmoretolearn.Therearetonsoffreeresourcesonline,like

EloquentJavaScript,JavaScriptGardenorCodecademy.

Formorecomplexinterfaces,youcanuseaJSframeworklikeReact,AngularJS,Ember.jsorVue.js.

Learnbackenddevelopment

We'veonlycoveredclient-sidedevelopment(or"frontend").Butformorecomplexwebsites,youwillneed

tolearnserver-sidedevelopment(or"backend").Thisrequireslearningaprogramminglanguage(like

JavaScript,Python,Ruby,PHP…).Again,Codecademyisagreatfreeresource.

TryoutBulma

Basedontheknowledgegatheredthrough10yearsofexperience,I'vecreatedanopensourceCSS

frameworkcalledBulma.

YoucanuseitdirectlytobuildinterfacessimplybyusingtheCSSclassesprovided.It'smodular,soyoucan

includeonlywhatyouneed.ButsinceyouprobablywanttowriteyourownCSSafterhavingreadthisbook,

it'salsoagoodstartingpointforanytypeofwork.Ialwaysuseitinmypersonalandprofessionalprojectsin

someway.

It'salsoagoodresourceforlearning.Bygoingthroughthesourcecode,youmightendupimplementing

newfeatures,writingextensions,orsimplyfixingbugs!It'sacodebaselotsofdevelopershavetaken

inspirationfrom.

Thankyouforreading!

top related