DEV Community

Cover image for Designing a Playing Card With Flexbox
Alisa Bajramovic
Alisa Bajramovic

Posted on

Designing a Playing Card With Flexbox

I'm working on a conversation-starting app, built using React Native. The idea behind that app is that in many social settings--whether you're with friends, at a professional networking event, or on a date--you sometimes feel at a loss for what to talk about. You want to ask the other person a question, but maybe can't think of a good question.

My app contains three decks of "cards" for different social settings, and on each card is a question you can ask someone to help spur conversation. I liked the image of having playing cards contain these questions, and so modeled my app off of them. here's an example of a card from the Friend Stack:

Playing card with the question, "What's the best thing that happened to you this year?"

To flip to the next card in the stack. You simply tap on the right side of the card. To go back to the previous card, you tap on the left side. Every time you open up a stack, it shuffles the cards and places them in a random order.

In this blog post, I wanted to walk through how I designed the cards, which mostly came down to flexbox.


The general structure of my card goes as follows --

  screen
    cardShape
      imageSectionTop
        imageTop
      cardBody
        directions
        questionSection
        directions
      imageSectionBottom
        imageBottom
Enter fullscreen mode Exit fullscreen mode

In the above image, 'screen' is the yellow background. 'cardShape' is the white container with rounded edges. 'imageSectionTop' is the top section of the card, above the line where the question starts. 'imageTop' is the image in the top left hand corner. 'cardBody' is the middle section of the card. 'questionSection' is the light grey box that surrounds the text, and 'directions' are the areas to the left and right of the questionSection (the areas are touchable and enable you to flip between cards). 'imageSectionBottom' and 'imageBottom' are the reverse sections from the top of the card.

I started designing this screen knowing that I wanted it to be shaped like a standard playing card. The first element I needed was for the card to have rounded corners. I wanted the card's shape to be very apparent against the background, so it needed to have a black border. Also, since card faces are typically white or off-white, I set the background color to white.

Here's the style sheet for the first two elements -- the background of the whole screen, and the card itself.

const styles = StyleSheet.create({
  screen: {
    flex: 1,
    backgroundColor: "#ffc40b"
  },
  cardShape: {
    flex: 1,
    margin: 30,
    borderColor: "black",
    borderWidth: 2,
    borderRadius: 40,
    backgroundColor: "#FFFFFF"
  }
  //...
})
Enter fullscreen mode Exit fullscreen mode

Many playing cards have suits in the opposite corners of the card, and I wanted to replicate that in my cards. I call these parts 'imageSectionTop' and 'imageSectionBottom'. The purpose of those sections is primarily just to set the height. Within imageSectionTop is the image itself. The image needed its own styling, and since this symbol is a circle, I set the height and width equal to 60. In order to equally space the image from the borders, I set the margin equal to 15 (60 + 15 is 75, which is the height of the container.

const styles = StyleSheet.create({
  //...
  imageSectionTop: { height: 75 },
  imageTop: { 
     height: 60, 
     width: 60, 
     margin: 15 
  }
  //...
})
Enter fullscreen mode Exit fullscreen mode

Next comes the cardBody. This contains the question, as well as the two 'touchable' sections which enable going back or forward in the card stack. I set the flex direction of the card body to 'row' so that the three areas--directions, questionSection, directions--would be spaced horizontally rather than vertically. I also set justify content to 'space-evenly' so that the three sections would be evenly aligned. Finally, I wanted to set a margin around this section so that the there was a space between the questions and the image.

const styles = StyleSheet.create({
  //...
  cardBody: {
    flex: 1,
    flexDirection: "row",
    justifyContent: "space-evenly",
    margin: 10
  }
  //...
})
Enter fullscreen mode Exit fullscreen mode

In the current state of my app, directions does not have any specific styling, though previously I considered setting the sides to different colors.

The section that contains the question is aptly called 'questionSection'. I set flex to 5 so that it would take up the majority of the container. I wanted the text inside of it to be centered so I justified the content to center. I also thought the design would look better if there was a slight color difference between this section and the background of the card, so I set it to a light grey color, and set a black border around it.

const styles = StyleSheet.create({
  //...
  questionSection: {
    flex: 5,
    justifyContent: "center",
    borderColor: "black",
    borderWidth: 2,
    backgroundColor: "#fafafa"
  }
  //...
})
Enter fullscreen mode Exit fullscreen mode

The final element of the card is the image in the bottom right corner. I set the height of the image's container, imageSectionBottom, equal to 75 (same as the top), but this time set the flex direction to 'row-reverse'. This easily would enable me to place the image at the bottom right corner, rather than bottom left.

The styling on the image itself, however, is different than the top. Rather that setting a margin around all sides of the icon, I could only set it on the bottom and right side. Setting a margin on all sides pushed my image out of its container, and therefore was uneven.

const styles = StyleSheet.create({
  //...
  imageSectionBottom: {
    height: 75,
    flexDirection: "row-reverse"
  },
  imageBottom: { 
    height: 60, 
    width: 60, 
    marginBottom: 15, 
    marginRight: 15 
  }
})
Enter fullscreen mode Exit fullscreen mode

All put together, this is how I made the card:

const styles = StyleSheet.create({
  screen: {
    flex: 1,
    backgroundColor: "#ffc40b"
  },
  cardShape: {
    flex: 1,
    margin: 30,
    borderColor: "black",
    borderWidth: 2,
    borderRadius: 40,
    backgroundColor: "#FFFFFF"
  },
  imageSectionTop: { height: 75 },
  imageTop: { 
    height: 60, 
    width: 60, 
    margin: 15 },
  cardBody: {
    flex: 1,
    flexDirection: "row",
    justifyContent: "space-evenly",
    margin: 10
  },
  questionSection: {
    flex: 5,
    justifyContent: "center",
    borderColor: "black",
    borderWidth: 2,
    backgroundColor: "#fafafa"
  },
  imageSectionBottom: {
    height: 75,
    flexDirection: "row-reverse"
  },
  imageBottom: { 
    height: 60, 
    width: 60, 
    marginBottom: 15, 
    marginRight: 15 }
});
Enter fullscreen mode Exit fullscreen mode

Let me know if you have any questions! If you want to see the full repository for this project, you can find my Github (here)[https://github.com/alisabaj/piqued]. (Please note this is still a work in progress.)

Top comments (0)