طراحی وب با HTML و CSS فهرست مطالب
فصل ۱۰

فرم‌ها

تا اینجا صفحه‌هایمان تنها چیزی به کاربر نشان می‌دادند. فرم اولین جایی است که کاربر هم می‌تواند چیزی به ما بدهد.

در این فصل با این مباحث آشنا می‌شوید
  1. ساختار فرم و input
  2. برچسب و انواع input
  3. جعبه متن و فهرست کشویی
  4. تیک و دکمه رادیویی
  5. دکمه
  6. استایل دادن به فرم
  7. مثال نهایی و فرم جست‌وجو

۱. ساختار فرم و input

<form>
    <input type="text" name="fullname" placeholder="نام و نام خانوادگی">
    <input type="text" name="city" placeholder="شهر">
</form>

فرم ساده: نمونه 01-form-basic-input

شرح مثال

فرم و سرور

تگ form دو ویژگی مهم دیگر هم دارد: action که آدرس برنامه‌ای روی سرور است که فرم را دریافت می‌کند، و method که روش ارسال را مشخص می‌کند. چون در این دوره سرور نداریم، فرم‌های ما داده را واقعاً جایی نمی‌فرستند. ما تنها ظاهر و ساختار فرم را می‌سازیم. کار سرور مربوط به برنامه‌نویسی بک‌اند است که در فصل پانزدهم درباره‌اش صحبت می‌کنیم.

۲. برچسب و انواع input

<form>
    <label for="email">ایمیل</label>
    <input type="email" id="email" name="email">

    <label for="pass">رمز عبور</label>
    <input type="password" id="pass" name="pass">

    <label for="age">سن</label>
    <input type="number" id="age" name="age" min="10" max="99">

    <label for="birth">تاریخ تولد</label>
    <input type="date" id="birth" name="birth">

    <label for="phone">شماره تماس</label>
    <input type="tel" id="phone" name="phone" required>
</form>

برچسب و انواع: نمونه 02-label-and-input-types

شرح مثال

label برچسب هر فیلد است. ویژگی for آن باید دقیقاً برابر id فیلد مربوطه باشد. با این کار برچسب و فیلد به هم وصل می‌شوند و دو فایده مهم دارد:

  1. کاربر می‌تواند روی متن برچسب کلیک کند و نشانگر داخل فیلد برود. این روی موبایل که هدف‌ها کوچک‌اند، بسیار مهم است.
  2. صفحه‌خوان‌ها می‌فهمند این جعبه ورودی برای چیست. بدون label، کاربر نابینا تنها می‌شنود «جعبه متن» و نمی‌داند چه باید بنویسد.

انواع پرکاربرد type:

مقدارنتیجه
textمتن ساده یک‌خطی
emailمرورگر بررسی می‌کند علامت اَت داشته باشد
passwordحروف به شکل نقطه نمایش داده می‌شوند
numberتنها عدد. با min و max محدود می‌شود.
dateتقویم بازشو
telشماره تلفن. روی موبایل صفحه‌کلید عددی باز می‌شود.
fileانتخاب فایل از کامپیوتر

ویژگی required هم مقدار نمی‌گیرد و تنها نوشتنش کافی است. یعنی «این فیلد اجباری است» و مرورگر تا وقتی پر نشود اجازه ارسال نمی‌دهد.

چرا type درست مهم است

نوشتن type="text" برای همه چیز کار می‌کند، اما نوع درست دو مزیت رایگان می‌دهد: مرورگر خودش ورودی را بررسی می‌کند، و روی موبایل صفحه‌کلید مناسب باز می‌شود. برای فیلد شماره، صفحه‌کلید عددی و برای ایمیل، صفحه‌کلیدی که علامت اَت را جلوی چشم کاربر می‌گذارد.

۳. جعبه متن و فهرست کشویی

<label for="msg">پیام شما</label>
<textarea id="msg" name="msg" rows="5" placeholder="متن پیام..."></textarea>

<label for="city">شهر</label>
<select id="city" name="city">
    <option value="">انتخاب کنید</option>
    <option value="tehran">تهران</option>
    <option value="rasht" selected>رشت</option>
    <option value="tabriz">تبریز</option>
</select>

جعبه متن و کشویی: نمونه 03-textarea-select

شرح مثال

textarea برای متن‌های چندخطی است. برخلاف input، این تگ تگ بسته دارد و متن پیش‌فرضش بین دو تگ نوشته می‌شود، نه در ویژگی value. اگر می‌خواهید خالی باشد، حتماً دو تگ را بدون فاصله بچسبانید، وگرنه آن فاصله‌ها به عنوان متن اولیه داخل جعبه می‌نشینند. rows ارتفاع اولیه را بر حسب تعداد خط تعیین می‌کند.

select فهرست کشویی می‌سازد و هر گزینه‌اش یک option است. ویژگی value آن چیزی است که به سرور می‌رود و متن بین دو تگ، آن چیزی است که کاربر می‌بیند. این دو معمولاً فرق دارند: کاربر «رشت» می‌بیند و سرور rasht دریافت می‌کند.

ویژگی selected روی یک گزینه، آن را از ابتدا انتخاب‌شده می‌کند. گزینه اول با value خالی هم ترفند رایجی است تا کاربر مجبور شود آگاهانه انتخاب کند.

۴. تیک و دکمه رادیویی

<p>علاقه‌مندی‌ها (چند گزینه)</p>

<input type="checkbox" id="web" name="interest" value="web">
<label for="web">طراحی وب</label>

<input type="checkbox" id="net" name="interest" value="net" checked>
<label for="net">شبکه</label>

<p>جنسیت (یک گزینه)</p>

<input type="radio" id="male" name="gender" value="male">
<label for="male">آقا</label>

<input type="radio" id="female" name="gender" value="female">
<label for="female">خانم</label>

تیک و رادیویی: نمونه 04-checkbox-radio

شرح مثال

تفاوت این دو در تعداد انتخاب است:

مهم‌ترین قانون دکمه‌های رادیویی

دکمه‌های رادیویی که باید با هم یک گروه باشند، باید دقیقاً یک نام یکسان در ویژگی name داشته باشند. اگر نامشان فرق کند، هر کدام گروه جداگانه‌ای می‌شوند و کاربر می‌تواند همه را با هم انتخاب کند. برعکس، id هر کدام باید متفاوت باشد، چون برچسبشان با همان id به آنها وصل می‌شود.

ویژگی checked هم مانند required مقدار نمی‌گیرد و گزینه را از ابتدا انتخاب‌شده می‌کند.

۵. دکمه

<button type="submit">ارسال فرم</button>

<button type="reset">پاک کردن</button>

<button type="button">یک دکمه معمولی</button>

<input type="submit" value="ارسال">

دکمه: نمونه 05-button

شرح مثال

مقدار typeرفتار
submitفرم را ارسال می‌کند. پیش‌فرض داخل فرم همین است.
resetهمه فیلدها را خالی می‌کند.
buttonهیچ کاری نمی‌کند مگر با جاوااسکریپت به آن کاری بدهیم.

دو روش ساخت دکمه داریم: تگ button و input type="submit". تگ button بهتر است چون تگ بسته دارد و می‌شود داخلش هر چیزی گذاشت، حتی آیکون یا متن پررنگ. در input تنها متن ساده در ویژگی value ممکن است.

دکمه reset را کم استفاده کنید

کاربری که فرم بلندی را پر کرده و اشتباهی روی «پاک کردن» می‌زند، همه چیز را از دست می‌دهد. بیشتر سایت‌های حرفه‌ای امروز اصلاً دکمه reset ندارند.

۶. استایل دادن به فرم

اجزای فرم ظاهر پیش‌فرض زشتی دارند و از همه بدتر، قلمشان را از صفحه به ارث نمی‌برند. باید حتماً دستی تنظیمشان کنیم.

input, textarea, select, button {
    font-family: Tahoma, sans-serif;    /* حتماً لازم است */
    font-size: 15px;
}

input[type="text"],
input[type="email"],
input[type="password"],
textarea,
select {
    width: 100%;
    padding: 12px 15px;
    border: 1px solid #cccccc;
    border-radius: 8px;
    margin-bottom: 18px;
}

input:focus,
textarea:focus,
select:focus {
    outline: none;
    border-color: #2f4f4f;
}

label {
    display: block;
    margin-bottom: 6px;
    color: #2f4f4f;
    font-weight: bold;
}

button {
    background-color: #2f4f4f;
    color: white;
    border: none;
    padding: 14px 30px;
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 0.3s;
}

button:hover {
    background-color: #ff6347;
}

textarea {
    resize: vertical;
}

استایل فرم: نمونه 06-form-styling-css

شرح مثال

درباره outline: none

outline آن خط آبی است که مرورگر دور فیلد فعال می‌کشد. برداشتنش زیباتر است، اما تنها در صورتی مجاز است که چیز دیگری جایش بگذارید، مانند تغییر رنگ حاشیه در همین مثال. اگر آن را بردارید و جایگزینی نگذارید، کسی که با کلید Tab در فرم حرکت می‌کند اصلاً نمی‌فهمد کجاست.

۷. مثال نهایی و فرم جست‌وجو

<div class="form-box">
    <h2>فرم تماس با ما</h2>

    <form>
        <label for="name">نام و نام خانوادگی</label>
        <input type="text" id="name" name="name" placeholder="مثلاً سارا احمدی" required>

        <label for="email">ایمیل</label>
        <input type="email" id="email" name="email" placeholder="name@example.com" required>

        <label for="subject">موضوع</label>
        <select id="subject" name="subject">
            <option value="">انتخاب کنید</option>
            <option value="signup">ثبت‌نام</option>
            <option value="support">پشتیبانی</option>
        </select>

        <label for="message">پیام</label>
        <textarea id="message" name="message" rows="5"></textarea>

        <div class="check-row">
            <input type="checkbox" id="rules" name="rules">
            <label for="rules">قوانین سایت را می‌پذیرم</label>
        </div>

        <button type="submit">ارسال پیام</button>
    </form>
</div>

<form class="search-form">
    <input type="search" name="q" placeholder="جست‌وجو در سایت...">
    <button type="submit">بگرد</button>
</form>
.form-box {
    max-width: 550px;
    margin: 40px auto;
    background-color: white;
    padding: 35px;
    border-radius: 12px;
}

.form-box h2 {
    color: #2f4f4f;
    margin-bottom: 25px;
    text-align: center;
}

/* ردیف تیک: برچسب باید کنار تیک بماند، نه زیرش */
.check-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 20px;
}

.check-row label {
    display: inline;
    margin-bottom: 0;
    font-weight: normal;
}

button {
    width: 100%;
}

/* فرم جست‌وجو: فیلد و دکمه در یک خط */
.search-form {
    display: flex;
    gap: 8px;
    max-width: 450px;
    margin: 0 auto;
}

.search-form input {
    flex-grow: 1;
    margin-bottom: 0;
}

.search-form button {
    width: auto;
    flex-shrink: 0;
}

مثال نهایی: نمونه‌های 07-final-example و 08-search

شرح مثال

در این فرم دو مشکل رایج و راه‌حلشان را می‌بینید:

مشکل اول: برچسب تیک. قانون کلی ما display: block روی همه برچسب‌ها بود، که برای برچسب بالای فیلد درست است. اما برچسب یک تیک باید کنارش بماند. راه‌حل، پیچیدن آن دو در یک div با display: flex و بازگرداندن برچسب به حالت درون‌خطی است. این دقیقاً همان الگوی «قانون کلی، سپس استثنا» است که در فصل هشتم دیدیم.

مشکل دوم: فرم جست‌وجو. فیلد و دکمه باید در یک خط باشند و فیلد باید تمام فضای باقی‌مانده را بگیرد. این دقیقاً کاری است که فلکس‌باکس در فصل هشتم به ما یاد داد: flex-grow: 1 روی فیلد و flex-shrink: 0 روی دکمه تا هرگز فشرده نشود. توجه کنید که width: 100% و margin-bottom عمومی را هم باید برای این حالت خنثی کنیم.

این نکته را در ذهن نگه دارید: از فصل هفتم به بعد، هر مشکل چیدمانی که پیش می‌آید، اول با فلکس‌باکس امتحانش کنید.

فایل‌های تمرینی این فصل

پوشه 10-forms شامل نمونه‌های 01-form-basic-input تا 07-final-example، به‌علاوه 08-search.

خلاصه فصل

تگ یا ویژگیکارش
<form>ظرف کل فرم
<input type="...">فیلد ورودی، بسته به نوع
<label for="...">برچسب، وصل به id فیلد
<textarea>متن چندخطی. تگ بسته دارد.
<select> و <option>فهرست کشویی
type="checkbox"چند انتخاب
type="radio"یک انتخاب. نام گروه یکسان.
<button type="submit">ارسال فرم
placeholderمتن راهنمای داخل فیلد
requiredپر کردن اجباری
input:focusحالت فعال بودن فیلد
input[type="text"]انتخابگر بر اساس ویژگی

تمرین‌های فصل ده

  1. یک فرم ثبت‌نام کامل بسازید: نام، ایمیل، رمز، تاریخ تولد، شهر و پذیرش قوانین.
  2. سه دکمه رادیویی برای انتخاب رشته تحصیلی بگذارید و مطمئن شوید تنها یکی قابل انتخاب است.
  3. عمداً نام دو دکمه رادیویی را متفاوت بگذارید و ببینید چه اتفاقی می‌افتد.
  4. روی هر فیلد یک استایل focus: بگذارید که رنگ حاشیه‌اش را عوض کند.
  5. قانون قلم را از فایل CSS حذف کنید و ببینید فیلدها چقدر بد می‌شوند.
  6. یک فرم جست‌وجو بسازید که فیلد و دکمه‌اش با فلکس‌باکس در یک خط باشند.
فصل قبل: موقعیت‌دهی فصل بعد: گرید