Skin 10.x: Migrating to Grid

Last modified by Vincent Massol on 2024/02/26 17:57

 XWiki
 Implementation
 Idea

Description

The purpose of this investigation is to evaluate the difficulties, advantages and implementability of switching from Bootstrap to a Grid defined skin.

Comparison

Layout Definition

This is an example of how we have / could have the current layout variations defined in Flamingo skin using multiple techniques:

Limitations

  1. CSS Variables need to be inside a :root {} or other selector declaration, compared to LESS variables that are top level
  2. Bug Cannot use CSS variables inside our .LESS files. Gets a Less4jException: Could not compile less error. 
  3. Limitation

    Cannot use fr units in calc(). In the demo I'm using px, but we would need to calculated in % for panels sizes, using the formula:
    the width of each column = (width of viewport / number of columns) * 1%

Layout Variations

currentLayout.png

LESS + Bootstrap 3 mixins

@main-padding: @grid-gutter-width * 2;

#body {
 // Both left and right panels are displayed
 &.content {
   // Left panels are small
   &.panel-left-width-Small {
     .main {
       .make-md-column-push(1);
      }
     // Left panels are small and right panels are small
     &.panel-right-width-Small {
       .main {
         .make-md-column(10, @main-padding);
        }
        #leftPanels {
         .make-md-column-pull(10);
        }
      }
     // Left panels are small and right panels are medium
     &.panel-right-width-Medium {
       .main {
         .make-md-column(9, @main-padding);
        }
        #leftPanels {
         .make-md-column-pull(9);
        }
     }
     // Left panels are small and right panels are large
     &.panel-right-width-Large {
       .main {
         .make-md-column(8, @main-padding);
        }
        #leftPanels {
         .make-md-column-pull(8);
        }
     }
   }
   // Left panels are medium
   &.panel-left-width-Medium {
     .main {
       .make-md-column-push(2);
      }
     // Left panels are medium and right panels are small
     &.panel-right-width-Small {
       .main {
         .make-md-column(9, @main-padding);
        }
        #leftPanels {
         .make-md-column-pull(9);
        }
     }
     // Left panels are medium and right panels are medium
     &.panel-right-width-Medium {
       .main {
         .make-md-column(8, @main-padding);
        }
        #leftPanels {
         .make-md-column-pull(8);
        }
     }
     // Left panels are medium and right panels are large
     &.panel-right-width-Large {
       .main {
         .make-md-column(7, @main-padding);
        }
        #leftPanels {
         .make-md-column-pull(7);
        }
     }
   }
   // // Left panels are large
   &.panel-left-width-Large {
     .main {
       .make-md-column-push(3);
      }
     // Left panels are large and right panels are small
     &.panel-right-width-Small {
       .main {
         .make-md-column(8, @main-padding);
        }
        #leftPanels {
         .make-md-column-pull(8);
        }
     }
     // Left panels are large and right panels are medium
     &.panel-right-width-Medium {
       .main {
         .make-md-column(7, @main-padding);
        }
        #leftPanels {
         .make-md-column-pull(7);
        }
     }
     // Left panels are large and right panels are large
     &.panel-right-width-Large {
       .main {
         .make-md-column(6, @main-padding);
        }
        #leftPanels {
         .make-md-column-pull(6);
        }
     }
   }
 }

 // Only right panels
 &.hideleft {
   &.panel-right-width-Small {
     .main {
       .make-md-column(11, @main-padding);
      }
   }
   &.panel-right-width-Medium {
     .main {
       .make-md-column(10, @main-padding);
      }
   }
   &.panel-right-width-Large {
     .main {
       .make-md-column(9, @main-padding);
      }
   }
 }

 // Only left panels
 &.hideright {
   &.panel-left-width-Small {
     .main {
       .make-md-column(11, @main-padding);
       .make-md-column-push(1);
      }
      #leftPanels {
       .make-md-column-pull(11);
      }
   }
   &.panel-left-width-Medium {
     .main {
       .make-md-column(10, @main-padding);
       .make-md-column-push(2);
      }
      #leftPanels {
       .make-md-column-pull(10);
      }
   }
   &.panel-left-width-Large {
     .main {
       .make-md-column(9, @main-padding);
       .make-md-column-push(3);
      }
      #leftPanels {
       .make-md-column-pull(9);
      }
   }
 }

 // No Panels
 &.hidelefthideright {
   .main {
     .make-md-column(12, @main-padding);
    }
 }

 &.panel-left-width-Small {
   #leftPanels {
     .make-md-column(1);
    }
 }
 &.panel-left-width-Medium {
   #leftPanels {
     .make-md-column(2);
    }
 }
 &.panel-left-width-Large {
   #leftPanels {
     .make-md-column(3);
    }
 }
 &.panel-right-width-Small {
   #rightPanels, #editPanels {
     .make-md-column(1);
    }
 }
 &.panel-right-width-Medium {
   #rightPanels, #editPanels {
     .make-md-column(2);
    }
 }
 &.panel-right-width-Large {
   #rightPanels, #editPanels {
     .make-md-column(3);
    }
 }
}

#leftPanels, #rightPanels {
 .make-xs-column(12);
}

LESS + Grid

@supports (display: grid) {
  
#contentcolumn {
    
grid-area: content;
  
}
  
#leftPanels {
    
grid-area: leftpanels;
  
}
  
#rightPanels {
    
grid-area: rightpanels;
  
}
  
#contentcontainer {
    
display: grid;
    
grid: "leftpanels content rightpanels" / auto auto auto;
  
}
  
body {
    
&.panel-left-width-Small.panel-right-width-Small {
      
#contentcontainer {
        
grid-template-columns: 1fr 10fr 1fr;
      
}
    
}
    
&.panel-left-width-Small.panel-right-width-Medium {
      
#contentcontainer {
        
grid-template-columns: 1fr 9fr 2fr;
      
}
    
}
    
&.panel-left-width-Small.panel-right-width-Large {
      
#contentcontainer {
        
grid-template-columns: 1fr 8fr 3fr;
      
}
    
}
    
&.panel-left-width-Medium.panel-right-width-Small {
      
#contentcontainer {
        
grid-template-columns: 2fr 9fr 1fr;
      
}
    
}
    
&.panel-left-width-Medium.panel-right-width-Medium {
      
#contentcontainer {
        
grid-template-columns: 2fr 8fr 2fr;
      
}
    
}
    
&.panel-left-width-Medium.panel-right-width-Large {
      
#contentcontainer {
        
grid-template-columns: 2fr 7fr 3fr;
      
}
    
}
    
&.panel-left-width-Large.panel-right-width-Small {
      
#contentcontainer {
        
grid-template-columns: 3fr 8fr 1fr;
      
}
    
}
    
&.panel-left-width-Large.panel-right-width-Medium {
      
#contentcontainer {
        
grid-template-columns: 3fr 7fr 2fr;
      
}
    
}
    
&.panel-left-width-Large.panel-right-width-Large {
      
#contentcontainer {
        
grid-template-columns: 3fr 6fr 3fr;
      
}
    
}
    
&.hideright {
      
&.panel-left-width-Small {
        
#contentcontainer {
          
grid-template-columns: 1fr 11fr 0;
        
}
      
}
      
&.panel-left-width-Medium {
        
#contentcontainer {
          
grid-template-columns: 2fr 10fr 0;
        
}
      
}
      
&.panel-left-width-Large {
        
#contentcontainer {
          
grid-template-columns: 3fr 9fr 0;
        
}
      
}
    
}
    
&.hideleft {
      
&.panel-right-width-Small {
        
#contentcontainer {
          
grid-template-columns: 0 11fr 1fr;
        
}
      
}
      
&.panel-right-width-Medium {
        
#contentcontainer {
          
grid-template-columns: 0 10fr 2fr;
        
}
      
}
      
&.panel-right-width-Large {
        
#contentcontainer {
          
grid-template-columns: 0 9fr 3fr;
        
}
      
}
    
}
  
}
  
#body {
    
&.hidelefthideright {
      
#contentcontainer {
        
grid-template-columns: 0 12fr 0;
      
}
    
}
  
}
}

CSS + Grid + CSS Variables

@supports (display: grid) {
  
#contentcolumn {
    
grid-area: content;
  
}
  
#leftPanels {
    
grid-area: leftpanels;
  
}
  
#rightPanels {
    
grid-area: rightpanels;
  
}
  
#contentcontainer {
    
display: grid;
    
grid: "leftpanels content rightpanels" / auto auto auto;
  
}
  
:root {
    
--grid-small-column: 1;
    --grid-medium-column: 2;
    --grid-large-column: 3;
    /* The calculations work good with px, but not with fr. We could adapt to have a % solution */
    
--grid-unit: 1fr;
  }
  
#body.panel-left-width-Small #contentcontainer {
    
--grid-leftPanels: calc(var(--grid-small-column) * var(--grid-unit));
  }
  
#body.panel-left-width-Medium #contentcontainer {
    
--grid-leftPanels: calc(var(--grid-medium-column) * var(--grid-unit));
  }
  
#body.panel-left-width-Large #contentcontainer {
    
--grid-leftPanels: calc(var(--grid-large-column) * var(--grid-unit));
  }
  
#body.panel-right-width-Small #contentcontainer {
    
--grid-rightPanels: calc(var(--grid-small-column) * var(--grid-unit));
  }
  
#body.panel-right-width-Medium #contentcontainer {
    
--grid-rightPanels: calc(var(--grid-medium-column) * var(--grid-unit));
  }
  
#body.panel-right-width-Large #contentcontainer {
    
--grid-rightPanels: calc(var(--grid-large-column) * var(--grid-unit));
  }
  
#body.hideleft #contentcontainer {
    
--grid-leftPanels: 0;
  }
  
#body.hideright #contentcontainer {
    
--grid-rightPanels: 0;
  }
  
#body.hidelefthideright #contentcontainer {
    
--grid-leftPanels: 0;
    --grid-rightPanels: 0;
  }
  
#contentcontainer {
    
--grid-content: auto;
    grid-template-columns: var(--grid-leftPanels) var(--grid-content) var(--grid-rightPanels);
  }
}

 

Tags:
    

Get Connected