Week 2
Day 5
CSS works by associating rules with HTML elements.
These rules govern how the content of specified elements should be displayed.
CSS declarations sit inside curly brackets and each is made up of two parts: a property and a value, separated by a colon.
Three ways
1. Embedded,<style> CSShere </style>
2. Inline CSS
3. External CSS
<html>
<head>
</head>
<body>
<h1 style = "color:#36C;"> This is inline CSS </h1>
</body>
</html>
<head>
<link type = "text/css" href = "..." rel = "stylesheet" />
</head>
There are many different types of CSS selector that allow you to target rules to specific elements in an HTML document.
Applies to all elements in the document
* {
color: #343434
}
Targets all elements on the page
Matches Element Names
h1, h2, h3 {
height: 24px;
}
Targets the <h1>, <h2> and <h3> elements
Matches an element whose class attribute has a value that matches the one specified after the period (or full stop) symbol
.note {
}
Targets any element whose class
attribute has a value of note
p.note {
}
Targets only <p> elements
whose class attribute has a
value of note
Matches an element whose id attribute has a value that matches the one specified after the pound or hash symbol
#introduction {
}
Targets the element whose
id attribute has a value of
introduction
Matches an element that is a direct child of another
li > a {
}
Targets any <a> elements that
are children of an <li> element
(but not other <a> elements in
the page)
Matches an element that is a descendent of another specified element (not just a direct child of that element)
p a {
}
Targets any <a> elements that
sit inside a <p> element, even if
there are other elements nested
between them
The adjacent sibling combinator (+) separates two selectors and matches the second element only if it immediately follows the first element, and both are children of the same parent element.
h1+p {
}
Targets the first <p> element
after any <h1> element (but not
other <p> elements)
Matches an element that is a sibling of another, although it does not have to be the directly preceding element
h1~p {
}
If you had two <p> elements that
are siblings of an <h1> element,
this rule would apply to both
A pseudo-class is used to define a special state of an element.
selector:pseudo-class {
property:value;
}
input.submit:hover {
background-color: #665544;
}
input.submit:active {
background-color: chocolate;
}
input.text:focus {
color: #665544;
}
a:link {
color: deeppink;
text-decoration: none;
}
a:visited {
color: black;
}
a:hover {
color: deeppink;
text-decoration: underline;
}
a:active {
color: darkcyan;
}
:first-child
:nth-child(n)
:nth-last-child(n)
:nth-of-type(n)
:nth-last-of-type(n)
:last-child
:first-of-type
:last-of-type
:only-child
:only-of-type
:root
:empty
::before, ::after, ::first-letter, ::first-line, ::selection
1. The ::before selector inserts something before the content of each selected element(s).
2. The ::after selector inserts something after the content of each selected element(s).
3. The ::first-letter selector selects the first letter of every element it is used on.
4. The ::first-line selector selects the first line of every element it is used on.
5. The ::selection selector selects the portion of an element that is selected by a user
<style>
p::after {
content: " - Remember this";
background-color: yellow;
color: red;
font-weight: bold;
}
p::before{
content: 'hello'
}
</style>
</head>
<body>
<p>My name is Donald</p>
</body>
There are also a set of attribute selectors that allow you to create rules that apply to elements that have an attribute with a specific value.
a[target] {
background-color: yellow;
}
Matches a specific attribute (whatever its value)
p[class]{
}
/* Targets any <p> element with an
attribute called class
*/
[]
Matches a specific attribute with a specific value
p[title="dog"]{
}
/* Targets any <p> element with
an attribute called class whose
value is dog.
*/
[=]
Matches a specific attribute whose value appears in a space separated list of words
p[title~="dog"]{
}
/* Targets any <p> element with
an attribute called class whose
value is a list of space-separated
words, one of which is dog.
/*
[~=]
Matches a specific attribute whose value begins with a specific string
p[attr^="d"]{
}
/* Targets any <p> element with
an attribute whose value begins
with the letter "d".
*/
[^=]
Matches a specific attribute whose value contains a specific substring
p[attr*="do"]{
}
/* Targets any <p> element with an
attribute whose value contains
the letters "do".
*/
[*=]
Matches a specific attribute whose value ends with a specific string
p[attr$="g"]{
}
/* Targets any <p> element with an
attribute whose value ends with
the letter "g".
*/
[$=]
If the two selectors are identical, the latter of the two will take precedence
If one selector is more specific than the others, the more specific rule will take precedence
Ex: h1 is more specific than *, p b more than p
You can add !important after any property value to indicate that it should be considered more important than other rules
body {
font-family: 'Helvetica';
}
This will apply to most child elements. This is because the value of the font-family property is inherited by child elements.
p {
background-color: #333;
This will apply to most child elements. This is because the value of the font-family property is inherited by child elements.
<div>
<p>This is a paragraph.</p>
</div>
body {
color: green;
}
div p {
color: blue;
}
div + p {
color: grey;
}
div > p {
color: red;
}
<div id="div_id" class="div_class">
<p class="p_class" id="p_id">
This is a paragraph.
</p>
</div>
body {
color: green;
}
#p_id {
color: blue;
}
.div_class .p_class {
color: red;
}
<div class="parent" style="color: red !important;">
<div class="child">
I'm the child and what is my color?
</div>
</div>
.child {
color: blue;
}
<p>I'm <strong>important</strong></p>
p strong {
background-color: khaki;
color: green;
}
strong {
text-decoration: underline;
color: red;
}
body {
color: aqua;
}
p {
font-size: 30px;
}
The user (or reader) of the web site can choose to override styles in many browsers using a custom user stylesheet designed to tailor the experience to the user's wishes.
Specificity is basically a measure of how specific a selector is — how many elements it could match.
Element selectors have low specificity.
Class selectors have a higher specificity, so will win against element selectors.
ID selectors have an even higher specificity, so will win against class selectors.
The only way to win against an ID selector is to use !important.
Note: Universal selector (*), combinators (+, >, ~, ' ') and negation pseudo-class (:not) have no effect on specificity.
The amount of specificity a selector has is measured using four different values (or components), which can be thought of as thousands, hundreds, tens and ones — four single digits in four columns:
Thousands: Score one in this column if the declaration is inside a style attribute (such declarations don't have selectors, so their specificity is always simply 1000.) Otherwise 0.
Hundreds: Score one in this column for each ID selector contained inside the overall selector.
Tens: Score one in this column for each class selector, attribute selector, or pseudo-class contained inside the overall selector.
Ones: Score one in this column for each element selector or pseudo-element contained inside the overall selector.
Thousands |
Hundreds |
Tens |
Ones |
Total specificity |
|
---|---|---|---|---|---|
h1 |
0 |
0 |
0 |
1 |
0001 |
h1 + p::first-letter |
0 |
0 |
0 |
3 |
0003 |
li > a[href*="en-US"] > .inline-warning |
0 |
0 |
2 |
2 |
0022 |
#identifier |
0 |
1 |
0 |
0 |
0100 |
Note: If multiple selectors have the same importance and specificity, which selector wins is decided by which comes later in the Source order.
p {
color: blue;
}
/* This rule will win over the first one */
p {
color: red;
}
One thing you should bear in mind when considering all this cascade theory, and what styles get applied over other styles, is that all this happens at the property level — properties override other properties, but you don't get entire rules overriding other rules.
When several CSS rules match the same element, they are all applied to that element.
Only after that are any conflicting properties evaluated to see which individual styles will win over others.
<p>I'm <strong>important</strong></p>
/* specificity: 0002 */
p strong {
background-color: khaki;
color: green;
}
/* specificity: 0001 */
strong {
text-decoration: underline;
color: red;
}
The idea is that some property values applied to an element will be inherited by that element's children, and some won't.
For example, it makes sense for font-family and color to be inherited, as that makes it easy for you to set a site-wide base font by applying a font-family to the <html> element;
you can then override the fonts on individual elements where needed.
It would be really annoying to have to set the base font separately on every element.
As another example, it makes sense for margin, padding, border, and background-image to NOT be inherited. Imagine the styling/layout mess that would occur if you set these properties on a container element and had them inherited by every single child element, and then had to unset them all on each individual element!
The initial value of a CSS property is its default value, as listed in its definition table. The usage of the initial value depends on whether a property is inherited or not:
inherit
Sets the property value applied to a selected element to be the same as that of its parent element.
initial
Sets the property value applied to a selected element to be the same as the value set for that element in the browser's default style sheet. If no value is set by the browser's default style sheet and the property is naturally inherited, then the property value is set to inherit instead.
CSS provides four special universal property values for specifying inheritance:
unset
Resets the property to its natural value, which means that if the property is naturally inherited it acts like inherit, otherwise it acts like initial.
revert
Reverts the property to the value it would have had if the current origin had not applied any styles to it. In other words, the property's value is set to the user stylesheet's value for the property (if one is set), otherwise, the property's value is taken from the user agent's default stylesheet.
In CSS, there is a special piece of syntax you can use to make sure that a certain declaration will always win over all others: !important.
Note: The only way to override this !important declaration would be to include another !important declaration of the same specificity later in the source order, or one with a higher specificity.
CSS Layouts lets us place boxes in the right place in relation to the viewport, and one another.
Normal Flow
Normal flow is how the browser lays out HTML pages by default when you do nothing to control page layout.
<p>I love my cat.</p>
<ul>
<li>Buy cat food</li>
<li>Exercise</li>
<li>Cheer up friend</li>
</ul>
<p>The end!</p>
CSS helps you to position your HTML element. You can put any HTML element at whatever location you like.
The position property can help you manipulate the location of an element, for example:
.element {
position: relative;
top: 20px;
}
In normal flow, each block-level element sits on top of the next one
{
position: static;
}
static: every element has a static position by default, so the element will stick to the normal page flow. So if there is a left/right/top/bottom/z-index set then there will be no effect on that element.
Relative positioning moves an element in relation to where it would have been in normal flow. For example, you can move it 10 pixels lower than it would have been in normal flow or 20% to the right.
{
position: relative;
top: 20px;
}
relative: an element’s original position remains in the flow of the document, just like the static value.
But now left/right/top/bottom/z-index will work.
The positional properties “nudge” the element from the original position in that direction.
When the position property is given a value of absolute, the box is taken out of normal flow and no longer affects the position of other elements on the page. (They act like it is not there.)
It is positioned relative to the nearest parent with position:relative.
{
position: absolute;
top: 20px;
}
Fixed positioning is a type of absolute positioning that requires the position property to have a value of fixed.
It positions the element in relation to the browser window.
Therefore, when a user scrolls down the page, it stays in the exact same place. It is a good idea to try this example in your browser to see the effect.
{
position: fixed;
top: 20px;
}
{
position: sticky;
top: 20px;
}
The Flexbox Layout (Flexible Box) module aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic.
The main idea behind the flex layout is to give the container the ability to alter its items' width/height (and order) to best fill the available space.
Since flexbox is a whole module and not a single property, it involves a lot of things including its whole set of properties. Some of them are meant to be set on the container (parent element, known as "flex container") whereas the others are meant to be set on the children (said "flex items").
The two axes of flexbox
The main axis is defined by flex-direction, which has four possible values:
row
row-reverse
column
column-reverse
Flex Container Properties
Flex Item Properties
This defines a flex container; inline or block depending on the given value. It enables a flex context for all its direct children.
.container{
flex-wrap: nowrap | wrap | wrap-reverse;
}
By default, flex items will all try to fit onto one line. You can change that and allow the items to wrap as needed with this property.
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
This establishes the main-axis, thus defining the direction flex items are placed in the flex container. Flexbox is (aside from optional wrapping) a single-direction layout concept.
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}
This defines the alignment along the main axis.
.container {
align-items: flex-start | flex-end | center | baseline | stretch;
}
This defines the default behaviour for how flex items are laid out along the cross axis on the current line.
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
This aligns a flex container's lines within when there is extra space in the cross-axis. Note: no effect when there is only one line of flex items.
order
flex-grow
This property specifies how much of the remaining space in the flex container should be assigned to the item (the flex grow factor).
flex-shrink
flex-basis
It sets the initial main size of a flex item. It sets the size of the content box unless otherwise set with box-sizing.
align-self
auto | flex-start | flex-end | center | baseline | stretch
Grid Container
Grid Item
Grid Container
The Absolute Lengths
px
in
cm and mm
The Font-Relative Lengths
Em
Percentage
The Viewport Percentage Lengths
vw
vh
vmin
vmax
This value will be whichever is larger at the moment, vw or vh.
Every element in web design is a rectangular box.
Margin is unique in that it doesn't affect the size of the box itself per se, but it affects other content interacting with the box, and thus an important part of the CSS box model.
The width and height properties set the width and height of the content box
.some-class{
height: 40px;
width: 100%;
}
min-width
min-height
max-width
max-height
.some-class{
padding: 10px 8px 10px 8px;
}
Padding refers to the inner margin of a CSS box
.some-class{
border: 2px solid #232323;
}
The border of a CSS box sits between the outer edge of the padding and the inner edge of the margin. By default the border has a size of 0
.some-class{
margin: 10px auto 10px auto;
}
The margin surrounds a CSS box, and pushes up against other CSS boxes in the layout.
Width | width + padding-left + padding-right + border-left + border-right |
Height | height + padding-top + padding-bottom + border-top + border-bottom |
The box-sizing property in CSS controls how the box model is handled for the element it applies to.
The box-sizing CSS property defines how the user agent should calculate the total width and height of an element.
Responsive Web Design
The use of mobile devices to surf the web is growing at an astronomical pace, but unfortunately much of the web isn't optimized for those mobile devices.
A multitude of different screen sizes exist across phones, "phablets," tablets, desktops, game consoles, TVs, and even wearables.
Responsive web design, originally defined by Ethan Marcotte in A List Apart, responds to the needs of the users and the devices they're using.
Set the viewport
<meta name="viewport" content="width=device-width, initial-scale=1">
Size content to the viewport
On both desktop and mobile devices, users are used to scrolling websites vertically but not horizontally; forcing the user to scroll horizontally or to zoom out in order to see the whole page results in a poor user experience.
Instead, consider using relative width values, such as width: 100%.
Use CSS media queries for responsiveness
/* When the browser is at least 600px and above */
@media screen and (min-width: 600px) {
.element {
/* Apply some styles */
}
}
Media queries are a way to target browser by certain characteristics, features, and user preferences, then apply styles or run other code based on those things.
Media type
Media Feature
A responsive grid-view often has 12 columns, and has a total width of 100%, and will shrink and expand as you resize the browser window.
@media (max-width: 600px) {
body {
background-color: lightblue;
}
}
It uses the @media rule to include a block of CSS properties only if a certain condition is true.
Find it on csstricks.com
CSS Grid Layout is the most powerful layout system available in CSS.
It is a 2-dimensional system, meaning it can handle both columns and rows, unlike flexbox which is largely a 1-dimensional system.
<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
The element on which display: grid is applied. It's the direct parent of all the grid items
The children (e.g. direct descendants) of the grid container.
1. Transitions
2. Animations
.element {
transition:
[property]
[duration]
[ease]
[delay]
}
The animation property in CSS can be used to animate many other CSS properties such as color, background-color, height, or width.
Each animation needs to be defined with the @keyframes at-rule which is then called with the animation property
.element {
animation: pulse 5s infinite;
}
@keyframes pulse {
0% {
background-color: #some-color;
}
100% {
background-color: #another-color;
}
}
animation-name: declares the name of the @keyframes at-rule to manipulate.
animation-duration: the length of time it takes for an animation to complete one cycle.
animation-timing-function: establishes preset acceleration curves such as ease or linear.
animation-delay: the time between the element being loaded and the start of the animation sequence.
animation-direction: sets the direction of the animation after the cycle. Its default resets on each cycle.
animation-iteration-count: the number of times the animation should be performed.
animation-fill-mode: sets which values are applied before/after the animation.
For example, you can set the last state of the animation to remain on screen, or you can set it to switch back to before when the animation began.
animation-play-state: pause/play the animation.
Games
Scrolling Effects
Dropdown menus
Form Validations
Interactivity
Animations
Every awesome site ever
Definitions:
The Document Object Model is a platform- and language-neutral interface that will allow programs and scripts to dynamically access and update the content, structure and style of documents. The document can be further processed and the results of that processing can be incorporated back into the presented page. This is an overview of DOM-related materials here at W3C and around the web. - W3C
<html>
<body>
<p>
Hello World
</p>
<div> <img src="example.png"/></div>
</body>
</html>
The output tree (the "parse tree") is a tree of DOM element and attribute nodes. DOM is short for Document Object Model.
It is the object presentation of the HTML document and the interface of HTML elements to the outside world like JavaScript.
There are more ...
ATTRIBUTE_NODE is not actually part of a tree, but rather is listed for historical reasons.
Be aware that the ATTRIBUTE_NODE is being deprecated in DOM4.
Examples
Object < Node < Element < HTMLElement < (e.g., HTML*Element)
Object < Node < Attr (this is deprecated in DOM4)
Object < Node < CharacterData < Text
Object < Node < Document < HTMLDocument
Object < Node < DocumentFragment
< indicates “inherited from”
document.doctype.nodeName
// "html"
document.doctype
// <!DOCTYPE html>
document.doctype.nodeType
// 10
document.querySelector('a')
// <a ../>
document.querySelector('a').nodeName
// "A"
document.querySelector('a').nodeType
// 1
The document comes with a bunch of methods for selecting elements. We're going to learn about the following 5:
const tag = document.getElementById("highlight");
const tags = document.getElementsByClassName("bolded");
<body>
<h1>Hello</h1>
<h1>Goodbye</h1>
<ul>
<li id="highlight">List Item 1</li>
<li class="bolded">List Item 2</li>
<li class="bolded">List Item 3</li>
</ul>
</body>
document.getElementById()
document.getElementsByClassName()
document.querySelector()
document.getElementsByTagName()
const tags = document.getElementsByTagName("li");
const tags = document.getElementsByTagName("h1");
const tag = document.querySelector(".bolded");
const tags = document.querySelectorAll("h1");
<body>
<h1>Hello</h1>
<h1>Goodbye</h1>
<ul>
<li id="highlight">List Item 1</li>
<li class="bolded">List Item 2</li>
<li class="bolded">List Item 3</li>
</ul>
</body>
document.querySelectorAll()
createElement() and createTextNode()
const elementNode = document.createElement('div');
const textNode = document.createTextNode('Hi');
<!DOCTYPE html>
<html lang="en">
<body>
<div id="A"></div>
<span id="B"></span>
<div id="C"></div>
<div id="D"></div>
<div id="E"></div>
</body>
</html>
//create a strong element and text node and add it to the DOM
document.getElementById('A').innerHTML = '<strong>Hi</strong>';
/* create a div element and text node to replace <span id="B"></div>
(notice span#B is replaced) */
document.getElementById('B').outerHTML = '<div id="B"
class="new">Whats Shaking</div>'
//create a text node and update the div#C with the text node
document.getElementById('C').textContent = 'dude';
//NON standard extensions below i.e., innerText and outerText
//create a text node and update the div#D with the text node
document.getElementById('D').innerText = 'Keep it';
/* create a text node and replace the div#E with the text node
(notice div#E is gone) */
document.getElementById('E').outerText = 'real!';
console.log(document.body.innerHTML);
/* logs
<div id="A"><strong>Hi</strong></div>
<div id="B" class="new">Whats Shaking</div>
<span id="C">dude</span>
<div id="D">Keep it</div>
real!
*/
appendChild() and insertBefore()
The appendChild() method will append a node (or multiple nodes) to the end of the child node(s) of the node the method is called on.
//create a blink element node and text node
var elementNode = document.createElement('strong');
var textNode = document.createTextNode(' Dude');
//append these nodes to the DOM
document.querySelector('p')
.appendChild(elementNode);
document.querySelector('strong')
.appendChild(textNode);
//log's <p>Hi<strong> Dude</strong></p>
The insertBefore() method requires two parameters: the node to be inserted and the reference node in the document before which you would like the node inserted.
//create a text node and li element
// node and append the text to the li
var text1 = document.createTextNode('1');
var li = document.createElement('li');
li.appendChild(text1);
//select the ul in the document
var ul = document.querySelector('ul');
/*
add the li element we created
above to the DOM, notice I call on <ul>
and pass reference to <li>2</li>
using ul.firstChild
*/
ul.insertBefore(li,ul.firstChild);
console.log(document.body.innerHTML);
/*logs
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
*/
removeChild() and replaceChild()
//remove element node
var divA = document.getElementById('A');
divA.parentNode.removeChild(divA);
//remove text node
var divB = document.getElementById('B').firstChild;
divB.parentNode.removeChild(divB);
<div id="A">Hi</div>
<div id="B">Dude</div>
//set
divStyle.backgroundColor = 'red';
divStyle.border = '1px solid black';
divStyle.width = '100px';
divStyle.height = '100px';
const divStyle = document.querySelector('div').style;
// Remove
divStyle.backgroundColor = '';
divStyle.border = '';
divStyle.width = '';
divStyle.height = '';
//get
console.log(divStyle.backgroundColor);
console.log(divStyle.border);
console.log(divStyle.width);
console.log(divStyle.height);
setProperty(propertyName, value)
removeProperty()
divStyle.setProperty('background-color','red');
divStyle.setProperty('border','1px solid black');
getProperty(propertyName)
divStyle.getPropertyValue('background-color');
divStyle.getPropertyValue('border');
cssText
divStyle.removeProperty('background-color');
divStyle.removeProperty('border');
divStyle.cssText = 'background-color:red;
border:1px solid black;
height:100px;
width:100px;';
getComputedStyle()
To get an element’s CSS from the cascade (i.e., cascading from inline stylesheets, external stylesheets, and browser stylesheets) as well as its inline styles.
Setting up events can be accomplished using
<body onclick="console.log('fire/trigger attribute event handler')">
var elementDiv = document.querySelector('div');
elementDiv.onclick = function() {
console.log('fire/trigger property event handler');
};
elementDiv.addEventListener('click',function() {
console.log('fire/trigger addEventListener')
}, false);
only the addEventListener() provides a robust and organized solution.
inline attribute event handlers
property event handlers
addEventListener() method.
The removeEventListener() method can be used to remove event listeners, if the original listener was not added using an anonymous function
var sayHi = function(){console.log('hi')};
//adding event listener using anonymous function
document.body.addEventListener('click',function(){
console.log('dude');
},false);
document.querySelector('div').removeEventListener('click',sayHi,false);
//adding event listener using function reference
document.querySelector('div').addEventListener('click',sayHi,false);
Anonymous functions added using the addEventListener() method simply cannot be removed.
Event objects are dispatched to an event target. But before dispatch can begin, the event object’s propagation path must first be determined.
Event Object
By default, the handler or callback function invoked for events is sent a parameter that contains all relevant information about the event itself
document.querySelector('div').addEventListener('click', function(event) {
Object.keys(event).sort().forEach(function(item){
console.log(item+' = '+event[item]); //logs event properties and values
});
},false);
preventDefault()
stopPropagation()
<table border="1">
<tbody>
<tr><td>row 1 column 1</td><td>row 1 column 2</td></tr>
<tr><td>row 2 column 1</td><td>row 2 column 2</td></tr>
<tr><td>row 3 column 1</td><td>row 3 column 2</td></tr>
<tr><td>row 4 column 1</td><td>row 4 column 2</td></tr>
<tr><td>row 5 column 1</td><td>row 5 column 2</td></tr>
<tr><td>row 6 column 1</td><td>row 6 column 2</td></tr>
</tbody>
</table>
document.querySelector('table').addEventListener('click', function(event) {
if(event.target.tagName.toLowerCase() === 'td'){
/* make sure we only run code if a td is the target */
console.log(event.target.textContent); /* use event.target to gain access
to target of the event which is
the td */
}
},false);