CSS Styling — Margin Collapsing in Action!!!

CSS Styling — Margin Collapsing in Action!!!

“Oh, No! Where did the margin between the two elements disappear? Did I mess up the margins?”

If you come across face such a scenario, don’t worry! Your margin might have just collapsed.

A few days back while going through CSS, I came across a very interesting topic called Margin Collapsing and thought of sharing my understanding of it. So, let’s dive into it.

What is Margin Collapsing in CSS?

Margin collapsing is a behavior of CSS where the vertical margins (margin-top or margin-bottom) of two block-level elements are combined (or collapsed) to one, i.e, to the margin of the element with the larger value.

Now that’s much on theory. So, lets delve into the 3 basic use-cases as mentioned in MDN web docs, to understand where this behavior comes into action:

1. Collapsing of margins between two vertically adjacent siblings.

Let’s assume that we have 4 block elements aligned vertically with some margin in between them as configured below.

.first-block{
  margin-bottom: 25px;
}second-block{
  margin-top: 50px;
  margin-bottom: 50px;
}.third-block {
  margin-top: 50px;
  margin-bottom: -25px;
}.fourth-block {
  margin-top: 50px;
}

First let’s try to decode the vertical margin between 1st and 2nd block (adjacent siblings).

As configured, 1st block’s margin-bottom is 25px and 2nd block’s margin-top is 50px. So, ideally speaking the vertical margin between the first and second block should be the sum of both and result in 75px (25px + 50px).

Is it how the calculation is done?

Okay! What does actually happen?

What happens is that the vertical margin which has smaller value collapses into the one with the largest value in between the two adjacent elements.

Let’s put the above logic into a formula as mentioned by Geoff Graham in his blog

Therefore, the vertical margin between two blocks results in 50px (margin-top value of second-block as it’s the larger margin) than earlier calculated value of 75px.

Margin collapsing: : Adjacent Siblings with Positive Margins (Sketch by me)

Similarly, vertical margin between 2nd and 3rd block results in 50px (if that’s the value you guessed, kudos you got that right!!). But, it’s difficult to guess which margin collapses on the other, as both have the same value.

Margin collapsing: Adjacent Siblings with Equal Margins (Sketch by me)

Let’s move on to the final set of siblings (3rd and 4th block). Here we can observe that a negative margin has been mixed up with a positive one. And as per the logic, the bigger margin is 50px and is the total vertical margin. But to my surprise the total vertical margin was 25px!

The first that question popped into my mind was “ How did vertical margin between the 2 blocks end up being 25px than 50px?”

Upon research I found, when a negative margin is mixed with a positive one, there is a notable impact on vertical margin between the blocks and resultant margin is equivalent to the sum of the positive and negative margin.

50px + (-25px) = 25px

Next question “Why add them?”

My understanding exclusively for this case is that, the total vertical margin is the spacing from border-bottom of the 1st block till the border-top of the 2nd block. And, as the negative margin creates a negative spacing between 2 elements, that’s why we need to add them to get total vertical margin

Consequently, reducing the margin between the blocks.

After the above understanding the final question that came to my mind is that “Do the margins get collapsed or not?”

Yes, it does get collapsed, but to a reduced vertical margin.

Margin collapsing: Adjacent Siblings with mixed (-ve and +ve) margins (Sketch by me)

Checkout the above use-cases of margin collapsing in action in the below pen

Checkout here – https://codepen.io/siddkar/pen/QYyEPP

One last scenario “What if both the adjacent siblings have negative margins?”

The logic in this scenario is equivalent to that where both the margins are positive. The only change being that the total vertical margin is collapsed to the largest negative margin value among the two blocks.

Please let me know for a working demo, in the comments section down below.

2. Collapsing of margins between parent and first/last child

As per MDN web docs, if there is no separation between

  • margin-top of the block from margin-top of its first child, or
  • margin-bottom of the block from the margin-bottom of its last child

then these margins collapse and end up outside the parent.

What kind of separation are we talking about here? Something that can separate the margin-top or margin-bottom of a block from its first or last child respectively.

Separate the margin-top by introducing border, padding, inline content, block formatting context, or clearance.

Similarly separate the margin-bottom by introducing border, padding, inline content, heightmax-height or min-height.

Collapsing of margins (margin-top) between parent and nested children (sketch by me)

The above sketch emulates the collapsing of margins (margin-top) between the parent and first child and then again its child and so on (nested).

Go ahead and try to emulate the collapsing of margins (margin-bottom) between the parent and last child block. (Hint: Its already there, just spot it)

I would also suggest going through the explanationprovided by Blake Mann.

And also checkout the above use-case in action in the below pen

Checkout here – https://codepen.io/siddkar/pen/aXmJEv

3. Collapsing of margins between empty blocks

I personally feel this use-case is somewhat similar to the previous one that we discussed above.

Let’s say we a parent block, which has two child blocks that are siblings. Now, if a sibling doesn’t have separator (i.e, border, padding, inline content, height or min-height) to separate if from another, then it’s margin-top and margin-bottom collapse.

I would suggest go ahead and create a use-case to emulate it, also let me know about it in the comment section below.


The final question that comes to my mind is “Is margin collapsing a bug in CSS?”

And my answer to that is: NO! This is just how it has been designed to work.

Saying that, do let me know what’s your answer in the comment section below.

Conclusion

Margin collapsing can really be tricky and having understanding of the it can really help get out of those situations.


With this I come to the end of my article. Please kindly let me know if you find any mistakes, that would really help me learn more on margin collapsing.

Did you find this blog useful? If yes, then please do share it

Share this please:
Setting up React Redux application for production and hosting in AWS EC2 – Part II

Setting up React Redux application for production and hosting in AWS EC2 – Part II

Hosting in AWS EC2 – Part II

This blog is second part and continuation to my blog on medium. We are going to start with the installation step.

TABLE OF CONTENTS

  1. Installations (NGINX, Nodejs)
  2. Configurations
  3. Application Setup
  4. SSL Setup
  5. Conclusion

Step 4Installations

Nginx Setup

To install nginx run below command.

sudo apt-get install nginx -y

Once the installation get completed, we can check the status.

sudo systemctl status nginx
cmd screenshot

Just press Ctrl + C to close this. If it is not running and status is inactive then we have to start it.

sudo systemctl start nginx

Then run this so that Nginx starts on startup:

sudo systemctl enable nginx
cmd screenshot

For more details on nginx, please go through the documentation.

Node.js setup

Now we have to install node.js in our server. We are going to use NVM(Node Version Manager). Let’s start the installations.

sudo apt-get update

Then install the following packages.

sudo apt-get install build-essential libssl-dev

You may be prompted with questions for which you should respond with “Y”. Once completed, we are going to download the NVM install script:

cd ~
curl -sL https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh -o install_nvm.sh
bash install_nvm.sh
source ~/.profile
nvm install 8.9.0 //as we are going to use node 8.9.0 LTS
nvm use 8.9.0
node -v

# Outputs: “v8.9.0”

npm -v

# output: “5.5.1”

Step 5: Configurations

Now it’s time to add domain. First we need to configure the Nginx. We have to remove the original default configuration file.

sudo rm /etc/nginx/sites-available/default

Then we have to enter our information to default file. We are going to use nano to edit the file. To save and quit Nano, press Ctrl X. Then it will ask if you want to save the file (do Ctrl + O). Otherwise, do Ctrl + X if you do not want to save the changes.

sudo nano /etc/nginx/sites-available/default

Copy and paste the following and replace your_domain.com with your own domain.

server {
  listen 80;
  server_name your_domain.com www.your_domain.com;
  location / {
    proxy_pass http://127.0.0.1:3080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    proxy_redirect off;
  }}

This will have all HTTP web traffic redirected to port 3080.

I’m going to use my domain gobindathakur.com. On your domain provider side, you’ll have to point the DNS to your EC2 public IP. I use GoDaddy for my domains and I’ll navigate to this domain’s DNS. Under my EC2 instance info (where we found the IPv4) there is Public IP IPv4, we need to copy it.

Go to godaddy.com. Select “My Products”.

godaddy domain

Click on DNS.

DNS Records

For type “A”, enter “@” in “Host” field. Then enter your IPv4 Public IP of your aws instance to “Points to” field. Then save it.

The last step is reloading Nginx to accept our new configurations.

sudo systemctl reload nginx

Step 6: Application Setup

1. Goto your root directory and clone your repo to the server

cd ~/
git clone REPO_PATH

It will ask you for the user name and password of your git account whenever you will do any git operation. If you don’t want to enter user name and password every time, then you have to fork it.

2. Install the npm libraries

cd ./REPO_NAME
npm install --production

It will install all the libraries that we defined under “dependencies” in our package.json file. We will use these libraries to run the server files. We are not going to install any libraries that we defined in “devDependencies”. Because we already have bundle.js built for the production.

3. Start the application in the production

I have the below command in our package.json

NODE_ENV=production node server.js
console log

Once application get started, you can enter your domain url in browser. It will serve your application.

4. Start application with pm2

But once you hit Crtl + C, your web application will stop. This doesn’t work as an option because we need it always running. We will use pm2 to keep it running. Install with:

npm install pm2 -g

You may need to use sudo because we are going install pm2 globally.

Then we need to add one pm2 config file to our application.

ecosystem.config.js

module.exports = {
    apps : [
      {
        name: "<your application name>",
        script: "./<path to>/server.js",
        watch: true,
        env: {
          "PORT": 8080,//you can choose
          "NODE_ENV": "development"
        },
        env_production: {
          "PORT": 3000,//you can choose
          "NODE_ENV": "production",
        }
      }
    ]
}

It is good to place this config file in the root directory of your project.

Then run the below command.

pm2 start ecosystem.config.js --env production
pm2 console

It will start your application in production mode. To see the information about this process, you have to run the below command.

pm2 show <app name>
pm2 show

To stop and start the server, you can run:

pm2 stop <app name>
pm2 start <app name>

Step 7: SSL Setup

Now we are going to setup SSL. We will be using Letsencrypt. For this you need a domain name and it is mandatory to give a domain name while generating key files for SSL.

You can follow the steps given in digitalocean.

cd ~
sudo add-apt-repository ppa:certbot/certbot 
# This is the PPA for packages prepared by Debian Let's Encrypt Team and   backported for Ubuntu(s).
# More info: https://launchpad.net/~certbot/+archive/ubuntu/certbot
# Press [ENTER] to continue or ctrl-c to cancel adding it
sudo apt-get update
sudo apt-get install python-certbot-nginx  # Y
sudo ufw status  # Status: inactive
sudo ufw allow 'Nginx Full'  # Make sure the domain is pointing to the server at this point.
sudo certbot --nginx -d <your_domain.com>-d <www.your_domain.com>  # Enter email  # A to agree  # Share email so Y/N  # Fails if no domain  # otherwise 1 or 2 for redirect of traffic  # I recommend 2

Then create another key file.

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

If you will see your nginx file,

sudo nano /etc/nginx/sites-available/default

Below lines are added to this file

listen 443 ssl;  # managed by Certbot
ssl_certificate /etc/letsencrypt/live/<your_domain>/fullchain.pem; # managed by Ce$
ssl_certificate_key /etc/letsencrypt/live/<your_domain>/privkey.pem;   # managed by $
include /etc/letsencrypt/options-ssl-nginx.conf;   # managed by Certbot
ssl_dhparam /etc/ssl/certs/dhparam.pem;

Then reload the Nginx.

sudo systemctl reload nginx

Then restart your application using pm2.

pm2 restart <app name>
profile

You can test your ssl here. I have tested mine. You can see the result.

ssl result

Conclusion

By following the above steps, you should be able to host your application in AWS EC2 with SSL. If you have any questions or feedback, please leave your comments below.

Share this please:
How to deal with falsy values in Javascript !

How to deal with falsy values in Javascript !

Falsy values in Javascript

Javascript has it’s own way of dealing with values. Developers from Java or any object oriented programming background get confused while dealing with falsy values. That may leads to some mistakes. Let’s try to understand, what is the meaning of falsy values in Javascript.

TABLE OF CONTENTS

  1. What are the falsy values in JavaScript
  2. Ways of comparing falsy values
  3. Dealing with falsy values in array
  4. Short-circuit evaluation
  5. Conclusion

What are the falsy values in JavaScript

A falsy value is a value that translates to false when evaluated in a Boolean context.

  • false (boolean false)
  • null
  • undefined
  • 0 (number zero)
  • ‘’ or “” (empty string)
  • NaN

If we print in console by doing Boolean() then we will get false for all falsy values.

console

Comparisons:

Many developers use to compare explicitly with these falsy values, which is not at all require.

Bad code:

if (someValue === null) {} 
if (someValue === undefined) {}
if (someValue === '') {} 
if (someValue === "") {} 
if (someValue === 0) {} 
if (someValue === NaN) {}

We don’t have to compare like this. Instead of this we can do like

if (someValue) {} 

If the “someValue” belongs to these falsy values then it will give “false” and execute the false condition.

Even I have seen some of the developers assign true and false (boolean) values on basis of the result.

Bad Code:

const result = getValue(response);//fetching required value from API const
isResult = result ? true : false;

When “result” variable itself can give true or false on basis of the value it gets from response then why we need to create separate variable and assign the boolean value???

Falsy values in Array:

If we have an array with falsy values and we are filtering it on basis of Boolean then:

const noFalsyAndZero = [
  null,
  0,
  1,
  -2,
  50,   undefined, 
  true, 
  false, 
  '',
  NaN
].filter(Boolean);
// [ 1, -2, 50, true ]
console-2

We can see that it is also removing the 0(zero). We have to take care while dealing with array in such situation.

const noFalsyButWithZero = [
  null,
  0,
  1,
  -2,
  50, 
  undefined, 
  true, 
  false, 
  '',
  NaN
].filter(value => value === 0 || Boolean(value));
// [ 0, 1, -2, 50, true ]
devtool

Here, we have added extra logic to add 0(zero) to the result. Lets take the example of array of an object.

const persons = [
  {
    name: null,
    age: 20,
    address: []
  },
  {
    name: "Alex",
    age: 29,
    founders: []
  },
  {
    name: "Mallik",
    age: 10,
    address: []
  },
  {
    name: "Renu",
    age: 50,
    address: []
  },
  {
    age: 25,
    address: []
  }
];
const personNames = persons.map(person => person.name);
// [null, "Alex", "Mallik", "Renu", undefined]
console-4

Let say, after getting names we are converting it to the uppercase.

const makeNameUpperCase = name => name.toUpperCase();
const personNamesInCaps = personNames.map(makeNameUpperCase);
// TypeError: Cannot read property 'toUpperCase' of null
console-5

“toUpperCase()” will throw error when we use it for any null or undefined values. We can handle it by filtering out the array on basis of boolean values.

const personNamesInCaps = personNames
                           .filter(Boolean)
                           .map(makeNameUpperCase);
// [ "ALEX", "MALLIK", "RENU" ]
console-6

Short-circuit evaluation:

Short-circuit evaluation says, the second argument is executed or evaluated only if the first argument is not sufficient to determine the value of the expression. when the first argument of the AND (&&) function evaluates to false, the overall value must be false; and when the first argument of the OR (||) function evaluates to true, the overall value must be true. (Copied)

Lets check this example:

const person = {
      name: "Alex",
      role: "admin"
};
const userRole = person.role || 'user';
console.log(userRole); 
// "admin"

Here, it will check person.role while evaluating the value for the “userRole”. If person.role is not a falsy value then it will assign the person.role value i.e “admin”. In case, person.role is a falsy value then it will assign “user” to the “userRole” variable.

const person = {  name: "Alex",  role: ""};//role may be null or undefined
const userRole = person.role || 'user';
console.log(userRole); 
// "user"

Conclusion:

There are some advantages and also disadvantages. One thing I see here is, it affect the readability but reduce the lines of code.

Share this please:
Create react application from scratch

Create react application from scratch

The user interface frameworks and libraries of Javascript programming
language work in a cycle. After every six months, they change positions
and a new one pops up. From past four years I am using react.js. It is an UI library backed by facebook.

It is also known as just React, has grown by leaps and bounds in recent years and became the de-facto library for component-based GUI development. It is loved by most of the developers all over the world. According to Stack Overflow survey 2019, react is most loved web framework.

Stack Overflow page

I am sure that developers will continue with react even in 2020 because of its simplicity and developer friendliness. See the npm trends:

React is much downloaded library in past 6 months. It is above all popular UI library/framework.

If you are still new to the react, then I can help you to learn it. You can start building application from scratch by following my series of blogs.

  1.  React application project setup — Installation
  2.  React application project setup — II
  3.  React application project setup — III
  4.  React application project setup — Routing in react

These blogs will help you in understanding the basic setup of react application using webpack and babel. Further in the series of these blogs I am going to cover the react application setup with react routerreduxbootstrapmaterial-uisass configuration, eslint configuration, integration with backend(using Node.js and express) etc. I hope this journey will be very very exciting.

Share this please:
React application project setup -Routing in react

React application project setup -Routing in react

 

In this blog we are going to setup the router. For this we will be using an open source library react-router. Creators of this library are Ryan Florence and Michael Jackson. These guys are awesome! I really like their talks on react.

If you are new to react and has not read my previous blogs the below is the list. Please go through it.

  1. React application project setup  – Installation
  2. React application project setup - II
  3. React application project setup - III

Before setting up the react-router in our project, lets discuss its need in our react application. For this, we need to understand the concept of SPA(Single Page Application). As per wiki, definition is:

single-page application (SPA) is a web application or web site that interacts with the user by dynamically rewriting the current page rather than loading entire new pages from a server.

In a simple sentence, You don’t need to refresh or request the whole page when you click on any link.

You can follow this nice blog to know more about the SPA.

So, meaning of routing in an application is to move between the different parts of the application when a user clicks an element like link, button, image etc. within the application.

Let’s start integrating the react-router in our project. If you are following my previous blogs then you must have repository my-react-app in your GitHub account. We will be going to create a branch feature/router-integration from our repository my-react-app and push the code to the branch.

In command line go to the project root in your system and run the below command.

git checkout -b feature/router-integration

//Switched to a new branch 'feature/router-integration'

React router library has below packages:

  1. react-router  –  This is the core library
  2. react-router-dom  –  This package is used for web applications. We are going to use it.
  3. react-router-native  -  This package is used in react native for the development of Android and iOS applications.
  4. react-router-config  -  This package provide static route configuration helpers for react-router.

There is no need to install the core react-router library by itself. Both react-router-dom and react-router-native import all the functionality of the core react-router library. For our web application we can choose react-router-dom. This library is installed in a project by running the command below.

npm install --save react-router-dom

Now, we have to decide which type of router we are going to use. For browser based applications we have 2 options.

  1. BrowserRouter: should be used when you have a server that will handle dynamic requests (knows how to respond to any possible URI). Usually it is preferable and we are going to use it.
  2. HashRouter: should be used for static websites (where the server can only respond to requests for files that it knows about).

Let’s start with writing the code and then we will go through the code.

Create a file App.js inside src folder.

touch src/App.js

Add below code in the file App.js.

import React from 'react';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from 'react-router-dom';
export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/dashboard">Dashboard</Link></li>
        </ul>
        <hr />
        <Switch>
          <Route exact path="/"><Home /></Route>
          <Route path="/about"><About /></Route>
          <Route path="/dashboard"><Dashboard /></Route>
        </Switch>
      </div>
    </Router>
  )
}
function Home() {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}
function About() {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}
function Dashboard() {
  return (
    <div>
      <h2>Dashboard</h2>
    </div>
  );
}

Then import App in the index.js file.

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
const HelloWorld = () => {
  return (
    <div>
      <h1>Hello World!</h1>
      <App />
    </div>
  );
}
ReactDOM.render(
  <HelloWorld />,
  document.getElementById('root')
);

Application will be looking like:

app

In App.js,we have imported SwitchRouter and Link from the react-router-dom.

  • Switch: A <Switch> looks through all its children <Route> elements and renders the first one whose path matches the current URL. Use a <Switch> any time you have multiple routes, but you want only one of them to render at a time.
  • Router<Route>s can be created anywhere inside of the router, but often it makes sense to render them in the same place. Routes have three props that can be used to define what should be rendered when the route’s path matches. Only one should be provided to a <Route> element.
  • component - A React component. When a route with a component prop matches, the route will return a new element whose type is the provided React component.
  • render - A function that returns a React element. It will be called when the path matches. This is similar to component, but is useful for inline rendering and passing extra props to the element.
  • children - A function that returns a React element. Unlike the prior two props, this will always be rendered, regardless of whether the route’s path matches the current location.
  • Link: Our application needs a way to navigate between pages. Router provides a <Link> component to prevent that from happening. When clicking a <Link>, the URL will be updated and the rendered content will change without reloading the page.

App.js file is looking very lengthy. Let’s split up the code.

We need to create different files for the HomeAbout and Dashboard.

touch src/Home.js src/About.js src/Dashboard.js

Then put the respective code in the files.

Home.js

import React from 'react';
function Home() {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}
export default Home;

About.js

import React from 'react';
function About() {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}
export default About;

Dashboard.js

import React from 'react';
function Dashboard() {
  return (
    <div>
      <h2>Dashboard</h2>
    </div>
  );
}
export default Dashboard;

Let’s create the Navbar links as a separate components.

touch src/Navbar.js

Navbar.js

import React from 'react';
import {
  Link
} from 'react-router-dom';
function Navbar() {
  return (
    <ul>
      <li><Link to="/">Home</Link></li>
      <li><Link to="/about">About</Link></li>
      <li><Link to="/dashboard">Dashboard</Link></li>
    </ul>
  );
}
export default Navbar;

Remove these code from App.js and import these components. Now the App.js file will be as below.

App.js

import React from 'react';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from 'react-router-dom';
import Home from './Home';
import About from './About';
import Dashboard from './Dashboard';
import Navbar from './Navbar';
export default function App() {
  return (
    <Router>
      <div>
        <Navbar />
        <hr />
        <Switch>
          <Route exact path="/"><Home /></Route>
          <Route path="/about"><About /></Route>
          <Route path="/dashboard"><Dashboard /></Route>
        </Switch>
      </div>
    </Router>
  )
}

Everything is looking fine now. Let’s commit and push the code to repository.

git add .

Files are added.

git commit -m "React router integration to the application"

Files are committed.

git push origin feature/router-integration

Files are pushed to the repository.

Now, code will be available in the branch feature/router-integration.

In my next blog we will look into the integration of CSS frameworks like bootstrap and material-ui with our existing react application. Later, we will see how to use the private routes for authenticated page request.

Share this please: