CSS 🐠
Cascading style sheets
CSS under the hood and best practices?
Browser
Loads the HTML
Parse the HTML
Create the DOM tree
Meanwhile, after the step2, it also loads CSS
Parses CSS (2 Steps)
Resolve conflicting CSS declarations through a process known as cascades
Process final CSS values (like converting % into px and so on)
Finally, the parsed CSS is stored in CSOM (CSS Object model just like DOM)
DOM + CSOM forms rendered tree
The browser uses the Visual formatting model to render the page using the rendered tree.
Finally, the website is rendered to the screen

CSS Parsing phase
Remember, in the parsing phase we have two steps: Let's look at the first step
Resolve conflicting CSS declarations through a process known as cascades
CSS Cascades

The CSS can come from many sources
The one we write is called Author declarations
The other one is User declaration where the user changes CSS in the browser
Browser declarations (default/ user-agent css) when no styles are applied by the developer
The cascade resolves conflicts using Specificity
CSS Architecture and BEM Methodology (Block Element Modifier)
How to architect the code

BEM is one of the CSS class naming conventions while writing HTML markups


Responsive images

Three ways of using responsive images
Overview: High resolution means high pixels. For example, Normal resolutions use 100 physical pixels to display 100px (1X screen). High resolution will have 2 physical pixels per 1px. So 100px will actually have 200 physical pixels (2X screens - Macbook with retina display)
Resolution switching - Using the same image but with a lower resolution for the small screen
Density switching (We use
srcset
instead of src) - Reducing the pixel density for a low-resolution screen. Using a different image that has low pixel density for a lower resolution screen. One image for higher res and the other for lower res.

Art direction (we use picture) - Using a different image altogether for a smaller screen


3 pillars of a good web-design

Vertically aligning items in center is a night-mare. Here's how to do it.
margin: auto
auto doesn't work. Second auto places in certer but first auto is considered to be 0. This is as per w3C standards but not sure why.
There are a few points you should understand before approaching this
Position absolute lifts up the element from normal flow and places it at the left top corner (still floated and not on the base yet) of relatively positioned element.
When element is still floating, the margin:auto doesn't work. The width, and height and margin(of some value) still works. The moment you set position :absolute, the width and height sets to fit content even though it is a block element.
How to remember what works
Well, imagine the element is lifted to outer dimension and it has no access to it's sorroundings. In that case the margin:auto cannot be set because margin is related to it's sorrounding. When I say margin 20px, this works because it understands, "Ok I need to move 20px all sides". Remember it is still not related to it's sorroundings.
So the question is how to remember what properties work on an absoultely positioned/lifted element? Any property which is related to element itself and not to it's sorroundings will work. Except margin:auto everything else work as they are related to the element itself.
Now considering back the floating element again. First, for a floated element to sit back on the normal flow, we need to specify top, bottom,left and right. Doing so will bring back the element to where ever we want.
This is the way we pick an element from where we don't want by defining
position: absoulte
top, left, bottom and right
.
Now that we understand how positioned absiolute works, we can now say the margin auto works now on absolutely positioned element after defining top,left,bottom and right.
Now that we understood the basics, lets move on.
To center the element vertically, the element must be positioned abosulte, set top, bottom, left and right to 0 and then put margin:auto auto.
But that's not it, the relative container and this absolute container should have a height defined.
Talking about the height, one thing is worth keeping in mind. Body height can be set to 100% only when it's parent's height (html height is set to 100%)
Container (div) inside body can be set (height) to 100% only when body's height is 100%. Meaning, for div to have 100% height, body and html should have 100% height. That is so much of pain. The simple way to directly set the height of this div container is by doing height:100vh. This is why 100vh is better than 100%.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./css/main.css" />
</head>
<body>
<div class="container">
<div class="center-container">
<p>Please center me</p>
</div>
</div>
</body>
</html>
How many ways CSS can be added to HTML?
3 ways
Inline styles ---- 1st priority
<style></style> tag within head ----- whichever comes first compared to link. Technically it should be placed inside the head but the truth is it can be placed anywhere in the HTML document and how many ever times you want.
External CSS - Linking style sheet to HTML using link tag in the head ----- whichever comes first compared to <style> tag
// Ist way
<body style="background-color: blue;">
</body>
// Second way
<style>
body{
background-color: red
}
</style>
//Third way (recommended) Linking style sheet to html
<link rel="stylesheet" href="style.css">
CSS Selectors
There 5 Major types of selectors
Simple selectors (select elements based on name, id, class)
Universal selector (*)
Element selector (h1, p, etc)
ID selector (#)
Class Selector (.)
Group Selector (h1,h2,h3)
Small variation of 2 and 5. ->
h3.myclass{ color : red} // all h3 having myclass class gets red color
Combinator selectors (select elements based on a specific relationship between them)
Pseudo-class selectors (select elements based on a certain state)
Pseudo-elements selectors (select and style a part of an element)
Attribute selectors (select elements based on an attribute or attribute value)
1. Simple selectors
/* Universal selector - Selects everything on the page */
*{
margin:0;
padding:0;
box-sizing: border-box;
}
/* ********************************** */
/* Element Selector */
p {
text-align: center;
color: red;
}
/* ********************************** */
/* ID Selector */
#para1 {
text-align: center;
color: red;
}
/* Class selector */
.center {
text-align: center;
color: red;
}
/* ********************************** */
/* Group selectors - Selectors having same props can be grouped together */
h1 {
text-align: center;
color: red;
}
h2 {
text-align: center;
color: red;
}
p {
text-align: center;
color: red;
}
/* The above can be grouped as */
h1, h2, p {
text-align: center;
color: red;
}
/* ********************************** */
/* Some variations of the above */
/* select all the p tags having class red in it*/
p.red{
color:'red'
}
2. Combinator selector
There are 4 combinator selectors
Descendant combinator (ul li) - all something inside something
Child combinator (div > p) - all direct children (p in this case) inside parent (div in this case)
Adjacent sibling combinator (h3 + p) - one p next to (sibling of) h3
General sibling combinator (h3 ~ p) - all p next to (siblings of ) h3
/* Descendent combinator selector */
/*html*/
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
/*css*/
ul li{
color:green /* all li inside ul is targeted*/
}
/* ********************************** */
/* Child combinator selector */
/*html*/
<div>
<p>This is a paragraph at outer level</p> //style applied
<article>
<p>This is a para inside article inside div</p> //not applied
</article>
<p>This is a paragraph at outer level</p> //style applied
</div>
/*css*/
div > p {
color: red; /* all direct p inside div*/
}
/* ********************************** */
/* Adjacent sibling combinator selector */
/*html*/
<p>This is p next to (above) h3</p>
<p>This is p next to (above) h3</p>
<h3>This is h3</h3>
<p>This is p next to (below - applied to this) h3</p>
<p>This is p next to (below) h3</p>
<p>This is p next to (below) h3</p>
<h3>This is h3</h3>
<p>This is p next to (below - applied to this) h3</p>
<div>
<p>This is p inside div</p>
</div>
/*css*/
h3 + p {
color: green; /* applied only to the first direct p that is next to (below and not above) h3 */
}
/* ********************************** */
/* General sibling combinator selector */
/*html*/
<p>This is p next to (above) h3</p>
<p>This is p next to (above) h3</p>
<h3>This is h3</h3>
<p>This is p next to (below - applied to this) h3</p>
<p>This is p next to (below - applied to this) h3</p>
<p>This is p next to (below - applied to this) h3</p>
<h3>This is h3</h3>
<p>This is p next to (below - applied to this) h3</p>
<div>
<p>
This is p inside div - NOT APPLIED AS THIS IS NOT A SIBLING WHICH IS
INSIDE div
</p>
</div>
/*css*/
h3 ~ p {
background-color: #fff;
color: black;
}
/*
NOTE : One difference between + and ~. + means select only one element next
to the given element whereas ~ means all elements next to given element
*/
3. Pseudo-class selector (:)
A pseudo-class is a keyword added to an element to define a special state of that element.
For example, it can be used to:
Style an element when a user mouses over it
Style visited and unvisited links differently
Style an element when it gets focus
Some of the most used pseudo-classes
/*hover on any element*/
a:hover{
color:green;
}
/* ********************************** */
/*for a link, there are different states so that can be selected*/
a:link{
color:blue; /*link -> not yet clickd*/
}
a:hover{
color:green; /*link -> hoverd*/
}
a:active{
color: red; /*link -> which is currently clicked*/
}
a:visited{
color: yellow; /*link -> clicked atleast once*/
}
/* ********************************** */
/* Selects any <p> that is the first element
among its siblings */
p:first-child {
color: lime;
}
/* example of :first-child*/
/*html*/
<div>
<p>This text is selected!</p> /* this is the element selected which is first-child*/
<p>This text isn't selected.</p>
</div>
<div>
<h2>This text isn't selected: it's not a `p`.</h2>
<p>This text isn't selected.</p>
</div>
/*css*/
p:first-child {
color: lime;
background-color: black;
padding: 5px;
}
/*html*/
case 1
<div>
<li>S</li>
<li>A</li>
<li>N</li>
<li>D</li>
</div>
case 2
<div>
<h2>This is h2</h2>
<li>S</li>
<li>A</li>
<li>N</li>
<li>D</li>
</div>
/*css*/
li:first-child {
color: blue;
background: #000;
}
/*This css will change first li in case 1 but doesn't change anything in case 2
because in case 2, li is not the first-child but h2 is the first-child. So the
first-child rule won't be applied.
Note: To make it work for case 2, we need to use first-of-type instead of first-child
*/
/* ********************************** */
/* Selects each <p>, but only if it is the */
/* only child of its parent */
p:only-child {
background-color: lime;
}
/* example of :only-child*/
/*html*/
<div>
<div>I am an only child.</div> /* only child*/
</div>
<div>
<div>I am the 1st sibling.</div>
<div>I am the 2nd sibling.</div>
<div>I am the 3rd sibling, <div>but this is an only child.</div></div>
</div>
/*css*/
div:only-child {
color: red;
}
/* ********************************** */
/* Selects the second <li> element in a list */
li:nth-child(2) {
color: lime;
}
/* Selects every fourth element
among any group of siblings */
:nth-child(4n) {
color: lime;
}
/* ********************************** */
/* Selects every fourth <p> element
among any group of siblings */
p:nth-of-type(4n) {
color: lime;
}
/*html*/
<div>
<div>This element isn't counted.</div>
<p>1st paragraph.</p>
<p class="fancy">2nd paragraph.</p>
<div>This element isn't counted.</div>
<p class="fancy">3rd paragraph.</p>
<p>4th paragraph.</p>
</div>
/*css*/
/* Odd paragraphs */
p:nth-of-type(2n+1) {
color: red;
}
/* Even paragraphs */
p:nth-of-type(2n) {
color: blue;
}
/* First paragraph */
p:nth-of-type(1) {
font-weight: bold;
}
/* This will match the 3rd paragraph as it will match elements which are 2n+1 AND have a class of fancy.
The second paragraph has a class of fancy but is not matched as it is not :nth-of-type(2n+1) */
p.fancy:nth-of-type(2n+1) {
text-decoration: underline;
}
/* ********************************** */
/* Selects any element that is NOT a paragraph */
:not(p) {
color: blue;
}
/* <p> elements that are not in the class `.fancy` */
p:not(.fancy) {
color: green;
}
/*NOTE : :first was used for printing pages and :first-child must be used for css*/
Full list here. Go through when you're super bored 😐
4. Pseudo-element selector (::)
A CSS pseudo-element is used to style specified parts of an element.
For example, it can be used to:
Style the first letter, or line, of an element
Insert content before, or after, the content of an element
There are 6 pseudo-element selectors
pseudo-element
usage
Works only for
Details
p::first-letter
works only for block elements
Selects the first letter of each <p> element
p::selection
If nothing is specified, just like ::selection
, then it works for all elements
Selects the portion of an element that is selected by a user
content:
is important inside before and after. Also, the box-sizing:border-box
doesn't apply for pseudo-elements, so we might have to specify it deliberately.
*,
::before,
::after{
box-sizing:border-box;
}
// PRACTICE HOVER AND SELECTORS
<!DOCTYPE html>
<html lang="en">
<head>
<title>Grid Practice</title>
</head>
<body>
<style>
h4:hover ~ div ul,
h4:hover ~ ul {
color: red;
background-color: antiquewhite;
}
</style>
<h4>Hover me</h4>
<p>This is p</p>
<ul>
<li>3rd child div's ul's li</li>
</ul>
<ul>
<li>3rd child div's ul's li</li>
</ul>
<ul>
<li>3rd child div's ul's li</li>
</ul>
<div>
<ul>
This is also ul
</ul>
</div>
</body>
</html>
5. Attribute selector
Targets all the elements with a specific attribute. We can also specify weather to select the values of the attribute also, and if yes, we can choose exactly the way we want to target the value containing something in the attribute
1. With an attribute
<style>
p[attr]{
color: red;
background-color: antiquewhite;
}
</style>
<p attr="s">This is a paragraph</p> // This gets selected coz it has attr attribute
<p>This is a paragraph</p>
<p>This is a paragraph</p>
2. With a specific value
<style>
p[attr="s"] {
color: red;
background-color: antiquewhite;
}
</style>
<!-- the below two gets selected -->
<p attr="s">This is a paragraph</p>
<p attr="s">This is a paragraph</p>
<p attr="m">This is a paragraph</p>
3. Contains a specific word (after space) in value of the attribute
<style>
p[attr~="word"] {
color: red;
background-color: antiquewhite;
}
</style>
<p attr="nospaceword">This contains a word</p>
<!-- the below one gets selected -->
<p attr="word">This word</p>
<p attr="m">This is a paragraph</p>
4. Contains a specific word (anywhere and not only that has space) in the value attrubute
<style>
p[attr*="word"] {
color: red;
background-color: antiquewhite;
}
</style>
<!-- the below two gets selected -->
<p attr="nospaceword">This contains a word</p>
<p attr="word">This word</p>
<p attr="m">This is a paragraph</p>
5. Starting with the value specified
<style>
p[attr^="word"] {
color: red;
background-color: antiquewhite;
}
</style>
<p attr="notstartingwithword">This contains a word</p>
<!-- the below two gets selected -->
<p attr="word">This word</p>
<p attr="m">This is a paragraph</p>
6. Ending with the value specified
<style>
p[attr$="word"] {
color: red;
background-color: antiquewhite;
}
</style>
<!-- the below one gets selected -->
<p attr="endingwithword">This contains a word</p>
<p attr="wordhasnoending">This word</p>
<p attr="m">This is a paragraph</p>
7. Starting with a value- at the beginning
p[attr|="word"] {
color: red;
background-color: antiquewhite;
}
</style>
<p attr="s-word">This contains a word</p>
<!-- the below one gets selected -->
<p attr="word-atstart">This word</p>
<p attr="m">This is a paragraph</p>
Box Model
Margin collapse
Margin collapse happens when two boxes have a margin in between them in which case, the box which has a higher margin is considered and the box which has a lower margin also gets the same margin from the box which has a higher margin. The two margins will not get added up.

Display property
display:inline
Inline elements cannot have width, height, top, and bottom
margin
,padding
. It can have left, and rightmargin
andpadding
. Elements can sit side by side.Example:
span
,a
display:block
Block elements will occupy the entire space even if the width is not 100%. Width and height can be set on this. Elements can't sit next to each other.
Example:
div,h1-h6, p, form, header, footer,text-area.img
display:inline-block
Similar to inline. But we can set width, height, top and bottom margins, and paddings. Elements can sit next to each other.
Example:
button, select
Flexbox
display:flex
Create an example in vscode with the code below and practice the given link.
<!-- FLEX BOX PRACTICE - https://css-tricks.com/snippets/css/a-guide-to-flexbox/ -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=\, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
.box {
width: 150px;
height: 150px;
font-size: 2rem;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.box1 {
background-color: rgb(43, 226, 165);
}
.box2 {
background-color: rgb(152, 192, 114);
}
.box3 {
background-color: rgb(163, 114, 192);
}
.box4 {
background-color: rgb(233, 109, 8);
}
.box5 {
background-color: rgb(22, 24, 21);
color: white;
}
.box6 {
background-color: rgb(10, 13, 187);
color: white;
}
.box7 {
background-color: rgb(209, 20, 20);
color: white;
}
.box8 {
background-color: rgb(121, 111, 114);
color: white;
}
.box9 {
background-color: rgb(114, 192, 173);
}
.box10 {
background-color: rgb(72, 219, 14);
}
.box11 {
background-color: rgb(244, 248, 8);
}
.box12 {
background-color: rgb(3, 2, 12);
color: white;
}
.container {
display: flex;
/* flex-direction: column; */
/* background-color: rgb(0, 183, 255); */
height: 40vh;
/* align-content: flex-start; */
justify-content: space-evenly;
/* align-items: ; */
}
</style>
<body>
<div class="container">
<div class="box box1">1</div>
<div class="box box2">2</div>
<div class="box box3">3</div>
<div class="box box4">4</div>
<div class="box box5">5</div>
<div class="box box6">6</div>
<div class="box box7">7</div>
<div class="box box8">8</div>
<div class="box box9">9</div>
<div class="box box10">10</div>
<div class="box box11">11</div>
<div class="box box12">12</div>
</div>
</body>
</html>
To learn each property quickly, here's the playlist you can refer to
Grid
display:grid
Learn the interactive way above
Grid assignments
Assignment 1

Assignment 2

Assignment 3

Assignment 4


Congratulations : 👏 You have now completed the first part of CSS grid. Let's learn some advance CSS grid techniques now
Assignment 5
Assignment 6
Assignment 7
How do you combine CSS grid with Flexbox?
Well, a grid item can be made flex container to layout the items in one dimension.
Practice grid by building this
Grid Cheat sheet
Text properties
text-align
text-align
can be center/right/left. We can use this to align the text inside a div. We can't move the entire div itself using text-align.
margin:auto
works to move the div to the center provided, the width of the div must be less than 100%.
text-decoration
can be underline, overline, line-through, and so on.
text-transform
capitalize, uppercase, lowercase
Font properties
font-size
Font size can be in px
, rem
, em
and %
. 1px is 1 unit of the number of pixels present on the screen. Giving this is not good because every screen size will show the fonts differently.
em
is relative to the parent's font size. If parent is 10px and child is 3em then child gets 3 * 10px = 30px.
<style>
.parent {
font-size: 20px;
}
.child {
font-size: 3em;
}
</style>
<div class="parent">
<p>This is in parent</p> <!-- 10px -->
<div class="child">
<p>This is in child</p> <!-- 3em which is 3 * 10px of parent = 30px -->
</div>
</div>
rem
is relative to the root's font size. The root is <html> stag. The default value of html
is 16px.

For easy calculations, we take this 16px root font size as 10px by making it 62.5% so it will be consistent on all screens.
html {
font-size: 62.5%;
/* now 1rem is not 16px but 1rem = 10px*/
/* with this we can use rem everywhere and the calculation
will be simpler. 3rem will now be 3*10px = 30px and not
3*16
*/
}
% sets the font size in percentage. Let's say font-size
of the element is 20px. If I set it to 200% then it will become 40%.
Min-width vs Max-width
In media queries, I always have confusion as to min-width and max-width applications. Here's the clarity
/*max-width*/
@media screen and (max-width: 768px) {
/* below starts from 0 to 768px. Style applies if screen is between 0 and 768px*/
.booklist {
grid-template-columns: repeat(3, 1fr);
}
}
/*min-width*/
@media screen and (min-width: 768px) {
/* below starts from 768px. Style applies only if screen >= 768px*/
.booklist {
grid-template-columns: repeat(3, 1fr);
}
}
Position
static (default) - same as relative but top/bottom/left/right/z-index has no effect.
relative - same as static but top/bottom/left/right/z-index will now work
fixed
absolute
sticky
An element with position: static
;
is not positioned in any special way; it is always positioned according to the normal flow of the page.
position: relative;
An element with position: relative;
is positioned relative to its normal position. Setting the top, right, bottom, and left properties of a relatively positioned element will cause it to be adjusted away from its normal position. Other content will not be adjusted to fit into any gap left by the element.
An element with position: fixed;
is positioned relative to the viewport, which means it always stays in the same place even if the page is scrolled. The top, right, bottom, and left properties are used to position the element.
An element with position: absolute;
is positioned relative to the nearest positioned ancestor (instead of positioned relative to the viewport, like fixed). However; if an absolute positioned element has no positioned ancestors, it uses the document body, and moves along with page scrolling.
Other definition of position:absolute
The element is removed from the flow and is relatively positioned to its first non-static ancestor. to/bottom etc works.
An element with position: sticky;
is positioned based on the user's scroll position. A sticky element toggles between relative
and fixed
, depending on the scroll position. It is positioned relative until a given offset position is met in the viewport - then it "sticks" in place (like position:fixed
).
p.head {
background-color: blueviolet;
position: sticky;
top: 50px;
}
/* Position sticky always need to have top/bottom to work. generally we
set top unit so that when it reaches that particular unit from top
during scroll, it get's fixed. Unit then it remains relative*/
SaaS
Two versions of SaaS.
SaaS -> Indeneted
ScSS -> Parenthesis
Variables
CSS also has variables but saas had been introduced earlier.
/* CSS Variables*/
:root{
--primary-color : black;
}
body{
background-color: var(--primary-color)
}
/* SCSS Variables*/
$primary-color : black;
body{
background-color: $primary-color;
}
We can use a map to store scss variables just like JS map.
$colors: (
"main": black,
"second": white,
);
body {
background-color: map-get($colors, main);
color: map-get($colors, second);
}
Nesting
<body>
<div class="main">
<p class="main__paragraph">Please center me</p>
</div>
</body>
//scss
.main {
background-color: blue;
&__paragraph {
color: white;
}
}
//The above scss leads to css below
.main {
background-color: blue;
}
.main__paragraph {
color: white;
}
Looking above we can say & makes it possible to refer to the parent. What if I need . .main .main__paragraph{}.
I mean the descendent selector? that's where we use interpolation
Interpolation
// Scss
.main {
background-color: blue;
#{&}__paragraph { -> interpolatation, to target full parent and then it's continuation
color: white;
}
}
// css
.main {
background-color: blue;
}
.main .main__paragraph { -> result of interpolation
color: white;
}
File separation
We can separate the files in Saas for maintainablility. How to do that?
We create a partial saas files. This partial saas file will start with an underscore.
css file will not be created for this partial saas file, rather it will be treated as the part of main scss file which is just placed in a separeate file.
We then include this in the main saas file by using
@import nameOfParatialFile
. No need to put underscore or extension while importing
/*partial file _resetss.scss */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* main.css*/
@import "./resets"; /* note that we don't have to use _ or .scss extension while importing*/
.main {
background-color: blue;
&__paragraph {
color: white;
}
}
Functions
$font-weights: (
"regular": 300,
"medium": 500,
"bold": 700,
);
@function weight($property) {
@return map-get($map: $font-weights, $key: $property);
}
.main {
background-color: $primary-color;
&__paragraph {
color: $secondary-color;
font-weight: weight("medium"); /* gives 500*/
}
}
Mixins
Used when we want to avoid repeated typing.
Let's say we have some properties we always want to use in multple places. Then we can create a mixin for these commands and use them where we want. Writing a mixin will then be same as including those lines of CSS properties everywhere.
@mixin flexCenter {
background-color: $primary-color;
display: flex;
justify-content: center;
align-items: center;
}
.main {
@include flexCenter; /*same as writing all the above lines*/
}
Mixin wih an argument
What if we want to change flex-direction in the above example. Let's say for a few cases we have to have flex-direction row and columns a few times, so we can pass an argument.
@mixin flexCenter($direction) {
background-color: $primary-color;
display: flex;
justify-content: center;
align-items: center;
flex-direction: $direction;
}
.main {
@include flexCenter(column);
}
Function vs Mixin
The difference is, a function is used to set the property of a CSS. Let's say we want font-weight like in above functions example, we called the function at the value of font-weight like below
font-weigth:function()
Whereas, mixin is used to replace the lines of code and not just a single CSS property. In the above mixin example, we are replacing 5 lines of code (reusing these lines of code).
So, function -> for single property and mixin for multiple CSS lines.
Use cases of mixins
Can be used to set light and dark themes.
@if is an if loop similar to normal if loop.
/*declare a mixin*/
@mixin theme($light-theme: true) {
@if ($light-theme) {
background-color: lighten($color: $primary-color, $amount: 100%);
color: darken($color: $text-color, $amount: 100%);
}
}
/*include in a class*/
.light {
@include theme(true);
}
/*before applying mixin in html*/
body {
background-color: $primary-color;
color: $text-color;
}
/*include this in html*/
<body class="light">
Can be used to set media-queries
@content is a property which acts like a place-holder for set of values just like mixin. See the example below
/*Media query WITHOUT mixin*/
.main {
@include flexCenter(column);
&__paragraph {
font-weight: weight(bold);
margin: 2rem;
}
@media screen and (max-width: 800px) {
color: blue;
}
}
/* Media Query WITH mixin*/
$mobile: 800px;
@mixin mobile {
@media(max-width:$mobile){
@content;
}
}
.main {
@include flexCenter(column);
&__paragraph {
font-weight: weight(bold);
margin: 2rem;
}
/* @media screen and (max-width: 800px) {
color: blue;
}
*/
@include mobile {
color: blue;
}
}
Extend
Let's say you have two paragraphs and you have defined a bunch of styles for p1. Now, you want all those styles to be included in p2 but you want to make changes to one or two properties, then you can use extend. Imagine this like copying an object using spread operator {...} and then making necessary changes to the properties you want.
&__paragraph1 {
font-weight: weight(bold);
margin: 2rem;
}
&__paragraph2 {
@extend .main__paragraph1; /*saying - include everything from para1 and change margin to 4rem*/
margin: 4rem;
}
Calculations
/* In CSS */
margin: calc(20rem - 10rem);
/* In SaaS */
margin: 20rem - 10rem;
/*NOTE: Below is the CSS, we can't do this in SAAS (mixing types)*/
margin: calc(20rem - 1px); /*We can't mix types in Saas like this*/
Last updated
Was this helpful?