Introduction to CSS in Our Flask Application

Welcome to the second lesson of our course on building an image generation web application with Flask! In our previous lesson, we created the HTML structure for our application, setting up the tabs, form elements, and containers that will make up our user interface. While the structure is in place, our application currently lacks visual appeal and usability.

In this lesson, we'll focus on styling our application using CSS (Cascading Style Sheets). CSS is a styling language that allows us to control the appearance of HTML elements, including colors, fonts, spacing, and layout. By adding CSS to our application, we'll transform the basic HTML structure into an attractive, user-friendly interface.

Remember that in a Flask application, static files like CSS are stored in a folder called static. We've already linked our CSS file in the HTML using the Flask url_for function:

HTML, XML
1<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

This tells Flask to look for a file named style.css in the static folder. Now, let's create this file and add our styles to it.

Setting Up the Page Layout

Let's start by styling the basic page layout, including the body element and the main container. This will set the foundation for our application's appearance.

CSS
1body { 2 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 3 background-color: #f0f0f0; 4 margin: 0; 5 padding: 40px 0; 6 display: flex; 7 flex-direction: column; 8 justify-content: center; 9 align-items: center; 10 min-height: 100vh; 11} 12 13.container { 14 background: white; 15 padding: 30px; 16 border-radius: 12px; 17 box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); 18 width: 100%; 19 max-width: 600px; 20}

In this code, we're styling the body element to use a modern sans-serif font stack, with 'Segoe UI' as the primary font. We've set a light gray background color (#f0f0f0) and removed the default margin. We've also added padding to the top and bottom of the page.

The display: flex, flex-direction: column, justify-content: center, and align-items: center properties work together to center our content both horizontally and vertically on the page. The min-height: 100vh ensures that the body takes up at least the full height of the viewport, which helps with the centering.

For the .container class, we've set a white background, added padding for spacing, and used border-radius to round the corners. The box-shadow property adds a subtle shadow effect, giving the container a slight elevation above the background. We've set the width to 100% but limited the maximum width to 600 pixels, which will make our application responsive while preventing it from becoming too wide on large screens.

With these styles in place, our application already looks much better. The content is centered on the page, and the white container stands out against the light gray background.

Designing the Tab Navigation System

Next, let's style the tab navigation system that allows users to switch between the "Generate Image" and "View History" tabs.

CSS
1.tabs { 2 display: flex; 3 justify-content: center; 4 margin-bottom: 30px; 5} 6 7.tab-button { 8 padding: 10px 25px; 9 margin: 0 10px; 10 background-color: #0056b3; 11 color: white; 12 border: none; 13 border-radius: 6px; 14 cursor: pointer; 15 transition: background-color 0.3s; 16} 17 18.tab-button:hover { 19 background-color: #007bff; 20} 21 22.tab-content { 23 display: block; 24 margin-top: 20px; 25}

For the .tabs container, we're using flexbox (display: flex) with justify-content: center to center the tab buttons horizontally. We've added a margin at the bottom to separate the tabs from the content below.

The .tab-button class styles the individual tab buttons. We've added padding to make the buttons larger and more clickable, and margins to separate them from each other. The background color is a deep blue (#0056b3), and the text color is white for good contrast. We've removed the default border, rounded the corners with border-radius, and set the cursor to a pointer to indicate that the buttons are clickable.

The transition: background-color 0.3s property creates a smooth transition effect when the background color changes, which happens when a user hovers over a button. The .tab-button:hover selector targets buttons when the user hovers over them, changing the background color to a lighter blue (#007bff).

Finally, the .tab-content class styles the containers for the tab content. We've set display: block to make them visible (though in our HTML, the "history" tab content has an inline style of display: none to hide it initially). We've also added a margin at the top to separate the content from the tabs.

With these styles, our tab navigation system now looks like a proper set of tabs, with clear visual feedback when users interact with them.

Enhancing Form Elements

Now, let's style the form elements in our "Generate Image" tab, including the input fields, select dropdowns, and the generate button.

CSS
1input, select { 2 width: 100%; 3 padding: 12px; 4 margin-top: 15px; 5 margin-bottom: 20px; 6 border-radius: 6px; 7 border: 1px solid #d1d1d1; 8 font-size: 14px; 9} 10 11button { 12 width: 100%; 13 padding: 12px; 14 background-color: #007bff; 15 color: white; 16 border: none; 17 border-radius: 6px; 18 cursor: pointer; 19 transition: background-color 0.3s; 20 font-size: 15px; 21} 22 23button:hover { 24 background-color: #0056b3; 25}

For both input and select elements, we've set the width to 100% to make them span the full width of their container. We've added padding to make them larger and more user-friendly, and margins to separate them from each other. The border-radius property rounds the corners, and we've set a light gray border color (#d1d1d1). We've also increased the font size slightly for better readability.

For the button elements, we've also set the width to 100% and added padding. The background color is a bright blue (#007bff), and the text color is white. Like with the tab buttons, we've removed the default border, rounded the corners, set the cursor to a pointer, and added a transition effect for the background color. We've also increased the font size for better readability.

The button:hover selector changes the background color to a deeper blue (#0056b3) when the user hovers over a button, providing visual feedback.

With these styles, our form elements now look more polished and user-friendly. The input fields and select dropdowns are clearly defined, and the button stands out as a call to action.

Styling the Image Display Areas

Finally, let's style the areas where images will be displayed, both in the "Generate Image" tab and the "View History" tab.

CSS
1#image-container, #history-container { 2 margin-top: 20px; 3} 4 5img { 6 max-width: 100%; 7 border-radius: 10px; 8 box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); 9}

For both the #image-container and #history-container elements, we've added a margin at the top to separate them from the elements above.

For the img elements that will be displayed in these containers, we've set the maximum width to 100% to ensure that they don't overflow their containers. We've rounded the corners with border-radius and added a subtle shadow effect with box-shadow to give the images a slight elevation.

With these styles, our image display areas are now ready to showcase the generated images in an attractive way.

Summary and Next Steps

In this lesson, we've transformed our basic HTML structure into an attractive, user-friendly interface using CSS. We've styled the page layout, tab navigation system, form elements, and image display areas, creating a cohesive and visually appealing design.

Here's a summary of what we've accomplished:

  1. We've set up a centered, responsive layout with a clean white container on a light gray background.
  2. We've styled the tab navigation system to provide clear visual feedback when users interact with it.
  3. We've enhanced the form elements to make them more user-friendly and visually appealing.
  4. We've prepared the image display areas to showcase the generated images in an attractive way.

Our application now looks much better, but it still doesn't do anything when users interact with it. In the next lesson, we'll implement the JavaScript functionality to handle user interactions, such as switching between tabs, generating images, and viewing the image history.

The CSS we've added serves as the visual layer of our application, complementing the structural layer (HTML) that we created in the previous lesson. In the upcoming lessons, we'll add the behavioral layer (JavaScript) to make our application fully functional.

In the practice exercises that follow, you'll have the opportunity to modify the CSS styles and experiment with different visual designs. You'll also get to see how the CSS interacts with the HTML and JavaScript to create a complete web application. This hands-on experience will help reinforce the concepts we've covered in this lesson and prepare you for the more advanced topics in the upcoming lessons.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal