CSS 2: Flex, flex page layout and background-image

Flex property and image background

Flex and page layout

The Flexbox layout justifies and aligns items within its container, while flex child elements expand their width to fill it dynamically.

//we still need to set height, and justify won't change how the space managed
<div class="stripe">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>

.goleador{
    display: flex;
    height: 50px;
    flex-direction: column/ row;
}

.goleador div:nth-child(odd){
    flex: 1;
    background-color: purple;
}

.goleador div:nth-child(even){
    flex: 1;
    background-color: yellow;
}
column and row

The values for both justify-content and align-items:

flex-start | flex-end | center         //left, right, center
space-between |                        //uses all the space to space the elements
space-around |                         //uses spaces for the border
stretch |                              //will stretch elements to use all the space
baseline                               //align for baseline

We can use inline-flex to use flex only on a text element width:

Inline-flex, triple border and limited border guide

We use font-awesome icons <i> that work as text:

<ul class="trino">
  <li>
    <i class="fas fa-laptop-code"></i>
    ...
  </li>
  <li>
    <i class="fas fa-laptop-code"></i>
    ...
  </li>
  <li>
    <i class="fas fa-laptop-code"></i>
    ...
  </li>
</ul>

We use inline-flex to have the border circle only the text width and not the entire container, and also to use all flex properties:

//we need justify and align for the :before:after layers
.trino li i{
    color: #C80815;
    border: 1px brown solid;
    padding: 0.6em;
    border-radius: 100%;

    display: inline-flex;
    justify-content: center;
    align-items: center;
}

.trino li i::before{
    padding: 1em;
    border-radius: 100%;
    border: 1px brown solid;
}

.trino li i::after{
    content: "";
    position: absolute;

    padding: 1em;
    border-radius: 100%;
    border: 1px brown solid;
}

To get a smaller border we reduced the container:

.trino li:nth-child(2){
    width: 80%;
    margin: 0 auto;
    border-bottom: 2px solid brown;
}
row and column flex layout

The flex-wrap property sets if flex element will fit in one line (nowrap) or can warp onto multiple lines, we can use flex with % to set more precise for the elements.

We don't need to create row containers, the CSS can split by itself.

//for each 3 elements we change a line
<div class="griglia">
  <div>
    <i class="fas fa-volleyball-ball"></i>
    ...
  </div>
  <div>
    <i class="fas fa-volleyball-ball"></i>
    ...
  </div>
  ...
</div>

We can also use wrap-reverse if we needed to change the order.

//3 for each line
.griglia{
    display: flex;
    flex-wrap: wrap;
}

.griglia div{
    flex: 33%;
    text-align: center;
}

//then we border the third and forth for the effect
.griglia div:nth-child(3n+1){
    border-right: 1px black solid;
}

.griglia div:nth-child(3n){
    border-left: 1px black solid;
}
33% flex layout

When using a flex-container with multiple items we can space them using align-content (different from align-items) or gap:

Align-content and gap guide

We have a flex-container that flex wraps,

<div class="quatto">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

We use align-content to space the vertical space of multiple flex items:

//each image wrapping at 40%
.quatto div{
    flex: 40%;
    height: 25px;
}

//we give space to the top/bottom using align-content, while padding is for outside
.oltre .quatto{
    display: flex;
    flex-wrap: wrap;

    align-content: space-around;
    padding: 5px;
}

If we want to define the space between the flex elements we use gap:

//it won't work with align-content
.oltre .quatto{
    display: flex;
    flex-wrap: wrap;
    
    gap: 10px;
    padding: 5px;
}
align-content and gap

CSS reset and flex navbar

For a flex navbar, we need:

//we create a row with 2 columns
<div class="naviga">
  <div class="col">
    <div>lorem </div>
    <div>lorem </div>
  </div>

  <div class="col">
    <div>lorem </div>
    <div>lorem </div>
    <div>lorem </div>
  </div>
</div>


//we use justify-content to space the nav-items
.naviga{
  display: flex;
  justify-content: space-between;
  background-color: orangered;
}

.naviga .col{
  display: flex;
}

.col div{
  padding: 0.6em 1em;
  color: blueviolet;
}

.col div:hover{
  color: orangered;
  background-color: blueviolet;
  cursor: pointer;
}

We use CSS reset to cut default CSS styling from the browser:

//Without this we would have extra borders, and the navbar wouldn't cover the page
HTML,body, div, form, fieldset, blockquote, header,h1,h2,h3
{
  font-size: 100%;
  font-weight: normal;

  margin: 0;
  padding: 0;

  vertical-align: baseline;

  border: 0;
  outline: 0;
  background: transparent;
}

img
{
  border: 0;
}

HTML <img> and Background image

We use the <img> tag for images, it creates a space to link the image to:

Image tag and flex order example
//we can use order to change the order of flex-items
<div class="vedi">
    <img src="https://live.staticflickr.com/65535/52575562589_e7f248ff8f_c.jpg" alt="">
    <img src="https://live.staticflickr.com/65535/49197710168_014f46e3a2_w.jpg" alt="">
    <img src="https://live.staticflickr.com/65535/52148924164_6c7a2d74af_m.jpg" alt="">
</div>

.vedi{
    display: flex;
    height: 115px;
}

.vedi img:nth-child(1){
    flex: 1;
    order: 2;
}
.vedi img:nth-child(1){
    flex: 2;
    order: 1;
}
.vedi img:nth-child(1){
    flex: 3;
    order: 3;
}
<img> with flex order

The aspect-ratio property regulates the proportions between the height/width of the element independently of the screen size.

//By higher it will be smaller than the other, if lower it will multiply
height: 300px
aspect-ratio: 3/2 // 300 = aspect-rario * x

We can use both the <img> and background-Image to set a low-opacity image background to some centered text.

The text zIndex and position-absolute avoids the backgroundImage opacity.

//The first justify is for the centered row column, the second for the image
//text-center/aling-items centers the text

<div className="position-relative d-flex justify-content-center align-items-center">
  <div className="row col-8 mx-0 text-center align-items-center d-flex justify-content-center">
    <div className="img-fluid fondo"></div>

    <h2 className="position-absolute" style={{ zIndex: 2 }}>
      Index text
    </h2>
  </div>
</div>

The background sets the container's height

.fondo{
  height: 30vh;
  background-image: url("https:...jpg");
  background-position: center;
  background-size: cover;
  opacity: 0.6;
}
centered index text on background-image

Background-position and background-size work similarly to how they worked with gradients, on CSS1.

//position accepts X/Y values
background-position: top/left/bottom/right/%/px

//its default value is the native size of the image, auto/contain
background-size: X/Y/%
background-size: cover    //it stretches the image to occupy all the space, can crop

The background-position set with % won't work for 100% background-size, due to how the background interacts with its container. For more details check THIS stackOverflow.

//We need to reduce the size and implement this formula for the position
//100% * ((movement=50)/(100 - (size=99.5)) = 100% * 100 = 10000%

.backo{
  width: 250px; height: 150px;
  background-image: url("https://picsum.photos/id/1069/200/200");
  background-size: 99.5%;
  background-position: 10000%;
}

By default, if a background-image is smaller than the element it's in will repeat itself to fill it.

We use background-clip to extend it underneath its border-box, padding-box, or content-box.

backround-repeat and background-clip guide

We can set the background-repeat on the X/Y of the element, or not use it.

//it has background-repeat: repeat/ background-clip: border-box by default
.cliprepeat div{
    background-image: 
        url("https://live.staticflickr.com/65535/49197710168_014f46e3a2_w.jpg");

    width: 90%;
    border: 10px dotted black;
}

background-repeat: no-repeat            //will use the image only once
                   repeat-x/repeat-y    //will repeat only on width/height
                   space                //repeats only if available space, no clip
                   round                //repeats and stretches to not cut

while background-clip:

//we can use padding-box/ content-box to not include the border
.clipped div{
    background-image: url("https://live.staticflickr.com/65535/49197710168_014f46e3a2_w.jpg");
    background-repeat: no-repeat;
    background-clip: padding-box;

    width: 90%;
    border: 10px dotted black;
}
Background.clip and background-repeat different uses

We can include most properties with a background shorthand and put multiple background-images in one element.

Multiple background and shorthand property

Any space that is not filled by the image can be filled by background-color:

.molti div{
    background: 
        lightblue 
        url("https://live.staticflickr.com/65535/49197710168_014f46e3a2_w.jpg")
        no-repeat
        right top;

    width: 80%;
}

//background can include
background-color
background-image
background-repeat
background-position

We can add multiple backgrounds to an image:

//remember to use , for any new backround
.altri div{
    background: 
        url("https://live.staticflickr.com/65535/52148924164_6c7a2d74af_m.jpg")
        no-repeat
        left bottom,

        url("https://live.staticflickr.com/65535/49197710168_014f46e3a2_w.jpg")
        repeat;

    width: 80%;
}
background shorthand using multiple images and background-color

We use a fixed background-image to have a fixed scroll image:

//The fixed navbar will remain visible, while the background will disappear on scroll
<div class="barra">
</div>
<div class="gravity">
</div>

.barra{
  position: fixed;
  top: 0;
  
  height: 3em;
  width: 100%;
  background-color: red;
}

.gravity{
  background: url("https://bit.ly/3NwLCLI") 20% 3em fixed;
  
  background-position: bottom;
  background-size: cover;
  height: 22em;
}
fixed background-image with fixed top navbar

CSS box-shadow

The box-shadow property adds internal/external shadow effects to an element frame.

//It is also affected by the border-radius
//optional inset/ X offset/ Y offset/ blur/ spread(scale)/ color

box-shadow: (inset) 20px -15px 10px 10px teal;
Box-shadow basic guide

Box-shadow requires at least 2 values, X/Y offset, it will be solid border/outline:

.flessi3 div:first-child{    
    background: url("https://live.staticflickr.com/65535/52148924164_6c7a2d74af_m.jpg");
    width: 40%;
    border-radius: 10%;

    box-shadow: 10px 15px brown;
}

The third value is blur, it pushes the shadow forward but also blurs it.

//the shadow covers more, but is less intense
box-shadow: 10px -15px 10px brown;

Then there is spread, which can expand/reduce the box-shadow from the element size:

//with a lower spread we keep the blur with less space
box-shadow: -10px -15px 10px -10px brown;

Then we can use inset to put the shadow inside the element

//this has the same X/Y offset of the second, inset reverses offsets
box-shadow: inset 10px -15px 10px 10px brown;
box-shadow with different offsets/blur and spread

We can also have single-side box-shadow effects:

Single side box-shadow guide

Box-shadow directions are bottom/right, on inset its reversed, also we need a negative spread to avoid any other side shadow from being visible:

//Y inset 20px would be bottom shadow, on inset it's top
box-shadow: inset 0px 20px 20px -10px green;

//negative X offset is left, but on inset is on the right
box-shadow: inset -20px 0px 20px -10px green;

//bottom inset negative X-offset
box-shadow: inset 0px -20px 20px -10px green;

//right inset box shadow
box-shadow: inset 20px 0px 20px -10px green;
single side box-shadow inset effect

CSS scrollbar styling

We use pseudo-elements to style the scrollbar/scrollbar-track/scrollbar-thumb:

Scrollbar style guide

We need to set the scroll overflow in the container first:

<div class="skrull">
  <div>
    <div>
      Lorem, ipsum dolor sit amet consectetur adipisicing elit. 
      ...
    </div>
  </div>
</div>

.skrull{
  overflow-x: scroll;
  overflow-y: scroll;

  width: 30%;
  height: 8em;
}

The bottom/right scrollbar area is set by height/width:

//width sets the left one, while height the bottom one
.skrull::-webkit-scrollbar{
  width: 12px;
  height: 4px;
}

while scrollbar-track is the actual areas

.skrull::-webkit-scrollbar-track {
  background: orange;
}

We use scrollbar-thumb for the css thumb:

//we can't reduce it, so we use border to color with the backround
.skrull::-webkit-scrollbar-thumb{
  background-color: rebeccapurple;
  border-radius: 10px;
  border: 3px solid orange;
}
CSS scrollbar

The ::-webkit-scrollbar pseudo selector doesn't work in the Firefox browser, we use scrollbar-width and scrollbar-color props.

/*Both on the container*/
.wind{
  scrollbar-width: none; //auto, thin 
  scrollbar-color: orange lightyellow; //thumb scrollbar colors
}

We create a carousel made of form cards through radio buttons:

CSS form carousel

First, we create the navbar using radio buttons:

Radio buttons navbar guide

We create radio buttons with their own label:

//each label is linked to the radio button
<div class="contenuto">

  <input id='tabC-4' type='radio' name='tabgroupC' checked />
  <label class="salta" for="tabC-4">1</label>

  <input id='tabC-5' type='radio' name='tabgroupC'>
  <label class="salta" for="tabC-5">2</label>

  <input id='tabC-6' type='radio' name='tabgroupC'>
  <label class="salta" for="tabC-6">3</label>

  <input id='tabC-7' type='radio' name='tabgroupC'>
  <label class="salta" for="tabC-7">4</label>

</div>

We then hide the radio buttons with CSS:

//We keep the buttons position 
[type=radio] {
  opacity: 0;
  width: 0;
  position: absolute;
  display: inline-block; 
}

//and then we style the labels
.salta{
  background: transparent;
  color: brown;
  padding: 0em 0.4em;
}
radio buttons navbar

Then use CSS to create and move the carousel.

Form card

Last updated

Was this helpful?