rlperez
rlperez

Reputation: 1328

Bootstrap 4 - Column to row on small display

Have a grid with 4 columns and 4 rows. What I want to happen is on a small display the 4th column becomes a 5th row on a small display vs the column that it is on a medium+ display. It's a pet project to try and understand the bootstrap grid layout better. I'm essentially making a responsive calculator for the practice. I feel like I could do this with just raw CSS but figured bootstrap had to have some utilities that would make this easier. Images for example.

Large format:

enter image description here

Small format:

enter image description here

I have a start for the markup. There is some more associated CSS but I don't think it's important in the example. I've had a few versions but this is where I'm at in the moment.

<div class="container">
  <div class="row">
    <div class="col-md-8">
      <div class="row">
        <button type="button" class="btn-lg btn-outline-dark">1</button>
        <button type="button" class="btn-lg btn-outline-dark">2</button>
        <button type="button" class="btn-lg btn-outline-dark">3</button>
      </div>
      <div class="row">
        <button type="button" class="btn-lg btn-outline-dark">4</button>
        <button type="button" class="btn-lg btn-outline-dark">5</button>
        <button type="button" class="btn-lg btn-outline-dark">6</button>
      </div>
      <div class="row">
        <button type="button" class="btn-lg btn-outline-dark">7</button>
        <button type="button" class="btn-lg btn-outline-dark">8</button>
        <button type="button" class="btn-lg btn-outline-dark">9</button>
      </div>
      <div class="row">
        <button type="button" class="btn-lg btn-outline-light">&plusmn;</button>
        <button type="button" class="btn-lg btn-outline-dark">0</button>
        <button type="button" class="btn-lg btn-outline-light">.</button>
      </div>
    </div>
    <div class="col-md-4">
      <div class="row">
        <button type="button" class="btn-lg btn-outline-dark">X</button>
      </div>
      <div class="row">
        <button type="button" class="btn-lg btn-outline-dark">-</button>
      </div>
      <div class="row">
        <button type="button" class="btn-lg btn-outline-dark">+</button>
      </div>
      <div class="row">
        <button type="button" class="btn-lg btn-outline-dark">=</button>
      </div>
    </div>
  </div>
</div>

EDIT: I can only pick one solution as an answer but kiranvj, WebDevBooster, and dferenc all provided Bootstrap 4 release version working solutions. I can only mark one as an answer. No slight to the rest of you guys. My hands are tied.

Upvotes: 10

Views: 8864

Answers (4)

dferenc
dferenc

Reputation: 8126

I think, the simplest possible markup is the one below. It also uses the Order classes, but instead of setting the order of every button explicitly, this one touches just the "extra" buttons in the last column with .order-last .order-sm-0.

<div class="container">
    <div class="row justify-content-center">
        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">1</button>
        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">2</button>
        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">3</button>

        <button type="button" class="col-4 col-sm-3 order-last order-sm-0 btn-lg btn-secondary">X</button>

        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">4</button>
        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">5</button>
        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">6</button>

        <button type="button" class="col-4 col-sm-3 order-last order-sm-0 btn-lg btn-secondary">-</button>

        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">7</button>
        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">8</button>
        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">9</button>

        <button type="button" class="col-4 col-sm-3 order-last order-sm-0 btn-lg btn-secondary">+</button>

        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">&plusmn;</button>
        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">0</button>
        <button type="button" class="col-4 col-sm-3 btn-lg btn-dark">.</button>
        
        <!--
        Use `col-12 col-sm-3` in case you want a full-width `=` button 
        In that case you could omit `.justify-content-center` at the wrapper
        -->
        <button type="button" class="col-12 col-sm-3 order-last order-sm-0 btn-lg btn-secondary">=</button>
    </div>
</div>


<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>

Upvotes: 3

WebDevBooster
WebDevBooster

Reputation: 14964

Since you wanted to build a calculator, I took a slightly different approach than my esteemed colleagues and created a grid that looks, feels and quacks like an actual calculator. I hope you aren't too mad about that. :-)

The main job is done by using the re-ordering classes. Those allow moving things around based on your breakpoint needs.

For example, the class combo order-3 order-md-1 says:

"Normally i.e. from the smallest screen size onwards you're gonna go to position #3 but from the medium (md) screen size and up you're gonna go to position #1."

And since the neighboring HTML elements also have order-1 as their default position, that element is gonna appear in the same order on medium sized screens as the neighbors. But on smaller than md screens that element is gonna become a "third-class citizen" and will, therefore, be positioned after the element with the order-2 class.

The <div class="w-100"></div> elements are just handy dividers. w-100 means "width:100%".

Speaking of dividers: I've noticed that your calculator has no division button, but I hope you'll figure out what to do about that.

Finally, you hadn't specified what to do with the equal sign button. So, I took the liberty to change its appearance on smaller screens. That is accomplished by first hiding the default button using the d-none d-md-block classes and then having a wider version of it appear using the d-md-none class. That last class basically says: Hide it (display:none) from md screens and up.

Here's the working code:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono" rel="stylesheet">
<style>
body {
    font-family: 'Roboto Mono', monospace;
}
</style>

<div class="container">
    <div class="row mt-2">
        <div class="col-md-8">
            <div class="row">
                <button type="button" class="btn-lg btn-outline-dark order-1">1</button>
                <button type="button" class="btn-lg btn-outline-dark order-1">2</button>
                <button type="button" class="btn-lg btn-outline-dark order-1">3</button>
                <button type="button" class="btn-lg btn-outline-dark order-3 order-md-1">&times;</button>
                <div class="w-100 order-1"></div>
                <button type="button" class="btn-lg btn-outline-dark order-1">4</button>
                <button type="button" class="btn-lg btn-outline-dark order-1">5</button>
                <button type="button" class="btn-lg btn-outline-dark order-1">6</button>
                <button type="button" class="btn-lg btn-outline-dark order-3 order-md-1">&minus;</button>
                <div class="w-100 order-1"></div>
                <button type="button" class="btn-lg btn-outline-dark order-1">7</button>
                <button type="button" class="btn-lg btn-outline-dark order-1">8</button>
                <button type="button" class="btn-lg btn-outline-dark order-1">9</button>
                <button type="button" class="btn-lg btn-outline-dark order-3 order-md-1">+</button>
                <div class="w-100 order-1"></div>
                <button type="button" class="btn-lg btn-outline-light text-dark order-1">&pm;</button>
                <button type="button" class="btn-lg btn-outline-dark order-1">0</button>
                <button type="button" class="btn-lg btn-outline-light text-dark order-1">.</button>
                <button type="button" class="btn-lg btn-outline-dark order-1 d-none d-md-block">=</button>
                <div class="w-100 order-2"></div>
                <div class="w-100 order-4"></div>
            </div>
            <div class="row">
                <div class="col-3 col-sm-4 pl-0 pr-0 pr-sm-4">
                    <button type="button" class="btn-lg btn-block btn-outline-dark order-4 d-md-none">=</button>
                </div>
            </div>
        </div>
    </div>
</div>

Upvotes: 1

kiranvj
kiranvj

Reputation: 34147

I would do something like this. Check in full screen mode and resize to small

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row text-center">
  <div class="col-12 col-sm-8">
    <div class="row">
      <div class="col-4">black</div>
      <div class="col-4">black</div>
      <div class="col-4">black</div>
    </div>
    <div class="row">
      <div class="col-4">black</div>
      <div class="col-4">black</div>
      <div class="col-4">black</div>
    </div>
    <div class="row">
      <div class="col-4">black</div>
      <div class="col-4">black</div>
      <div class="col-4">black</div>
    </div>
  </div>
  <div class="col-12 col-sm-4 text-danger">
    <div class="row">
      	<div class="col-4 col-sm-12">pink</div>
      	<div class="col-4 col-sm-12">pink</div>
      	<div class="col-4 col-sm-12">pink</div>
    </div>
  </div>
</div>

Upvotes: 6

Marco Principio
Marco Principio

Reputation: 495

What I would do is create 3 additional pink div elements that render below the black divs, and then hide them using the hidden-*-up and hidden-*-down classes. When the screen is small, hide the pink divs on the right and show the pink divs on the bottom, and vice versa when the screen is small.

Upvotes: 1

Related Questions