On Github gdiboulder / gdi-boulder-css3-properties
Network: galvanize guest
Password: login with your email or facebook account.
If you have not already downloaded the files for this workshop - please download them at gdiboulder.com/css-properties
Slides are available at materials.gdiboulder.com. Click on "CSS Properties & Selectors".
Digital copy of the Selectors Cheat Sheet.
The CSS rule:
selector { property: value; property: value; }
Different properties & values:
body { color: yellow; background-color: black; } p { width: 70%; padding: 10px; margin: auto; } h1 { font-size: 12px; border-bottom: 1px solid #ccc; }
HTML:
CSS:
#myID: ID .myClass: Class ul/li: Elements
ul { font-weight: bold; } li { color: magenta; } .myClass { color: red; } #myID { color: blue; font-weight: normal; font-style: italic;}
Open basic-selectors.html in your browser.
Modify the CSS to see how Specificity works.
Specificity is the means by which a browser decides which property values are the most relevant to an element and gets to be applied. Specificity is only based on the matching rules which are composed of selectors of different sorts.
In case of specificity equality, the latest declaration found in the CSS is applied to the element.
.favorite { color: red; } .favorite { color: black; }
The color will be black because it comes last in the cascade
ul#summer-drinks li.favorite { color: green; font-weight: bold; }
The color will now be green, because this is more specific that the previous declaration.
html body div#pagewrap ul#summer-drinks li.favorite { color: magenta; font-weight: bold; }
The color will now be magenta, because this is the most specific of them all.
.favorite { color: orange !important; font-weight: bold !important; }
The !important declaration is like a ninja and will force itself over all other declarations.
This should be used sparingly
An illustrated SpeciFISHity chart
* :before :root :enabled E ::before :last-child :disabled .class ::selection :only-child :checked #id :after :nth-child() :indeterminate E F ::after :nth-last-child() :default E > F :first-letter :first-of-type :valid E + F ::first-letter :last-of-type :invalid E[attribute] :first-line :only-of-type :in-range E[attribute=value] ::first-line :nth-of-type() :out-of-range E[attribute~=value] E[attribute^=value] :nth-last-of-type() :required E[attribute|=value] E[attribute$=value] :empty :optional :first-child E[attribute*=value] :not() :read-only :lang() E ~ F :target :read-write
Checkout caniuse.com for compatability across browsers.
Advanced ways to target elements using basic selectors.
Descendant selector matches nested <li>s
Child selector matches <li>s in <ol> but not nested <ul>
Adjacent sibling
general sibling selector matches later siblings, but not nested.
element[attribute]
Select elements containing the named attribute
img[alt] {} <img src="image.jpg" alt="accessible"> <img src="image.jpg" title="inaccessible"> form [type] {} <input type=date> <select>
E[attr]
Element E that has the attribute attr with any value.
a[href] { background: pink; } /* Styles all links with the attribute 'href' */
E[attr="val"]
Element E that has the attribute attr with the exact, case-sensitive if attribute is case sensitive, value val.
a[href="http://girldevelopit.com"] { background: magenta; font-weight: bold; } /* Styles all links to http://girldevelopit.com */
E[attr|=val]
Element E whose attribute attr has a value val or begins with val- ("val" plus "-").
p[lang|="en"] {background: url(icon-flag.png); } /* Syles elements <p lang="en-us"> OR <p lang="en-uk"> */
E[attr~=val]
Element E whose attribute attr has within its value the space-separated full word val.
a[title~=more] { color: orange; } /* Styles links that have a title that contain 'more' surrounded by spaces. <a title="want more info about this?"> */
E[attr^=val]
Element E whose attribute attr starts with the value val.
a[href^=mailto] {background-image: url(emailicon.gif);} a[href^=http]:after {content: " (" attr(href) ")";}
E[attr$=val]
Element E whose attribute attr ends in val .
a[href$=pdf] {background-image: url(pdficon.gif);} a[href$=pdf]:after {content: " (PDF)";}
E[attr*=val]
Element E whose attribute attr matches val anywhere within the attribute.
Note: Multiple attributes work! a[title][href]
To review
input[placeholder] {} E:[attr] input[type=email] {} E:[att=val] abbr[title~=unicorn] {} E:[att~=val] abbr[title|=en] {} E:[att|=val] a[href^=mailto] {} E:[att^=val] a[href$=pdf]{} E:[att$=val] abbr[title*=unicorn] {} E:[att*=val]
Don't forget, you can use Attribute Selectors in Media Queries
@media print{ abbr[title]:after { content: "(" attr(title) ")"; } a[href^=http]:after { content: "(" attr(href) ")"; } }
Open attribute-selectors.html in your web browser.
Change the CSS and see what happens.
Based on the current state of the UI
:enabled :disabled :checked :focus
input[type=checkbox]:checked + label { color: red; }
valid :in-range :invalid :out-of-range :required :read-only :optional :read-write :default
Examples:
input:valid { border: 1px solid green;} input:invalid { border: 1px solid red;} input:required {border-width: 5px;} input:optional {border-width: 10px;} input:out-of-range { background-color: pink;} input:in-range { background-color:lightgreen;}
Open ui-selectors.html in your web browser.
Change the CSS and click the checkboxes to see how the form UI changes.
:nth-child() :first-of-type :nth-last-child() :last-of-type :nth-of-type() :only-child :nth-last-of-type() :only-of-type :first-child* :root :last-child :empty :not(:empty)
Target elements on the page based on their relationships to other elements in the DOM.
Updates dynamically if page updates.
Reduced need for extra markup, classes and IDs
Open structural-selectors.html in your browser.
Experiment with targetting different element on the page with Structural Selectors.
Target element or elements based on argument passed to the selector
:nth-child(3n) :nth-last-child(odd) :nth-of-type(5) :nth-last-of-type(3n+1) :nth-of-type(even) :nth-of-type(odd) :nth-of-type(an+b)
li:first-child, li:last-child { font-weight: bold; } li:first-of-type, li:last-of-type{ text-decoration:line-through; } li:nth-child(even) { background-color: #CCC; } li:nth-child(3) { color: #CCC; } li:nth-of-type(odd) { background-color: #FFF; } li:nth-of-type(4n) { color: hsl(205, 87%, 50%); } li:nth-of-type(3n-1) { text-align: right; }
Nth-child can be very confusing. Here's some resources:
Open nth-child-selectors.html in your browser.
Change the values of the nth-child to see what cells change colors
Open flag.html and see how crazy you can get with nth-child selectors.
These should be familar.
:link :visited :hover :active :focus :not :empty :lang :target
The :not selector creates an argument using a simple selector and then matches elements on the page that do not match that element.
Open not-selector.html in your browser
Try using our previous selectors to styles things (or not!).
Pseudo classes select elements that already exist
Pseudo Elements create fake elements you can style.
p:first-of-type::first-letter { position: relative; top: 8px; float: left; font-size: 3em; line-height: 1; color: magenta; padding: 0 4px 2px 0; font-weight: bold; }
Open first-letter.html to play with this pseudo-element.
You can use ::after and ::before in combination with 'content' to add some elements to your page without having to edit the HTML
.triangle-border { position:relative; padding:15px; margin:1em 0 3em; border:5px solid #5a8f00; color:#333; background:#fff; } .triangle-border::before { content:""; position:absolute; bottom:-20px; left:40px; border-width:20px 20px 0; border-style:solid; border-color:#5a8f00 transparent; } .triangle-border::after { content:""; position:absolute; bottom:-13px; left:47px; border-width:13px 13px 0; border-style:solid; border-color:#fff transparent; }
Open after-before.html to see this in action.
Icon fonts use ::before to insert a unicode character with 'content' that is associated with a glyph in that font.
.icon-search:before { content: "\f002"; } .icon-envelope-o:before { content: "\f003"; } .icon-heart:before { content: "\f004"; }
::beore and :before are often interchangable.
Don't forget, when using fancy CSS3 properties you need to add the vendor prefixes so all browsers can play.
selector { property: value; -webkit-property: value; -moz-property: value; -ms-property: value; -o-property: value; }
div { border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; }
div { -webkit-text-fill-color: black; -webkit-text-stroke-color: magenta; -webkit-text-stroke-width: 0.00px; }
color: rgba(255, 0, 0, 0.75); background: rgba(0, 0, 255, 0.75);
color: hsla( 128, 75%, 33%, 1.00);
background-image: linear-gradient(to bottom, #00abeb 0%, #fff 50%, #66cc00 50%, #fff 100%);
background-image: radial-gradient(center, circle cover, red, #000 40%);
text-shadow: rgba(64, 64, 64, 0.5) 0px 0px 0px; box-shadow: rgba(0, 0, 128, 0.25) 0px 0px 0px;
@font-face { font-family: 'alpha_echoregular'; src: url('fonts/alpha_echo-webfont.eot'); src: url('fonts/alpha_echo-webfont.eot?#iefix') format('embedded-opentype'), url('fonts/alpha_echo-webfont.woff') format('woff'), url('fonts/alpha_echo-webfont.ttf') format('truetype'), url('fonts/alpha_echo-webfont.svg#alpha_echoregular') format('svg'); font-weight: normal; font-style: normal; } .special-header { font-family: 'alpha_echoregular'; }
#box-1, #box-2 { background: magenta; } #box-1:hover, #box-2:hover { background: lime; } #box-2 { -webkit-transition: background 1s ease-in-out; -moz-transition: background 1s ease-in-out; -ms-transition: background 1s ease-in-out; -o-transition: background 1s ease-in-out; transition: background 1s ease-in-out; }
Hover over me:
-webkit-transform: rotateY(45deg); -webkit-transform: scaleX(25deg); -webkit-transform: translate3d(0, 0, 90deg); -webkit-transform: perspective(500px)
#threed-example { -webkit-transform: rotateZ(5deg); -webkit-transition: -webkit-transform 2s ease-in-out; } #threed-example:hover { -webkit-transform: rotateZ(-5deg); }
@-webkit-keyframes pulse { from { opacity: 0.0; font-size: 100%; } to { opacity: 1.0; font-size: 200%; } } div { -webkit-animation-name: pulse; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: ease-in-out; -webkit-animation-direction: alternate; }
Use your new powers for good!
October 15th. 6p - 8p
Galvanize - Boulder
October 18th. 10a - 1p
Amante Coffee Baseline - Boulder
October 25th. 9a-5:30p
Turing School - Denver