0

I've built a "Buzzfeed-like" quiz app with four answer choices for each question. On mobile I'm very pleased by the layout (a 2x2 box). However, on desktop the answers are simply displaying as 4 choices horizontally across the screen. The main issue is that I'm using Angular to generate all the questions and answer choices, which makes styling a bit trickier. Any ideas on how to 'elegantly' code the html/css so it always displays the answer choices as a 2x2 box? I've attempted to use media queries, but it feels like putting a bandaid on a large wound.

Current code and images below:

HTML:

<div class="jumbotron text-center" ng-hide="quizComplete">
    <h3>{{ questions[number].ask }}</h3>
    <div class="row">
        <div ng-repeat="answer in questions[number].answers" class="choice">
            <div ng-click="recordChoice(answer.points)">
                <span class="centerer"></span>
                <span class="centered">{{ answer.choice }}</span>
            </div>
        </div>
    </div>
</div>

CSS:

.choice {
    position: relative;
    display: inline-block;
    width: 128px;
    height: 128px;
    margin: 8px;
    background: rgba(183,222,237,1);
    background: -moz-linear-gradient(45deg, rgba(183,222,237,1) 0%, rgba(33,180,226,1) 49%, rgba(113,206,239,1) 92%, rgba(183,222,237,1) 100%);
    background: -webkit-gradient(left bottom, right top, color-stop(0%, rgba(183,222,237,1)), color-stop(49%, rgba(33,180,226,1)), color-stop(92%, rgba(113,206,239,1)), color-stop(100%, rgba(183,222,237,1)));
    background: -webkit-linear-gradient(45deg, rgba(183,222,237,1) 0%, rgba(33,180,226,1) 49%, rgba(113,206,239,1) 92%, rgba(183,222,237,1) 100%);
    background: -o-linear-gradient(45deg, rgba(183,222,237,1) 0%, rgba(33,180,226,1) 49%, rgba(113,206,239,1) 92%, rgba(183,222,237,1) 100%);
    background: -ms-linear-gradient(45deg, rgba(183,222,237,1) 0%, rgba(33,180,226,1) 49%, rgba(113,206,239,1) 92%, rgba(183,222,237,1) 100%);
    background: linear-gradient(45deg, rgba(183,222,237,1) 0%, rgba(33,180,226,1) 49%, rgba(113,206,239,1) 92%, rgba(183,222,237,1) 100%);
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b7deed', endColorstr='#b7deed', GradientType=1 );
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
    cursor: pointer;
    cursor: hand;
}

.choice div {
    position: absolute;
    background: transparent;
    width: 100%;
    height: 100%;
    padding: 5px;
    top: 0;
    left: 0;
    text-decoration: none; /* No underlines on the link */
    z-index: 10; /* Places the link above everything else in the div */
}

.centerer {
    display: inline-block;
    height: 100%;
    vertical-align: middle;
}

.centered {
    display: inline-block;
    vertical-align: middle;
    color: white;
}

mobile view (preferred): mobile view

desktop view (wish to look like mobile view): desktop view

MattDionis
  • 3,534
  • 10
  • 51
  • 105
  • Use `@media` queries? – royhowie Aug 17 '14 at 23:10
  • Your demo really doesn't make it clear what the issue is, but @media is not a bandaid solution. :-) – ralph.m Aug 17 '14 at 23:12
  • Apologies for not being more clear. I edited my above post by adding screenshots. I'm aiming for that 2X2 layout no matter the screen size. – MattDionis Aug 17 '14 at 23:19
  • use a `
    ` tag after two boxes
    – Dan Aug 17 '14 at 23:21
  • In future please remove code not relevant to the problem. Your gradient properties are just meaningless clutter that distract from the actual issue. – Jon P Aug 17 '14 at 23:50
  • @Dan adding a `
    ` tag is not neccesary and appart from using tables would be the least elegant way of solving the problem. This can be solved easily with CSS. If the OP then wants to change the style again he has to change the markup and CSS instead of CSS alone.
    – Jon P Aug 17 '14 at 23:52

3 Answers3

2

The simplest solution with the markup you have is to set the width of the row. Your selections are 128px with a total margin of 16px so set the width of row to double that, and maybe a little more to allow for the approximately 4px of whitespace added between inline(-block) elements.

.row
{
     width:300px;
}

Demo

I wouldn't say this is the most elegant solution, just the simplest fix without refactoring your code. You could also experiment with float:left instead of inline block with .choice:nth-child(odd){clear:both} to get every other element to start on a new row.

Demo

Jon P
  • 19,442
  • 8
  • 49
  • 72
1

Most elegant? maybe a framework

Bootstrap

to achive that this would work

<div clas="row">
    <div class="col-md-3 col-xs-6">
        1
    </div>
    <div class="col-md-3 col-xs-6">
        2
    </div>
    <div class="col-md-3 col-xs-6">
        3
    </div>
    <div class="col-md-3 col-xs-6">
        4
    </div>

</div>
bto.rdz
  • 6,636
  • 4
  • 35
  • 52
0

There are a couple of solutions using angular, but perhaps the simplest is to insert a line break at the beginning of the 3rd element.

<br ng-if="($index) % 2 == 0 && $index != 0"/>

When using ng-repeat, angular has a local scope variable called $index, which increments each time it repeats. We preform some modular division on it, and make sure it doesn't display on the first index, and you have what you need.

<div class="jumbotron text-center" ng-hide="quizComplete">
    <h3>{{ questions[number].ask }}</h3>
    <div class="row">
        <div ng-repeat="answer in questions[number].answers" class="choice">
            <br ng-if="($index) % 2 == 0 && $index != 0"/>
            <div ng-click="recordChoice(answer.points)">
                <span class="centerer"></span>
                <span class="centered">{{ answer.choice }}</span>
            </div>
        </div>
    </div>
</div>
Mathew Kleppin
  • 302
  • 2
  • 7
  • Why use angular when CSS will do the job? This is a styling issue so this should be handled with a style sheet. – Jon P Aug 18 '14 at 00:20
  • I agree that styling should be kept to css; the most elegant solution should be able to handle a wider range of device size and content size. You can use [ng-class](http://stackoverflow.com/questions/7792652/what-is-the-best-way-to-conditionally-apply-a-class-with-angularjs) if you want to add a specific styling to a div. I proposed an angular solution because troubleshooting a bunch of css styles on multiple devices with different browsers using pseudo selectors can be a bit of a headache. Why write 10 lines of code when you can just write one? – Mathew Kleppin Aug 18 '14 at 01:39