Adapt Non-Adjacent Content Sections For XL Screens in Sidebar Without Replicating Source Code Segments

I'm struggling to figure out how to achieve my desired layout.

Details

  1. The solution presented by sheriffderek using CSS grid seems promising, but it causes issues with white space when adding content to the profile block on XL screens. Adjusting the grid-template-areas layout may not work well with variable-height content.
  2. Despite my experience with CSS/HTML, I am finding it challenging to achieve this using Bootstrap 4 and CSS without duplicating code blocks.
  3. Bootstrap 4 is a requirement for me, and I prefer a purely Bootstrap 4 solution or one that utilizes flex classes from Bootstrap 4. Flexbox would be acceptable if it meets my needs.

Context

  1. I have a fixed left sidebar which I want to hide on small screens. However, the focus is on arranging the middle and right columns on screen widths between 768px and larger.
  2. When the screen size ranges from 768px (md min) to 1199px (lg max), I need a "Cards Lower Sidebar" block to be positioned between a search bar and the main content area. On screens of 1200px (xl) or wider, this block should move to the lower-right sidebar.
  3. Similarly, a profile content block below the main content area should transition to the top-right sidebar when the screen width exceeds 1200px. Duplicating HTML source code blocks is not an option due to constraints.

Figure 1

In the provided images, you can see the desired positioning of the content blocks based on screen size adjustments.

I've included a minimal example code snippet for reference.

Note: I had previously asked a similar question but found my own answer lacking. I'm seeking a more efficient solution that avoids duplicating HTML code blocks in Django templates.

UPDATE

Based on previous answers, I still face challenges with realistic content inputs and gaps between areas on XL screens. Any suggestions or solutions are welcome.

Answer №1

Here's an example showcasing how to tackle this task using Bootstrap with a touch of creativity (added the extra class .break). I was intrigued to see if Bootstrap could handle it, and it did!

html {
  height: 100%;
}

body {
  height: 100%;
}

.break {
  flex-basis: 100%;
  width: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js"></script>

<div class="bg-primary">Navbar</div>
<div class="d-flex flex-wrap flex-column h-75">
  <div class="col-3 flex-fill bg-danger">Fixed</div>
  <div class="break"></div>
  <div class="col-lg-6 col-9 flex-fill flex-grow-0 bg-success order-1">Search</div>
  <div class="col-lg-3 col-9 flex-fill bg-warning order-lg-4 order-1">Cards Lower Sidebar</div>
  <div class="col-lg-6 col-9 flex-fill bg-info order-1">Main Content Area</div>
  <div class="col-lg-3 col-9 flex-fill flex-grow-0 bg-dark order-lg-3 order-1">User</div>
  <div class="break order-2"></div>
</div>

Check it out on Codepan for a dynamic view.

UPDATE:

I tested all approaches and found that there is no straightforward CSS solution for this task. However, utilizing a bit of jQuery alongside Bootstrap 4 can resolve the issue efficiently. Here's a refined answer that functions as intended without any additional CSS tweaks.

transferBlocks(); // calling function

window.addEventListener('resize', () => {
  transferBlocks(); // calling function on resize
});

function transferBlocks() {
  if ($(window).width() < 992) {
    $('#search').after($('#cardsLowerSidebar'));
    $('#mainContentArea').after($('#user'));
  } else {
    $('#colRight').append($('#user'));
    $('#colRight').append($('#cardsLowerSidebar'));
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js"></script> 

<div class="d-flex flex-nowrap flex-column min-vh-100">
  <div class="bg-primary">Navbar</div>
  <div class="flex-fill d-flex flex-nowrap">
    <div class="col-3 px-0 bg-danger">Fixed</div>
    <div class="col-lg-6 col-9 px-0 d-flex flex-nowrap flex-column">
      <div id="search" class="bg-success">Search</div>
      <div id="cardsLowerSidebar" class="flex-fill bg-warning">Cards Lower Sidebar</div>
      <div id="mainContentArea" class="flex-fill bg-info">Main Content Area Main Content... 

View the updated version on Codepan for interactive visualization.

UPDATE 2:

This approach combines Bootstrap with display: grid and some custom JS to enhance functionality. For wider screens (> 992px), we envision a 2-column layout with 24 rows grid system.

The first column includes elements like #search covering row 1 onwards and #mainContentArea spanning multiple rows from row 2 onwards. Similarly, the second column houses #user taking precedence over #search and #cardsLowerSidebar spanning rows below it.

Feel free to experiment with the row values and explore more about Grid Row.

.d-grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  grid-auto-rows: auto;
}
// Relevant styling for different screen sizes and layouts.
Your HTML content goes here...

Answer №2

One of the first steps I would take is to identify all the components.

(Although I resisted for a while... CSS grid truly works wonders!)

https://i.sstatic.net/xVywl.png and

https://i.sstatic.net/bjgQe.png

To ensure that different sections do not clash, you need to make sure of it. While achieving what you have here may involve some clever tricks and margin adjustments - it's probably easier with CSS grid. That's what it was designed for!

part one: https://codepen.io/sheriffderek/pen/8e7bf2469b0cd16515f1278fa0519eea?editors=1100

You should also consider making changes at the medium breakpoint...

part two: https://codepen.io/sheriffderek/pen/3d57b839cf62d00b4bdc46af698218ca?editors=1100

part three: https://codepen.io/sheriffderek/pen/215e14b16e1a8af05bce4ab236dab465

<header>
    <nav>
        app header / nav-bar
    </nav>
</header>

<aside class="sidebar">
    sidebar
</aside>

<nav class="actions">
    bread-crumbs and search
</nav>

<section class="cards">
    cards
</section>

<main>
    main stuffs
</main>

<aside class="profile">
    profile stuff
</aside>

.

* {
    box-sizing: border-box;
}

body {
    margin: 0;
}

header {
    border: 5px solid lightblue;
    padding: 10px;
}

.sidebar {
    border: 5px solid #ff0066;
    padding: 10px;
}

.actions {
    border: 5px solid lime;
    padding: 10px;
}

.cards {
    border: 5px solid orange;
    padding: 10px;
}

main {
    border: 5px solid yellow;
    padding: 10px;
}

.profile {
    border: 5px solid black;
    padding: 10px;
}

/* with flex-box... you COULD reorder these a bit on small screens if you wanted */


/* your 'medium' size */
@media (min-width: 600px) {

}

/* your 'large' size */
@media (min-width: 900px) {
    
    body { /* look! it's like a little drawing of the layout!" */
        display: grid;
        grid-template-areas: 
            "header header header"
            "sidebar  actions  actions"
            "sidebar  cards    cards"
            "sidebar  main     main"
            "sidebar profile  profile";
    }

    header {
        grid-area: header; /* note! no quotes " " */
    }

    .sidebar {
        grid-area: sidebar;
    }

    .actions {
        grid-area: actions;
    }

    .cards {
        grid-area: cards;
    }

    main {
        grid-area: main;
    }

    .profile {
        grid-area: profile;
    }
}

/* your 'extra-large' size */
@media (min-width: 1300px) {
    body { /* look! it's another drawing of the layout!" */
        display: grid;
        grid-template-areas: 
            "header   header   header  header"
            "sidebar  actions  actions profile"
            "sidebar   main     main   cards"
            "sidebar   main     main   cards";
    }
}

Mind-blowing, isn't it!???

Note: Remember that there are other factors to consider and this is just an optimistic scenario. You may need to set a max-width on the parent container - and the layout might change based on the items in each area - but this should give you a good starting point.

Answer №3

@sheriffderek's solution is solid. However, you can streamline it by incorporating a mix of flexbox and grid. This allows you to still utilize Bootstrap for certain aspects of the layout.

The Issue with Bootstrap

It's unlikely that you'll find a complete Bootstrap 4 solution. The issue lies in the fact that Bootstrap does not make use of CSS Grid for layouts. When creating a Grid with Bootstrap, the Grid functionality is essentially simulated using nested flex elements.

Here's how I would approach this.

Flexbox + Grid

Set up the main sections of the page using traditional layout rules and flexbox. I recommend excluding the header from this setup since it remains static and defaults to display:block, naturally pushing other content down as needed.

------------------------------------------------------------------
|                     header (display block)                     |
------------------------------------------------------------------
|                       |                                        |
|                       |                                        |
|      nav (flex)       |                 content (flex)         |
|                       |                                        |
------------------------------------------------------------------

Note: You could use Bootstrap here if desired, but I will demonstrate using display:flex for simplicity and ease of future reference.

header {
  background-color: lightGray;
  padding: 10px;
  text-align: center;
}

#mainContent {
  display:flex;
}

nav {
  background-color: aqua;
  padding: 10px;
  text-align: center;
  flex-basis: 33.3333%;
  min-height: 100px;
}
#content {
  background-color: tan;
  padding: 10px;
  text-align: center;
  flex-basis: 66.6666%;
}
<header>Header Content</header>
<div id="mainContent">
  <nav>Nav Bar</nav>
  <section id="content">Content</section>
</div>

Standard Content Display

No need for complex grid or flexbox techniques for regular display. Block elements inherently push everything else down, which matches your mockup.

header {
  background-color: lightGray;
  padding: 10px;
  text-align: center;
}

header {
  background-color: lightGray;
  padding: 10px;
  text-align: center;
}

#mainContent {
  display:flex;
}

nav {
  background-color: aqua;
  padding: 10px;
  text-align: center;
  flex-basis: 33.3333%;
  min-height: 100px;
}
#content {
  background-color: tan;
  padding: 5px 10px;
  text-align: center;
  flex-basis: 66.6666%;
}

.search, .cards, .content, .profile {
    background: rgba(0,0,0,0.2);
    padding: 10px;
    margin: 5px 0;
}
<header>Header Content</header>
<div id="mainContent">
  <nav>Nav Bar</nav>
  <section id="content">
      <div class="search">Search</div>
      <div class="cards">Cards</div>
      <div class="content">Main Content</div>
      <div class="profile">Profile</div>
  </section>
</div>

Large Screens

For larger screens, utilize Media Queries to implement CSS Grid and overwrite the default block-level layouts.

header {
        background-color: lightGray;
        padding: 10px;
        text-align: center;
    }
    
    #mainContent {
        display: flex;
    }
    
    nav {
        background-color: aqua;
        padding: 10px;
        text-align: center;
        flex-basis: 33.3333%;
        min-height: 100px;
    }
    
    #content {
        background-color: tan;
        padding: 5px 10px;
        text-align: center;
        flex-basis: 66.6666%;
    }
    
    .search,
    .cards,
    .content,
    .profile {
        background: rgba(0, 0, 0, 0.2);
        padding: 10px;
        margin: 5px 0;
    }

    @media screen {
        /* typically, there would be specific sizes here, but we're demonstrating the effect of the media query */
        #content {
            padding: 5px;
            display: grid;
            grid-template-areas: "search profile"
                                 "content profile" 
                                 "content cards"
                                 "content cards";
        }
        .search,
        .cards,
        .content,
        .profile {
            margin: 5px;
        }
    }
<header>Header Content</header>
<div id="mainContent">
    <nav>Nav Bar</nav>
    <section id="content">
        <div class="search">Search</div>
        <div class="cards">Cards</div>
        <div class="content">Main Content</div>
        <div class="profile">Profile</div>
    </section>
</div>

If you wish to adjust sizes explicitly, consider utilizing Grid's sizing system or updating the grid-template-areas with multiples of the same-named rows/columns.

Answer №4

I experimented with a simple flexbox property, utilizing the HTML structure provided by @sheriffderek as a foundation. This concept is meant to inspire exploration of alternative design possibilities.

Limitation: Any content located outside of this container will be positioned behind the main content. Essentially, I am imposing a fixed height to bring the profile and cards to the top. You can determine the height of the main content and the empty space adjacent to the container using a line of JavaScript.

<header>
    <nav>
        App header / navigation bar
    </nav>
</header>
<div class="all-stuff">
    <aside class="sidebar">
        Sidebar
    </aside>
    <div class="container">
        <nav class="actions">
            Breadcrumbs and search
        </nav>

        <section class="cards">
            Cards
        </section>

        <main>
            Main content
            <div style="background-color: #f5f5f5;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit... (content truncated for brevity)

        </main>

        <aside class="profile">
            Profile information
            <p>Profile details</p>
        </aside>
    </div>
</div>

The corresponding CSS code would be:

* {
    box-sizing: border-box;
}

body {
    margin: 0;
}

header {
    border: 3px solid lightblue;
    padding: 10px;
}

.sidebar {
    border: 3px solid #ff0066;
    padding: 10px;
}

.actions {
    border: 3px solid lime;
    padding: 10px;
}

.cards {
    border: 3px solid orange;
    padding: 10px;
}

main {
    border: 3px solid yellow;
    padding: 10px;
}

.profile {
    border: 3px solid black;
    padding: 10px;
}

/* Additional styling and media queries included */
*Additional CSS code listed above*

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for resolving the error "Invalid value for style prop - must be an object" in a React.js and CSS scenario

Hey there, I'm currently working with module.css in React and facing an issue when trying to include the following line: <span style="--i:1;"><img src="https://i.postimg.cc/BQcRL38F/pexels-photo-761963.jpg" alt="not f ...

Display the element when it becomes visible in the user's viewport as they

I've been struggling to implement a feature where an element is shown on scroll when it's in the viewport and hidden when it's not. However, despite my efforts, I haven't been able to get it working properly. Here's what I have so ...

What is the best way to retrieve a GWT textbox value using Selenium WebDriver?

I'm currently testing my GWT application with selenium, and the HTML generated by GWT Textbox appears like this: <input type="text" class="gwt-TextBox" > Even though there's no value visible in the code above, I can see text in the UI. Is ...

Refresh numerous pages

Currently, I'm working on a freelance project where I've been tasked with re-coding an outdated menu for my client. The website is built on static pages, so updating the menu manually on each page seems like a time-consuming and repetitive task. ...

What is the reason for JavaScript consistently returning the initial value as the result?

My current issue involves customizing Joomla article content using a module. I am attempting to hide a div until a user clicks on an input, such as a radio button labeled Test1. Once Test1 is selected, another hidden field within the div should display the ...

What is the best way to send data to PHP while moving objects between different div elements?

I have a situation where I have two parent divs containing dynamic children divs, and I want to enable POST requests to PHP when items are dragged from one side to the other (and vice versa). Here is the Javascript code I am using: function allowDrop( ...

How can I create a unique visual effect on the background in frontend development using chipped design techniques?

Creating a static website utilizing React. Description I am looking to incorporate a visual effect into the website pages, similar to the one demonstrated below. visual effect The goal is to design a rectangular background with triangles cut out from it ...

Illustrating a fresh DOM element with intro.js

I am currently utilizing intro.js to create a virtual 'tour' for my website. As I aim to provide a highly interactive experience for users, I have enabled the ability for them to engage with highlighted DOM elements at different points in the tou ...

Direct your attention towards the bootstrap dropdown feature

I have encountered an issue with using a bootstrap dropdown. I need to focus on the dropdown in order to navigate through its options using the keyboard. However, my current attempt at achieving this using jQuery does not seem to be working when I use $(&a ...

Stable Banner with Automatic Scroll to Sections

I have implemented a script that allows for smooth scrolling to different sections within a webpage when clicking on links in the top navigation menu. In the HTML, I've assigned IDs to each section (section1, section2, section3, etc.) and linked these ...

Utilizing if conditions within loops in a Jade template

Hey there. I am attempting to create a `tr` element at the start and after every 9th item. I am using the modulo operator as shown in the example above. However, if I want to include `td` elements inside that same `tr`, with an `else` condition for inst ...

Is the navigation item only clickable within its designated area?

Apologies in advance for the confusion, but I'm facing an issue with the navigation bar on my website. It works perfectly on the Home page when hovered over, but on the login and register pages, it requires hovering over a specific spot under the item ...

Unable to override default styles with custom styles in React MUI 5

I've been attempting to replace the default MUI 5 Button styles with my custom styles using either withStyles or a className (created using makeStyles), but I'm running into an issue where the default styles take precedence over my custom ones. I ...

Toggle a button with javascript

My setup involves two switches: <input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="switch1" checked> <label class="onoffswitch-label" for="switch1"> <span class="onoffswitch-inner"></span> <span ...

What is the best way to attach an event listener to detect the coordinates where a click occurs inside a div element?

Imagine a situation where you have a div container measuring 200px by 500px. The goal is to implement an event listener that can identify the x and y coordinates within this div when it is clicked. What would be the approach to achieve this in React? ...

Changing the Color of Hamburger Menu Lines in Bootstrap

How can I change the color of the hamburger menu icon's lines for medium and smaller screen sizes? I have attempted changing it through style attributes and using !important in my CSS file, but so far nothing has been successful. ...

Attaching dynamic data to a specific element within an array

I have successfully created a demo where elements can be dropped into a specific area and their top and left values are displayed. I have also added functionality to remove dropped items and move them between different blocks. However, I am encountering so ...

"Encountering issues with updating the .css file while debugging in ASP.NET MVC 2, changes

I've been working on an MVC 2 Project and ran into an issue. I made changes to the attributes of an id in the Site.css file, specifically changing the color from White to Red. However, when I run the application, the changes are not reflected on the v ...

JavaScript code altered link to redirect to previous link

I added a date field to my HTML form. <input type="date" name="match_date" id="matchDate" onchange="filterMatchByDate(event)" min="2021-01-01" max="2021-12-31"> There is also an anchor tag ...

Learn how to stream videos using the YouTube Player API's loadPlaylist feature

Is there a way to make the next video play automatically using the loadPlaylist option? I've tried implementing this code but unfortunately, it doesn't work and the video won't play: <div id="player"></div> <script> var ...