Intro to CSS Grid Layout Part 2

This is intro to css grid layout part 2, continuing from the first post which explained basics of CSS grid layout. This post will explain fractional units which control the width of each grid item.

Example CSS Grid Layout

Example HTML Code

This is the html code used for the example images in the post.

<div class="container">
  <div class="item item--1">1: Orange</div>
  <div class="item item--2">2: Green</div>
  <div class="item item--3">3: Violet</div>
  <div class="item item--4">4: Pink</div>
  <div class="item item--5">5: Blue</div>
  <div class="item item--6">6: Brown</div>
</div>


Example CSS Code

This is the common CSS code used for the example images. I will specify more properties separately when necessary. For more explanations about rows, columns and gap properties, please take a look at the first post.

.container {
  background-color: #eee;
  width: 1000px;
  margin: 30px auto;
  
  display: grid;
  grid-template-rows: repeat(2, 150px);
  grid-template-columns: repeat(3, 200px);
  grid-gap: 30px;
}

.item {
  padding: 20px;
  font-size: 30px;
  font-family: sans-sarif;
  color: white;
  
  &--1 {
    background-color: orangered;
  }
  
  &--2 {
    background-color: green;
  }
  
  &--3 {
    background-color: violet;    
  }
  
  &--4 {
    background-color: pink;
  }
  
  &--5 {
    background-color: blue;
  }
    
  &--6 {
    background-color: brown;
  }
}


Fractional Units

We have defined a two-dimensional grid with two rows (width 150px) and three columns (width 200px). However, as you can see the left over space (gray color), the grid is not filling up the container width. Fractional units become useful to fill up the space just like flex: 1 property. Note that I only modified the necessary property for readability (you will still need the common code along with the modified one)

.container {
  grid-template-columns: repeat(2, 200px) 1fr;
}

Now, we have two columns of width 200px and the last column just grows to fill all the available space in the container.

What if you want to have all the columns grow equally instead of fixed width? You just need to specify the fr in the repeat like this.

.container {
  grid-template-columns: repeat(3, 1fr);
}

Note again that 1fr is a fraction of each available space. It means 2fr will have double size of 1fr in the container. You can also think of it as this way – the entire width will be divided into each fraction based on the specified ratio. You can use mix of %, px, or fr. For example, if you put the code as the following, the first column will have the 50% of the entire width and the rest of columns will be divided based on specified fr.

.container {
  grid-template-columns: 50% 1fr 2fr;
}

One thing to note is the gap size when using % or px. % or px do not take the gap as part of their size. They take the specified width. However, fractional units count the space after subtracting the gaps from the available space. Note the difference between the two images below – gap increase from 30px to 60px. The first column – width 50% – stays same but the width of the others decrease as gap size increased.


Conclusion

In this post, we went over fractional units which control the width of each grid item. For defining CSS grid, please take a look at the first post. In the next article, I am going to explain the positioning of each grid item.

Intro to CSS Grid Layout Part 1

This post is an intro to CSS grid layout part 1. You can use CSS Grid to easily build a two-dimensional grid-based layout. This is the first part of the article which will specifically focus on the basic properties.


CSS Grid Layout Example

The above image represents basics of CSS grid layout. It has two rows and three columns. Each brown box is called a grid item. There is a gap between the items which is called a gutter.


Grid Container

It is the container of the grid. You can declare the container by calling this in the CSS file.

.container {
    display: grid;
}


Row/Column

Row and column of the container can be specified by calling the following after display: grid

.container {
  grid-template-rows: 150px 150px;
  grid-template-columns: 150px 150px 150px;    
}

The above declares two rows and three columns. Each row/column has width of 150px. However, it is a bit inconvenient to specify all the rows and columns separately. For that you can use the keyword repeat.

.container {
  grid-template-rows: repeat(2, 150px);
  grid-template-columns: repeat(3, 150px);
}

The above code is exactly same as the first one. If you want to have different width for certain row or column, you can just specify it like this.

.container {
  grid-template-rows: repeat(2, 150px);
  grid-template-columns: repeat(2, 150px) 200px;
}

Now you have 2 rows with the same width but 3 columns of which first 2 columns have 150px and the last column has 200px.

Note the numbers around the row and column (row: 1,2,3 and column:1,2,3,4) are row lines and column lines.


Gap (gutter)

The space between each grid item. You can define the row/column gap separately or the same depending on the property.

.container {
  grid-row-gap: 30px;
  grid-column-gap: 50px;
}

The above code has 30px for row gap and 50px for column gap. Row gap is the space between two rows (there are only two rows).
Column gap is the spaces between three columns (there are only three columns)

If you would like to have the same space for all the gaps, you can use this property.

.container {
  grid-gap: 30px;
}


Conclusion

We have taken a look at very basics of CSS grid layout – declaring two-dimensional grid with rows and columns. In next post, I will go over more of CSS grid. fractional units, positioning of grid items

CSS – Intro to Flexbox Part 3

This is the continuation of CSS – intro to flexbox part 3. Previous posts explained what flexbox is and conceptual things (part 1) and flexbox container properties and examples (part 2). This post will focus on explaining the properties of flex items and examples for them. Since flex items properties are only applicable to the specified item, I posted the HTML, CSS code again for easier understanding. Please pay special attention to the classes such as i2, i4 that are specific to the item.

HMTL Code

<div class="container">
  <div class="item">1</div>
  <div class="item i2">2</div>
  <div class="item">3</div>
  <div class="item i4">4</div>
  <div class="item">5</div>
</div>


CSS Code

.container {
  background-color: #ccc;
  display: flex;;
  justify-content: space-between;
  align-items: center;
}

.item {
  background-color: orangered;
  padding: 30px;
  margin: 20px;
  color: #fff;
  font-size: 40px;
}

.i2 {
  height: 200px;
}


align-self: flex-end

This property aligns the item along the cross axis and at the end of the cross axis. As you see in the example, all the items are located at the center due to align-items: center but only item 4 is located at the end of the cross axis. Note that it might look weird since item 2 has a different height. But the item 2 is still aligned in the center of the cross axis.

.i4 {
    align-self: flex-end;
}


align-self: flex-start

This one is the opposite of the flex-end. You will see the item 4 is now aligned at the start of the cross axis.

.i4 {
    align-self: flex-start;
}


align-self: stretch

This property stretches the flex item to fill the entire container. You will see the height of item 4 is now the same as item 2 since it is the max height item – 200px.

.i4 {
    align-self: stretch;
}


order: <integer>

The order property decides the order of the flex items in the container. By default, all the items have 0 for the order value. In this example, I put -1 to item 4, and now it is the first one to be placed among all the items because -1 < 0 and flexbox always display the item based on the order (lowest order first).

.i4 {
    align-self: flex-end;
    order: -1;
}


What if you put -2 order value to item 3? Since -2 < -1, the item 3 will be placed before the item 4.


flex-grow: <integer>

The flex-grow property indicates the growth of each item. As you can see in the example below, setting flex-grow: 1 made all the items grow as much as possible. The space between the items is because of the margin property.

.item {
  /* skipped all the common properties since they are defined above */
  flex-grow: 1;
}


Note that the number is to indicate the relation compared to others. Just for the above example, it doesn’t matter which number you put because there is only one flex-grow in the item class. Then, what happens if we put flex-grow: 2 to item class such as i2?

.i2 {
  height: 200px;
  flex-grow: 2;
}


Do you see that the item 2 has double width of other items? it’s because the item2 has flex-grow: 2 which is twice of the other items – flex-grow: 1.

flex-basis: <% or px>

You can set a width of a flex item by using flex-basis property. When you deal with flex items, you usually use flex-basis instead of width property. In the example below, the item 2 now occupies 40% of the container.

.i2 {
  height: 200px;
  flex-basis: 40%;
}


flex-shrink: <integer>

Unlike flex-grow, flex-shrink tells the flexbox how the items should shrink when the viewport size change. I didn’t paste the example picture here as it was bit hard to capture the screenshot to indicate the viewport size. However, I still pasted the code example which you can try in the codepen.

.i2 {
  height: 200px;
  flex-basis: 300px;
  flex-shrink: 1;
}


The item 2 has now the fixed width in the container and flex-shrink is allowed (value 1). As you decrease the viewport width you will see the item shrinks. What happens if you disable the shrink? (flex-shrink: 0). Then, you will see that the item 2 will always keep the width of 300px.


flex: <grow> <shrink> <basis>

We have taken a look at the three flex item properties – grow, shrink, basis. However, it is actually more recommended to use flex property instead of others. It is the shorthand of all and very convenient to use. And using flex property instead of those three are is considered a best practice.

.i2 {
  height: 200px;
  flex: 0 0 300px;
}

.i4 {
  order: 2;
  flex: 1;
}

Item 2 doesn’t grow and shrink but has a fixed width of 300px. So the items 1,2,3,5 are rendered first. Then, item 4 has flex-grow enabled so it takes the remaining available space after 1,2,3,5. If you decrease the viewport width on your screen, you will see item 4 will shrink but not item 2. However, if you allow shrinking in item 2 (flex: 0 1 300px) then you will see item 4 shrink first because it has the largest space followed by item 2.


Conclusion

We have completed a long journey of taking a look at basics of flexbox. There are a ton of more stuff and will try to write in different posts.

CSS – Intro to Flexbox Part 2

This is the continuation of the post – css intro to flexbox part 1. Part 1 mostly focused on explaining conceptual things. In this post, I am going to focus on showing examples for each flexbox property. Note that all the other common css code is in part 1. I wrote necessary code only for each property.

justify-content

As explained in part 1 post, justify-content tells you how the flex items should be aligned along the main axis.

justify-content: center

justify-content:center aligns the flex items in the middle of the container but doesn’t do anything for the space between the items because space is defined by the margin.

.container {
    justify-content: center;
}


justify-content: space-between

Space is evenly distributed between flex items. Flexbox automatically calculates all the spaces and positions for each item. Space between the items will be automatically adjusted if the width of the container changes.

.container {
    justify-content: space-between;
}


justify-content: space-around

space around puts the same amount of space for both left and right side of each item. You will see that the space between item 1 and 2 are double of the left space of item 1. The difference between space-between and space-around is that space-between only evenly distributes the space between the items but space-around puts all the space equally for both left/right side.

.container {
    justify-content: space-around;
}


justify-content: space-evenly

space-evenly puts equal space to all sides. As you can see all the spaces are same here. It ensures all the spaces between the elements and side of the elements are same.

.container {
    justify-content: space-evenly;
}


justify-content: flex-end

flex-end puts all the elements to the end. Note that main-axis here is horizontal from left to right that all the elements are placed on the right side.

.container {
    justify-content: flex-end;
}


justify-content: flex-start

This is the default option which places all the items to the start (main axis from left to right) which is left side.

.container {
    justify-content: flex-start;
}


align-items

align-items tells how the flex items should be aligned along the cross axis which is perpendicular to main axis. To show the example, I need to have different height for one of the item.

New HTML Code for align-items example

<div class="container">
  <div class="item">1</div>
  <div class="item i2">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
</div>

New CSS Code for align-items example

.i2 {
  height: 200px;
}


align-items: flex-start

Note again align-items will align the items along cross axis. flex-start will align all the items to the start of the axis which is top in this case. It might be little hard to see at first time. But take a closer look and you will see all the items are aligned at the top which is the start of the cross axis

.container {
    align-items: flex-start;
}


align-items: flex-end

flex-end now will place all the items at the end of the cross axis which is the bottom.

.container {
    align-items: flex-end;
}


align-items: center

As you can already guess, center will place all the items on the center of the cross axis.

.container {
    align-items: center;
}


align-items: stretch

This is the default mode which stretches all the items to the max of flex items. Since it’s default, you don’t need to specify at all.

.container {
    align-items: stretch;
}


align-items: baseline

baseline will align the items based on the text in the flex item. For the example, let me add another class – increasing the font size.

New HTML Code

note that i4 class is added to 4.

<div class="container">
  <div class="item">1</div>
  <div class="item i2">2</div>
  <div class="item">3</div>
  <div class="item i4">4</div>
  <div class="item">5</div>
</div>
New CSS Class
.i4 {
  font-size: 70px;
}

.container {
  align-items: baseline;
}


What happens if flex-direction: column?

It changes the main axis from top to bottom and cross axis from left to right. In this case, you will see all the items are in the center of horizontal line due to align-items: center (see the code below). justify-content: center makes sure all the items are centered vertically here.

.container {
    flex-direction: column;
    justify-content: center;
    align-items: center;
}


Conclusion

We have taken a look at how flex container properties work. I will continue to explain flex item properties in different post. For conceptual explanation, please take a look at part 1. And for more examples of flex items please take a look at part 3

CSS – Intro to Flexbox Part 1

This is CSS – intro to flexbox part 1. This post will explain what flexbox is and go over important properties along with examples.

What is flexblox?

Flexbox is a new module in CSS 3 which makes it easy to align elements to one another in different directions and orders. The key idea is to give the container ability to expand and shrink elements so it can use all the space efficiently. Flexbox actually replaces float layouts by using less but more readable and logical code. It changes the way that we build one-dimensional layouts.

Flexbox properties

Now let’s go over important properties of flexbox.

Flex container

It is a container of the flexbox which contains all the elements. Here is how you create the container in CSS

/* create a container */
display: flex;

/* creates a container that behaves like inline */
display: flex-inline;

Flex items

As you can see the above image, all the direct children of the flex container is called flex items.

Main/cross axis

The direction flex items are laid out is called main axis and the perpendicular axis is called cross axis.

Container properties

Container properties include flex-direction, flex-wrap, justify-content, align-items, align-content.

/* flex-direction property specifies which direction the main axis goes */
flex-direction: row | row-reverse | column | column-reverse

/* defines if flex items should wrap to next line
   if there is not enough space in the container
 */
flex-wrap: nowrap | wrap | wrap-reverse

/* defines how the flex items will be aligned along the main axis */
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly

/* very similar to justify-content. the difference is that this one defines
   how the items willbe aligned along the cross axis not the main axis
*/
align-items: stretch | flex-start | flex-end | center | baseline

/* only applies when there more than 1 row of flex items, 
   controls how the rows should be aligned along the cross axis
*/
align-content: stretch | flex-start | flex-end | center | space-between | space-around

Item properties

Item properties include align-self, order, flex-grow, flex-shrink, flex-basis.

/* very similar to align-items but applies to only one individual flex item */
align-self: auto | stretch | flex-start | flex-end | center | baseline

/* defines the order in which one specific flex items should appear inside container */
order: 0 | <integer>

/* three properties (flex-grow, flex-shrink, flex-basis), 
   help flexbox decide on the width of flex item
*/

flex-grow: 0 | integer
flex-shrink: 1 | integer
flex-basis: auto | length

/* This is short form of the above three properties which is recommended to use */
flex: 0 1 auto

Examples

Here are examples for each property.

HTML Code

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
</div>

CSS Code

.container {
  background-color: #ccc;
  padding: 0 300px;
  
  /* creating flex container */
  display: flex;
  
  /* by default flex-direction is row for the container  so you don't need to specify */
  /* flex-direction: row; */
  /* flex-direction: row-reverse; */
  /* flex-direction: column; */
  /* flex-direction: column-reverse; */
}

.item {
  background-color: orangered;
  padding: 30px;
  margin: 20px;
  color: #fff;
  font-size: 40px;
}


flex-direction: row

By default flex-direction is row that you don’t need to specify anything. Note that main axis is horizontal from left to right.


flex-direction: row-reverse

Main axis is still horizontal but it’s from right to left


flex-direction: column

Main axis is now vertical from top to bottom


flex-direction: column-reverse

Main axis is vertical but it’s from bottom to top

There are still many more examples to go through but I will explain them in a different post as this one gets longer.

SASS – mixin for responsive design

In this post, I am going to explain how to use SASS mixin for responsive design which is very powerful way.

In CSS, there is a media query you can use to present a different layout for different screen size. However, it would be very tedious to write media query break points in every CSS component you write. What if screen size changes for a phone or tablet? You probably do not want to go through everything to fix it. There needs to be a better way to handle different screen size flexibly and let’s take a look at each option

mixin directive

what is mixin? It is a directive and lets you create CSS code that is to be reused throughout the website. It’s basically like a function in different programming languages.

Let’s first define each breakpoints. These are the breakpoints I want to be able to handle.

0 - 600px: phone
600 - 900px: Tablet portrait
900 - 1200px: Tablet landscape
[1200-1800] is where our normal styles apply
1800px + : Big Desktop

Use mixin directive – option 1

We are going to create a mixin called respond-phone so that you can just include the mixin in each component/layout for phone.
Please note that @content directive allows to pass in a block of code to mixin.

// _mixins.scss
@mixin respond-phone {
    // content directive allows to pass in a block of code to mixin
    @media (max-width: 600px) { @content };
}

// _base.scss
html {
    font-size: 62.5%;
    
    @include respond-phone {
        font-size: 50%;
    }
}

Originally, the font size is 62.5% of the root font size. However, by using the respond-phone mixin, it changes to 50%. It is pretty convenient because you don’t need to hard code media query every place. Instead, you just need to create necessary mixin functions (i.e., respond-tablet-portrait, respond-tablet-landscape) and use it. Although this is certainly an improvement, is there a better way? Is there a way to use just one mixin to represent all?

Use mixin directive – option 2

Since mixin is like a function, it can take an argument. It enables us to write a mixin that specifies proper media query breakpoint based on the argument!

Please note that unlike the example above, I used em instead of px. Why? It’s because if a user changes the default font size in a browser media queries will not be affected by that. However, we want the media query to reflect the change in default font size in a browser setting. Since em is a relative unit, it is the perfect one to use.

In a media query, em is always affected by the one that comes from the browser which is 16px. 1em = 16px

// _mixins.scss
/*
$breakpoint argument choices:
- phone
- tab-port
- tab-land
- big-desktop
*/
@mixin respond($breakpoint) {
  @if $breakpoint == phone {
    @media (max-width: 37.5em) { @content }; // 600px
  }
  @if $breakpoint == tab-port {
    @media (max-width: 56.25em) { @content }; // 900px
  }
  @if $breakpoint == tab-land {
    @media (max-width: 75em) { @content }; // 1200px
  }
  @if $breakpoint == big-desktop {
    @media (min-width: 112.5em) { @content }; // 1800px
  }
}

Now, we have a single mixin to use for all different screen sizes. Let’s take a look at how to use them

// _base.scss
html {
  font-size: 62.5%; // 1rem = 10px; 10 / 16 = 62.5%

  @include respond(tab-land) { // width < 900?
    font-size: 56.25%; // 1rem = 9px, 9 / 16 = 56.25%
  }

  @include respond(tab-port) { // width < 600 ?
    font-size: 50%; // 1rem = 8px, 8 / 16 = 50%
  }

  @include respond(phone) {
    font-size: 43.75%; // 1rem = 7px, 7 / 16 = 43.75%
  }

  @include respond(big-desktop) {
    font-size: 75%; // 1rem = 12px, 12/16 = 75%;
  }
}

Here, we are trying to use font-size as a breakpoint for different screen layout. You can see that I want to use different font-size for different screen and I converted to percentage to be flexible.

Please note the order of the mixin. All the max-width mixins are in a decreasing order. It’s ordered to prevent unintentional side effect. For example, if the screen size is 500px, it will fall under all the tablets and phone size. In that case, the last property written is selected and that’s why I ordered them in a decreasing size way.

Conclusion

It’s not simple to write a responsive designs due to its complexity. However, using the mixin could help a lot.

Basics of Protocol Buffers 3 – Part 2

This post explains basics of protocol buffers 3 part 2. It will specifically focus on how to do the followings.
1. multiple messages in a same file
2. nested messages
3. imports
4. packages

If you would like to read part 1, please read this post.

Multiple messages in a same file

You can have multiple messages in a same .proto file. Here is an example.
All you need to do is to define those messages and reference properly.

syntax = "proto3";

message Person {
    string first_name = 1;
    string last_name = 2;
    Address address = 3;
}

message Address {
    string street = 1;
    string city = 2;
    string zip_code = 3;
}

Nested Messages

You can nest messages depending on your design. You might want to nest messages to avoid naming conflicts (you can also use packages for this) or enforce some level of locality for that type. And you can nest types as deep as you want. Let’s take a look at an example code.

syntax = "proto3";

message Person {
    string first_name = 1;
    string last_name = 2;
    
    message Address {
        string street = 1;
        string city = 2;
        string zip_code = 3;
    }
    
    Address address = 3;
}

Import Messages

It is very reasonable to have messages in a different file and reuse it. This is especially the case that you need to use proto file created by another team. We have two files for the example. Please note that when you import you need to specify the folder too even if the files are in the same directory.

// this is person.proto located under "info" directory.
syntax = "proto3";

import "info/address.proto";

message Person {
    string first_name = 1;
    string last_name = 2;
    Address address = 3;
}
// this is address.proto located under "info" directory
syntax = "proto3";

message Address {
    string street = 1;
    string city = 2;
    string zip_code = 3;
}

Packages

It is important to define the packages where your protocol buffer messages live for the following reasons.
1. The file will be placed at the package you specified when you compile the code
2. It will prevent name conflicts between messages

Packages will assure all the different languages compile correctly from .proto files. When you import package proto, make sure you specify package in front of the imported messages. Let’s take a look at the example below.

// city.proto located under "info" directory
syntax = "proto3";

package city;

message City {
    string name = 1;
    string country_code = 2;
}
// address.proto located under "info" directory
syntax = "proto3";

package address;

import "info/city.proto";

message Address {
    string street = 1;
    city.City city = 2;
    string zip_code = 3;
}
// person.proto located under "info" directory
syntax = "proto3";

package person;

import "info/address.proto";

message Person {
    string first_name = 1;
    string last_name = 2;
    address.Address address = 3;
}

Conclusion

We have taken a look at simple but pretty useful features of protocol buffers. Next post will explain how to compile and use in python/go language.

Basics of Protocol Buffers 3 – Part 1

In this post, I am going to explain the basics of protocol buffer 3. Protocol buffer is developed by Google for better handling of data. There are many data formats such as csv, json. However, there are some weaknesses in each format. CSV is easy to handle but has some disadvantages – data type has to be inferred, hard to parse when the data includes commas. JSON is used in many places and can be communicated over the web and very flexible in format but it doesn’t have schema enforcing and JSON objects could be pretty big size because of repeated keys.

Advantages of Protocol Buffers

  • Data is fully typed
  • Data is compressed automatically results in less CPU usage
  • Schema is required to generate code and read the data
  • Documentations could be part of the schema
  • Supports multi-language communication – data can be shared in different languages (Java, Python, Go, Javascript and others)
  • Schema can evolve over time in a safe way
  • Code is auto generated for the convenience

Disadvantages

  • Not all languages are supported
  • Since data is serialized, you can’t open the data file with text editor

Example

This is an example of protocol buffer schema and we will take a look at each piece.

syntax = "proto3";

message Person {
  int32 age = 1;
  string first_name = 2;
  string last_name = 3;
  bytes profile_img = 4;
  bool verified = 5;
  float height = 6;
  repeated string contacts = 7;
}

Schema

You always have to put syntax = “proto3” to indicate this is protocol buffer 3. If you want to use 2 then replace 3 with 2.

Each schema starts with the keyword message then schema name with open/close braces.

In the schema, you can have multiple fields. Each field consists of field type, field name and tag. The first word is field types which are int32, string, bytes, bool, float as you see in the example. Next one is field name which you can arbitrarily decides. Mainly, it’s for your readability. The last one is tag which is more important than field names and is used for protocol buffers. Let’s take a look at each part.

Field Types

There are multiple built in types supported in protobuf3. I will not explain much about each type as they look very similar to other languages like C/C++, Java.

Integers
type: int32, int64, uint32, uint64, sint32, sint64
Floating Point Numbers
type: float (32 bits), double (64 bits)
Boolean
type: bool
String

String must always contain UTF-8 encoded or 7 bit ASCII text
type: string

Bytes

Raw byte array. Interpretation of bytes depends on the code.
type: bytes

Repeated Fields

Protocol buffers supports list or array by using “repeated” keyword. The specified field can take any number (0 or more) of elements you want. After the repeated keyword, you need to specify which type you want to use. Please refer to the example above.

Enums

If you need to use the values that are known in advance (i.e., day of week), you can use enum type.
Please note that the first value of an enum is the default value and enum must start by the tag 0 which is the default value. Here is an example of enums. You can use the enum type just like others after you define it.

enum DayOfWeek {
  UNDEFINED = 0;
  MONDAY = 1;
  TUESDAY = 2;
  WEDNESDAY = 3;
  THURSDAY = 4;
  FRIDAY = 5;
  SATURDAY = 6;
  SUNDAY = 7;
}

Tag

In protocol buffers, field names are not important because it’s not actually used for the actual communication. Instead, the tag is used and thus is a very important element. In the example above, there are always values after field names. Those values are tags. The smallest value you can use is 1 and the largest value you can use is 2^29 – 1 or 536870991.

Tags numbered from 1 to 15 use 1 byte in space. It is recommended to use them for frequently populated fields.
Tags numbered from 16 to 2047 use 2 bytes.

Please note that the numbers between 19000 – 19999 are reserved by google for special use.

Conclusion

We have taken a look at very basics of protocol buffers. Please continue to read this post for more about protocol buffers.

CSS – Build Navigation

This post will explain how to build a simple navigation logic for a webpage.
Please note that I have learned this from the udemy course by Jonas Schmedtmann.
Let’s take a look at the example first.

Example

Please note a couple of things. The navigation button always stays on the upper right corner (even if you scroll). And there is an animation from the button as soon as you click it. In this post, button animation is not explained. Please refer to the post here for button animation.

HTML Code

<div class="navigation">
    <input type="checkbox" class="navigation__checkbox" id="navi-toggle">
    <label for="navi-toggle" class="navigation__button">
        <span class="navigation__icon"> </span>
    </label>
    <div class="navigation__background"> </div>
    <nav class="navigation__nav">
        <ul class="navigation__list">
            <li class="navigation__item"><a href="#" class="navigation__link"><span>01</span>Option 1</a></li>
            <li class="navigation__item"><a href="#" class="navigation__link"><span>02</span>Option 2</a></li>
            <li class="navigation__item"><a href="#" class="navigation__link"><span>03</span>Option 3</a></li>
            <li class="navigation__item"><a href="#" class="navigation__link"><span>04</span>Option 4</a></li>
            <li class="navigation__item"><a href="#" class="navigation__link"><span>05</span>Option 5</a></li>
        </ul>
    </nav>
</div>

CSS Code – SCSS

Please don’t forget to replace SCSS variables into actual numbers.

There are three main functionalities here (except button animation)
1. The existing screen will be covered by navigation background (animation starts from the button)
2. Another animation when you hover over each option
3. Background animation bounces when render

Let’s take a look at each class now.

.navigation {
  &__checkbox {
    display: none;
  }

  &__button {
    background-color: $color-white;
    height: 7rem;
    width: 7rem;
    border-radius: 50%;
    position: fixed;
    top: 6rem;
    right: 6rem;
    z-index: 1000;
    box-shadow: 0 1rem 3rem rgba($color-black, .1);
    text-align: center;
    cursor: pointer;
  }

  &__background {
    height: 6rem;
    width: 6rem;
    border-radius: 50%;
    position: fixed; // similar to absolute. but it doesn't change the position as we scroll the page
    top: 6.5rem;
    right: 6.5rem;
    // difference bewteen linear gradient and radial gradient
    // linear gradient goes from one side to the other
    // radial gradient goes from the center to others
    background-image: radial-gradient($color-primary-light, $color-primary-dark);
    z-index: 500;

    // easings.net
    transition: transform .8s cubic-bezier(.86, 0, .07, 1);
  }
 
  &__nav {
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 600;

    opacity: 0;
    width: 0;
    transition: all .8s cubic-bezier(.68, -.55, .265, 1.55);
  }

  &__list {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    list-style: none;
    text-align: center;
    width: 100%;
  }

  &__item {
    margin: 1rem;
  }

  &__link {
    &:link,
    &visited {
      display: inline-block;
      font-size: 3rem;
      font-weight: 300;
      padding: 1rem 2rem;
      color: $color-white;
      text-decoration: none;
      text-transform: uppercase;
      background-image: linear-gradient(
        120deg,
        transparent 0%,
        transparent 50%,
        $color-white 50%);

      // size of the background, shift to the left to render animation
      background-size: 220%;
      transition: all .4s;

      span {
        margin-right: 1.5rem;
        display: inline-block;
      }
    }
    
    &:hover,
    &:active {
      background-position: 100%;
      color: $color-primary;
      transform: translateX(1rem);
    }
  }

  // FUNCTIONALITY
  &__checkbox:checked ~ &__background {
    transform: scale(80);
  }

  &__checkbox:checked ~ &__nav {
    opacity: 1;
    width: 100%;
  }
}

Navigation Background Animation

The most important things to note are
1. background-image: radial-gradient at line 30.
Unlike linear-gradient making the color from one side to the other side, radial-gradient makes gradient color from the center to all directions. (it’s like a water ripple)

2. transition: transform .8s cubic-bezier(.86, 0, .07, 1) at line 34
This is a bezier curve to provide a custom timing function. There are multiple websites that help you find various timing functions. The number is also calculated from one of the websites.

3. position: fixed at line 24
This is to fix the navigation button in the upper right corner. How is this different from absolute? Unline absolute, fixed doesn’t change the position even if you scroll the page and takes out the element from the float.

4. transform: scale(80) at line 99
This is the line to scale up to cover the entire screen when the checkbox is clicked. Please note that sibling selector is used because you want to select navigation__background and navigation__nav only when the checkbox is clicked. Please also note that the nav opacity is initially 0 and width is 0 to make it completely gone but once the checkbox is clicked it will have opacity 1 and proper width.

Navigation Option Animation

The most important thing to note is
1. &__link class
background-image: linear-gradient at line 73 is solid color gradients usage that you can specify different color in each stage (%). As you can see in the code, it rotates 120 degrees and transparent 0% and 50% and white color starting at 50%. But this alone doesn’t make the animation. It will just show you a different mix of the color. You need to have background-size at line 80 so that you will be able to shift the color by making the size bigger. Then when you hover (at line 89), you just need to re-position the element. Don’t forget to put transition: all .4s for animation.

CSS – Build Animating Nav Button

Today, we are going to take a look at how to build animating nav button using css properties.
Please note that I have learned this from the udemy course by Jonas Schmedtmann.

Example

As soon as you click the button, you will see there is a cool animation making the button X. This is built by pure CSS properties which we will take a look at it soon.

HTML Code

<div class="navigation">
    <input type="checkbox" class="navigation__checkbox" id="navi-toggle">
    <label for="navi-toggle" class="navigation__button">
        <span class="navigation__icon"> </span>
    </label>
</div>

checkbox input type is used here to make toggle easier. Please note that the checkbox input is hidden and the navigation__icon class is used to style like a button.

CSS Code – SCSS

Please don’t forget to change the SCSS variables to actual numbers when you use it.

.navigation {
  &__button {
    background-color: $color-white;
    height: 7rem;
    width: 7rem;
    border-radius: 50%;
    position: fixed;
    top: 6rem;
    right: 6rem;
    z-index: 1000;
    box-shadow: 0 1rem 3rem rgba($color-black, .1);
    text-align: center;
    cursor: pointer;
  }    
    
  &__icon {
    position: relative;
    margin-top: 3.5rem;;

    &,
    &::before,
    &::after {
      width: 3rem;
      height: 2px;
      background-color: $color-gray-dark-3;
      display: inline-block;
    }

    &::before,
    &::after {
      content: "";
      position: absolute;
      left: 0;
      transition: all .2s;
    }

    &::before { top: -.8rem; }
    &::after { top: .8rem; }
  }

  &__button:hover &__icon:before {
    top: -1rem;
  }
  &__button:hover &__icon:after {
    top: 1rem;
  }

  &__checkbox:checked + &__button &__icon {
    // make the middle one invisible
    background-color: transparent;
  }

  &__checkbox:checked + &__button &__icon::before {
    top: 0;
    transform: rotate(135deg);
  }

  &__checkbox:checked + &__button &__icon::after {
    top: 0;
    transform: rotate(-135deg);
  }
}

I skipped navigation class here as it’s explained in different post. Please refer to the post here for navigation logic.

As you can see in the html code, there is only 1 icon element in the button. How can there be three lines? Take a look at the line 20-27. 3 selectors are chosen – before, the element, after – and each selector make a line in the button. Please note that content, display properties are mandatory for pseudo-element usage.

Now, let’s see how you can make the animation when hover. There is a couple of steps for this.

Make a space between the lines when hover

Take a look at lines 41 – 46 in the CSS code. You need to choose before, after when hover happens and adjust the position accordingly. Don’t forget to have transition property to make it animation in line 34.

Animating the lines to form X

Take a look at lines 48 – 61 in the CSS code. What you need to do is the followings.
1. hide the middle one (background-color: transparent)
2. re-position the top and bottom (before, after pseudo elements) and rotate in opposite directions. Here 135 degree is chosen (180 – 45)

The logic is pretty simple. We just need to carefully select the element – only when the checkbox is checked. In order to do that, sibling selector (+) is used then choose navigation__icon::before and after