skip to Main Content

I want to style these 4 buttons into a cross form like a D-Pad. I tried it and it somehow didn’t look like I expected it to do. I’m a bit new to the whole html and css stuff.
For context I am trying to build a 2048 game as a webapp and I thought I would do a D-pad for it to work on mobile.

div#btn-container {
  width: 400px;
  height: 400px;
  align-items: center;
  display: flex;
  justify-content: center;
  margin-top: 600px;
  margin-left: auto;
  margin-right: auto;
  background-color: black;
}

button#left {
  width: 100px;
  height: 100px;
  margin-left: auto;
  margin-right: auto;
  margin-top: 200px;
}

button#up {
  width: 100px;
  height: 100px;
  margin-right: auto;
  margin-left: auto;
}

button#down {
  width: 100px;
  height: 100px;
  margin-left: auto;
  margin-right: auto;
  margin-top: 400px;
}

button#right {
  width: 100px;
  height: 100px;
  margin-left: auto;
  margin-right: auto;
  margin-top: 200px;
}
<div id="btn-container">
  <button id="left"></button>
  <button id="up"></button>
  <button id="down"></button>
  <button id="right"></button>
</div>

2

Answers


  1. As @Justinas said, you’ll probably want to use CSS grid to achieve this styling. Here is an example to get you started. Notice specifically that a 3×3 grid was defined, and then grid-xxx-start was used to put each button in the appropriate location.

    div#btn-container {
      width: 400px;
      height: 400px;
      display: grid;
      grid: 133px 133px 133px / 133px 133px 133px;
      margin-left: auto;
      margin-right: auto;
      background-color: black;
      place-items: center center;
    }
    
    button#left {
      width: 100px;
      height: 100px;
      grid-row-start: 2;
      grid-column-start: 1;
    }
    
    button#up {
      width: 100px;
      height: 100px;
      grid-row-start: 1;
      grid-column-start: 2;
    }
    
    button#down {
      width: 100px;
      height: 100px;
      grid-row-start: 3;
      grid-column-start: 2;
    }
    
    button#right {
      width: 100px;
      height: 100px;
      grid-row-start: 2;
      grid-column-start: 3;
    }
    <div id="btn-container">
      <button id="left">L</button>
      <button id="up">U</button>
      <button id="down">D</button>
      <button id="right">R</button>
    </div>
    Login or Signup to reply.
  2. Layout

    For a flexbox (FBL) approach it is easiest to create a main FBL container containing three FBL child containers for the buttons.

    • The first and third FBL child containers are just one button wide, horizontally centered in the main FBL container.
    • The second FBL child container is three buttons wide holding only two buttons, pushed apart with justify-content: space-between

    Sizing

    • The button sizes can be any value, but I used linear equation y = mx + b to calculate a size relative to the current viewport minimum size (vmin). At vmin 240px the button size is 70px and at vmin 1080px it is 245px. With points (240,70) and (1080,245) the equation is: y = 0.20833x + 20. In CSS, converted to rem: calc(20.834vmin + 1.25rem)
    • The same goes for the button font size. At vmin 360px the font size is 12px and at vmin 1080px it is 16px. Points (360,12) and (1080,16) yield equation y = 0.00555x + 10. CSS: calc(0.556vmin + 0.625rem)

    Snippet

    .D-Pad {
        /* define variable sizes depending on current minimum viewport size */
        /* using linear equation y = mx + b for points (x1,y1) and (x2,y2) */
        --button-size: calc(20.834vmin + 1.25rem); /* (240,70)(1080,245) */
        --button-text: calc(0.556vmin + 0.625rem); /* (360,12)(1080, 16) */
    }
    
    .D-Pad, .D-Pad>* {
        /* Default Flexbox row containers */
        display: flex; justify-content: center; align-items: center;
    }
    .D-Pad, .btn-col {
        /* Flexbox column containers */
        flex-direction: column;
    }
    .btn-col {
        width: var(--button-size)
    }
    .btn-row { 
        width: calc(3 * var(--button-size)); /* creates center space */
        justify-content: space-between;      /* push buttons to either side */
    }
    .btn-col > *,  /* Using wildcards so any element will work, not only <button> */
    .btn-row > * {
        font-size: var(--button-text);
    
        width: var(--button-size);
        aspect-ratio: 1; /* make it a square */
    }
    
    /* Just demo */
    *             { box-sizing: border-box }
    body          { margin: 0; min-height: 100vh }
    body, .center { display: grid; place-items: center; text-align: center }
    .center       { padding: 0.5em }
    <div class="D-Pad">
        <div class="btn-col"><button>top</button></div>
        <div class="btn-row">
            <button>left</button>
            <div class="center">optional center element</div>
            <button>right</button>
        </div>
        <div class="btn-col"><button>bottom</button></div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search