Skip to main content
April 1, 2026Dan Rodney/9 min read

Form Basics: Free HTML & CSS Tutorial

Master HTML Forms and CSS Styling Fundamentals

Essential Form Elements You'll Learn

Form Structure

Master the form tag and proper element organization. Learn how action attributes control form data submission.

Input Controls

Create text fields, email inputs, and buttons. Understand different input types for various data collection needs.

Accessibility Features

Implement proper label associations and screen reader compatibility. Ensure your forms work for all users.

Topics Covered in This HTML & CSS Tutorial:

The Form Tag, the Input & Label Elements, the Name & ID Attributes, the Button Element

Exercise Preview

form basics preview

Project Setup

This exercise uses the Hipstirred Form Style folder with signup.html and main.css files. Keep your browser open during development to see changes in real-time.

Exercise Overview

Forms are the backbone of user interaction on the web, enabling everything from simple newsletter signups to complex data collection systems. They're how businesses capture leads, gather customer feedback, and facilitate e-commerce transactions. In this exercise, you'll build and style a professional contact form that demonstrates modern HTML5 form practices while maintaining accessibility standards that real-world applications demand.

Getting Started: the Form Tag

Every well-structured form begins with proper setup and organization. Let's establish our working environment and implement the foundational form element that will contain all our interactive components.

  1. We'll be using a new folder of provided files for this exercise. Close any files you may have open in your code editor to avoid confusion and maintain a clean workspace.
  2. Navigate to the Desktop and go into the Class Files folder, then Web Dev Class folder, and find Hipstirred Form Style. Open the entire folder in your code editor if it supports folder-based workflows (like Visual Studio Code, Sublime Text, or Atom).
  3. Open signup.html from the Hipstirred Form Style folder.
  4. Preview the file in a browser. Between the paragraph and the footer we'll add form fields to collect the user's name and email—two of the most fundamental data points in digital marketing and customer relationship management.

    NOTE: Keep the page open in your browser as you work, so you can reload to see changes in real-time. This live preview workflow is essential for efficient front-end development.

  5. Return to signup.html in your code editor.
  6. Around line 26, wrap a form tag around the paragraph. The form element creates a boundary that defines which inputs belong together and where their data should be sent when submitted:

    <main>
       <form action="">
          <p>Fill out this form, and one of our coffee specialists will get in touch with you to figure out which coffees are best suited to your tastes. This personalized attention ensures you'll get the most our of your Hipstirred membership.</p>
       </form>
    </main>

    NOTE: The action attribute specifies the server endpoint that will process the form data when users submit. In production applications, this typically points to a backend API or server-side script. We'll leave it blank for this demonstration, but in real projects, this would connect to your data processing infrastructure.

For the form to be processed correctly, you must make sure to place all form elements inside the form tag.
This fundamental rule ensures proper form functionality and data submission.
Action Attribute Purpose

The action attribute specifies where form data goes when submitted. While left blank in this tutorial, it would typically contain a server endpoint URL in production.

Adding Name & Email Inputs to the Form

Now we'll implement the core interactive elements. The input element is remarkably versatile, offering different types optimized for various data formats. This semantic approach improves both user experience and data validation.

  1. Below the paragraph inside the form tag, add a text input field:

    <form action="">
       <p>Fill out this form, and one of our coffee specialists will get in touch with you to figure out which coffees are best suited to your tastes. This personalized attention ensures you'll get the most our of your Hipstirred membership.</p>
    
       <input type="text">
    </form>

    NOTE: The type attribute is crucial for modern web development. Different input types trigger appropriate virtual keyboards on mobile devices, enable built-in validation, and provide better accessibility. Beyond text, you can use email, tel, url, number, date, password, and many others introduced in HTML5.

  2. Save the file, return to the browser, and reload the page.

    You'll see a basic text field, but without context, users won't understand its purpose. This is where semantic labeling becomes essential for both usability and accessibility compliance.

  3. Return to signup.html in your code editor.
  4. Add a label element above the input to provide clear, accessible identification:

    <form action="">
       <p>Fill out this form, and one of our coffee specialists will get in touch with you to figure out which coffees are best suited to your tastes. This personalized attention ensures you'll get the most our of your Hipstirred membership.</p>
    
       <label>Name</label>
       <input type="text">
    </form>
  5. Save the file, return to the browser, and reload the page.
  6. The visual improvement is obvious, but click on the Name label. Nothing happens yet because we haven't established the programmatic relationship between the label and input—a critical step for accessibility compliance.
  7. Return to the code and create the proper association using for and id attributes:

    <label for="nameField">Name</label>
       <input type="text" id="nameField">
    </form>
  8. Save the file, return to the browser, and reload the page.
  9. Now click on the Name label and watch the cursor automatically focus the input field. This behavior improves usability for all users and is essential for screen reader compatibility, ensuring visually impaired users receive proper context about each form field.
  10. Return to signup.html in your code editor.
  11. Add the name attribute, which serves a different but equally important purpose:

    <input type="text" id="nameField" name="nameField">

    While the id creates the label association, the name attribute identifies the data when it's submitted to your server. Backend systems use these names as keys to access the submitted values—think of them as variable names for your form data.

    Now we'll duplicate this pattern to create an email input, demonstrating how consistent structure makes forms scalable and maintainable.

  12. Select these two lines of code:

    <label for="nameField">Name</label>
    <input type="text" id="nameField" name="nameField">
  13. Copy the code.
  14. Paste it directly underneath to create a duplicate:

    <label for="nameField">Name</label>
    <input type="text" id="nameField" name="nameField">
    
    <label for="nameField">Name</label>
    <input type="text" id="nameField" name="nameField">
  15. Modify the duplicated code to create a proper email field with unique identifiers:

    <label for="nameField">Name</label>
    <input type="text" id="nameField" name="nameField">
    
    <label for="emailField">Email</label>
    <input type="email" id="emailField" name="emailField">

    NOTE: The email input type provides significant advantages over generic text fields. Mobile devices display email-optimized keyboards with @ and . readily available, browsers can perform basic format validation, and the semantic meaning helps assistive technologies understand the expected data format.

  16. Save the file, return to the browser, and reload the page.

    • Verify that both Name and Email labels properly focus their respective fields when clicked.
    • Notice that labels and inputs currently display inline. We'll address this layout issue with CSS to create a more professional, mobile-friendly vertical arrangement.

Common Input Types Available

Text
85
Email
75
Checkbox
65
Radio
55
Date/Time
45

Creating Accessible Form Fields

1

Add Input Element

Create the input with appropriate type attribute for the data you're collecting

2

Create Label Association

Use for attribute on label and matching id on input for screen reader compatibility

3

Add Name Attribute

Include name attribute on input for proper form data processing and submission

Adding a Submit Button

Every form needs a mechanism for users to submit their data. We'll implement a button that not only handles the submission but also provides an opportunity to reinforce your brand messaging.

  1. Return to signup.html.
  2. Inside the form, below the email input, add a submit button:

    <input type="email" id="emailField" name="emailField">
    
       <button>Sign Me Up</button>
    </form>

    NOTE: We could use <input type="submit" value="Sign Me Up"> instead, and both approaches submit the form. However, the button element offers superior flexibility because it can contain HTML content—icons, emphasis, or other markup that input elements cannot accommodate. This extensibility makes buttons the preferred choice for modern web applications.

  3. Save the file, return to the browser, and reload the page. You now have a functional Sign Me Up button that will attempt to submit the form when clicked (though without a backend, nothing will actually process the data yet).

Button vs Input Submit

FeatureButton ElementInput Submit
HTML ContentCan contain HTML tagsText only via value
FlexibilityMore styling optionsLimited customization
FunctionalitySubmits form dataSubmits form data
Browser SupportUniversalUniversal
Recommended: Button element offers more flexibility for complex designs and content.

Styling the Form, Input, & Label

Raw HTML forms lack visual appeal and professional polish. Through strategic CSS application, we'll transform this basic form into a visually engaging interface that aligns with modern design standards and enhances user experience.

  1. Return to your code editor and open main.css from the Hipstirred Form Style folder.
  2. Scroll down to locate the /* form styles */ comment. This organizational approach—using comments to section CSS—becomes invaluable as stylesheets grow in complexity.
  3. Begin by establishing visual hierarchy and containment for the form with a subtle border treatment:

    /* form styles */
    form {
       border: 1px solid #e9d8c8;
       border-radius: 6px;
       padding: 5%;
    }
  4. Save the file, return to the browser, and reload signup.html. The form now has clear visual boundaries with modern rounded corners that create a contained, professional appearance.

    Next, we'll address the layout flow by converting inline elements to block-level display, creating the vertical stacking that users expect from modern forms.

  5. Return to main.css in your code editor.
  6. Add a rule that applies block display to both labels and inputs:

    label, input {
       display: block;
    }

    NOTE: This selector applies identical styling to multiple elements efficiently. The comma separator creates a group selector, reducing CSS redundancy and ensuring consistent treatment across related elements.

  7. Save the file, return to the browser, and reload signup.html. The form elements now stack vertically, but we need to address typography and spacing inconsistencies.
  8. Test the current state by typing in the input fields:

    • The text appears small and cramped against the input borders
    • The font family doesn't match the site's typography system
    • The submit button suffers from the same font inconsistency

    These details significantly impact perceived quality and brand cohesion.

  9. Return to main.css in your code editor.
  10. Establish consistent typography across interactive elements:

    input, button {
       font-family: 'Abel', sans-serif;
       font-size: 19px;
    }
  11. Now enhance the input fields with proper sizing, spacing, and visual refinement:

    input {
       width: 90%;
       padding: 10px;
       margin-top: 5px;
       margin-bottom: 30px;
       border: 1px solid #e9d8c8;
       border-radius: 6px;
    }

    This styling creates generous touch targets for mobile users, provides comfortable reading space with internal padding, and maintains visual consistency with the form's border treatment.

  12. Save the file, return to the browser, and reload signup.html.
  13. Test the improvements by interacting with the form:

    • Typography now maintains consistency across the entire interface
    • Adequate padding improves both readability and usability
    • Wider fields accommodate longer entries without horizontal scrolling
    • Proper spacing creates visual rhythm and reduces cognitive load

    These enhancements transform the form from a basic HTML structure into a polished, professional interface component.

Display Block for Stacking

Labels and inputs are inline by default. Setting display: block makes them stack vertically, creating better form layout and readability.

Key CSS Properties Applied

Border and Padding

Creates visual separation with 1px solid border and 5% padding. Border-radius adds modern rounded corners.

Typography Consistency

Abel font family and 19px font size ensure form elements match the overall page design.

Spacing and Layout

Margin-bottom of 30px separates fields. Width of 90% and padding of 10px improve usability.

Styling the Button

Buttons are critical conversion elements that deserve special attention. We'll leverage existing CSS classes to maintain design consistency while addressing browser-specific styling inconsistencies that can undermine the user experience.

  1. Return to your code editor and switch to signup.html.
  2. Apply the existing button class to maintain design system consistency:

    <button class="button">Sign Me Up</button>
  3. Save the file, return to the browser, and reload signup.html.

    Examine the button carefully and you'll likely notice browser default styling artifacts:

    • Unwanted borders that vary across different browsers
    • Focus outlines that may appear jarring or inconsistent
    • Missing pointer cursor on hover, reducing perceived interactivity

    These browser inconsistencies require explicit CSS overrides to ensure consistent experience across all platforms.

  4. Return to your code editor and switch to main.css.
  5. Add targeted CSS to normalize button appearance across browsers:

    button {
       border: 0;
       outline: none;
       cursor: pointer;
    }

    These declarations remove default browser styling and establish consistent interactive behavior that users expect from modern web applications.

  6. Save the file.
  7. Return to the browser to reload signup.html and test your completed, professionally styled form.

    NOTE: To make this form fully functional requires server-side processing using technologies like Node.js, Python, PHP, or serverless functions (AWS Lambda, Netlify Functions, etc.). Modern development often involves connecting forms to services like Formspree, Netlify Forms, or custom API endpoints that handle data processing, validation, and storage. This backend integration is essential for production applications but beyond the scope of front-end styling and structure.

Button Styling Improvements

0/4
Backend Processing Required

This tutorial covers frontend form creation only. Making forms functional requires backend technologies like PHP, Node.js, or Ruby on Rails for data processing.

Key Takeaways

1Form elements must be wrapped within form tags with proper action attributes for correct data submission
2Label elements should use for attributes that match input id attributes to ensure accessibility and screen reader compatibility
3Input type attributes determine the appropriate control type, with email inputs providing enhanced mobile keyboard layouts
4The name attribute on inputs is essential for backend form processing and data identification
5Setting display: block on labels and inputs creates vertical stacking instead of default inline layout
6Consistent typography and spacing using font-family, padding, and margin properties improve form usability
7Button elements offer more flexibility than input type submit for complex styling and HTML content
8Cross-browser compatibility requires resetting default browser styles with border, outline, and cursor properties

RELATED ARTICLES