الإجابة المختصرة
لتوسيط div أفقيًا وعموديًا معًا داخل أبيه، اجعل الأب شبكة grid ووسّط محتواها:
.parent {
display: grid;
place-items: center;
min-height: 200px; /* the parent needs room to center in */
}
تعمل هذه الطريقة مع أي حجم للابن ولا تحتاج إلى شيء على الابن نفسه. فيما يلي ست طرق جنبًا إلى جنب. كل صندوق يقيس نفسه بعد عرضه ويطبع بُعد مركزه عن مركز الأب:
الطرق الست كلها تعرض 0px على المحورين (حد المنصة البالغ 1px متساوٍ على كل الجوانب، فلا يزيح المركز). غيّر عرض صندوق أو نصه وشغّل المثال مرة أخرى: الطرق التي لا تعتمد على حجم ثابت تبقى عند 0.
أي طريقة تستخدم
| الطريقة | توسّط | هل يحتاج الابن إلى حجم ثابت؟ | الأنسب لـ |
|---|---|---|---|
Grid مع place-items: center | المحورين | لا | الخيار الافتراضي: ابن واحد في صندوق |
Flexbox مع justify-content وalign-items | المحورين | لا | صف أو عمود من العناصر، موسّطة كمجموعة |
margin: auto في أب flex أو grid | المحورين | لا | توسيط عنصر واحد بينما يُرتَّب إخوته بشكل مختلف |
margin: 0 auto | أفقيًا فقط | width أو max-width | حاويات الصفحات، والمقالات، والنماذج في التدفق العادي |
Absolute مع translate(-50%, -50%) | المحورين | لا | الطبقات، والشارات، والنوافذ المنبثقة فوق محتوى آخر |
Absolute مع inset: 0; margin: auto | المحورين | نعم، العرض والارتفاع | مربعات الحوار ثابتة الحجم |
align-content: center على عنصر كتلي | عموديًا | لا | التوسيط العمودي من دون تغيير display الأب |
الطريقة 1: flexbox
يوسّط flexbox على محورين بخاصيتين. تتولى justify-content المحور الرئيسي (الأفقي في الصف)، وalign-items المحور العرضي:
مع عدة أبناء يوسّطهم flexbox كمجموعة، ويبقيهم في صف. هنا يتفوق على grid، التي كانت ستكدّس العناصر الثلاثة في عمود واحد موسّط. تشرح صفحة justify-content كل قيم المحاذاة.
الطريقة 2: grid
place-items: center اختصار لـ align-items: center مع justify-items: center. على حاوية grid بابن واحد توسّط ذلك الابن في الاتجاهين:
استخدام min-height بدل height يسمح للأب بأن يكبر إن صارت البطاقة أطول من 180px، بدل أن يفيض محتوى البطاقة.
الطريقة 3: margin: 0 auto (أفقيًا)
العنصر الكتلي الذي عرضه أصغر من حاويته يمكن توسيطه أفقيًا بهوامش جانبية تلقائية. يقسم المتصفح المساحة الحرة بالتساوي بين الجانبين:
الصندوق الثاني يملأ العرض كله، فلا توجد مساحة حرة ولا يتحرك شيء. هذا هو السبب المعتاد لكون margin: 0 auto «لا تعمل». كما أنها توسّط أفقيًا فقط في التدفق العادي؛ فالهوامش العمودية auto تصبح 0 هناك. لكن داخل أب flex أو grid، توسّط margin: auto في الاتجاهين، وهو الصندوق الثالث في المقارنة أعلاه.
الطريقة 4: الموضع المطلق وtransform
حين يجب أن يقع العنصر فوق محتوى آخر (شارة على صورة، نافذة منبثقة فوق الصفحة)، ضعه بموضع مطلق عند 50% ثم اسحبه إلى الخلف بمقدار نصف حجمه:
تضع top: 50%; left: 50% الزاوية العلوية اليسرى للعنصر في المركز. والنسب المئوية في translate() تشير إلى حجم العنصر نفسه، فتعيده -50% بمقدار نصف عرضه وارتفاعه مهما كانا. يجب أن يكون الأب مُموضَعًا (position: relative)، وإلا فسيتوسط العنصر في الصفحة بدلًا من ذلك. الموضعة مشروحة في صفحة position.
نسخة للعناصر ذات الحجم المعروف: position: absolute; inset: 0; margin: auto; مع width وheight. تتقاسم الهوامش التلقائية المساحة على الجوانب الأربعة.
الطريقة 5: align-content على عنصر كتلي عادي
تعمل align-content: center الآن أيضًا على الحاويات الكتلية العادية، لا على حاويات flex وgrid فقط. توسّط المحتوى عموديًا من دون تغيير طريقة ترتيب الأبناء:
.parent {
min-height: 200px;
align-content: center; /* vertical centering, still display: block */
}
.child {
max-width: 300px;
margin-inline: auto; /* horizontal centering */
}
مدعومة في الإصدارات الحالية من Chrome وFirefox وSafari. المتصفحات الأقدم تتجاهلها، فاستخدم grid إن كان عليك دعمها.
التوسيط في الشاشة كلها
لتوسيط مربع حوار في نافذة العرض بغض النظر عن التمرير، اجمع طبقة ثابتة بملء الشاشة مع grid:
.overlay {
position: fixed;
inset: 0; /* covers the viewport */
display: grid;
place-items: center;
background: rgb(0 0 0 / 50%);
}
لتوسيط محتوى صفحة كاملة عموديًا، استخدم min-height: 100dvh على الأب بدل 100vh: على الهواتف تشمل 100vh المنطقة التي خلف أشرطة أدوات المتصفح، فيقع «المركز» منخفضًا أكثر من اللازم.
توسيط النص مهمة مختلفة
كل ما سبق يوسّط صندوقًا. لتوسيط النص داخل صندوق استخدم text-align: center عليه، كما تعرض صفحة توسيط النص في HTML. غالبًا تحتاج إلى الاثنين: grid لتوسيط البطاقة، وtext-align لتوسيط الأسطر داخلها.
أخطاء شائعة
- أب بلا ارتفاع. التوسيط العمودي يحتاج إلى مساحة حرة؛ والأب الذي يتقلص إلى محتواه لا يملك أي مساحة.
margin: 0 autoعلى عنصر كتلي بعرض كامل. أعطهwidthأوmax-widthأولًا.margin: autoللتوسيط العمودي في التدفق العادي. الهوامش العمودية التلقائية تساوي 0 هناك؛ استخدم flex أو grid.- التوسيط المطلق من دون أب مُموضَع. يتوسط العنصر في الصفحة لا في الصندوق.
align-items: centerعلى الابن. خصائص المحاذاة توضع على الأب (حاوية flex أو grid)، باستثناءmargin: autoوalign-self.text-align: centerلتوسيط عنصر كتلي. توسّط المحتوى السطري (النص، والصور، والأبناء من نوع inline-block)، لا الابن الكتلي.
الأسئلة الشائعة
كيف أوسّط div أفقيًا وعموديًا؟
اجعل الأب شبكة grid ووسّط محتواها: .parent { display: grid; place-items: center; }. ونسخة flexbox هي display: flex; justify-content: center; align-items: center;. في الحالتين يحتاج الأب إلى ارتفاع أكبر من الـ div.
كيف أوسّط div أفقيًا فقط؟
أعطه عرضًا وهوامش جانبية تلقائية: .box { width: 300px; margin: 0 auto; } (أو max-width لعنصر متجاوب). وmargin-inline: auto هي الشيء نفسه بالخصائص المنطقية.
لماذا لا يوسّط margin: 0 auto الـ div عندي؟
ليس للـ div عرض أصغر من حاويته، فلا توجد مساحة حرة لتقسيمها (العنصر الكتلي يملأ العرض كاملًا افتراضيًا). اضبط width أو max-width. كما أنها لا تفعل شيئًا على العناصر السطرية ولا توسّط عموديًا أبدًا في التدفق العادي.
لماذا لا يتوسط الـ div عموديًا؟
الأب بارتفاع محتواه فقط، فلا توجد مساحة إضافية للتوسيط فيها. أعطِ الأب ارتفاعًا (أو min-height)، ثم استخدم توسيط grid أو flexbox.
ما أسهل طريقة لتوسيط div؟
display: grid; place-items: center; على الأب: تصريحان، والمحوران، وأي حجم للابن. استخدم flexbox حين يرتّب الأب عناصر أخرى في صف أيضًا.
كيف أوسّط النص داخل div؟
استخدم text-align: center على الـ div للنص والمحتوى السطري. توسيط الـ div نفسه وتوسيط النص داخله مهمتان منفصلتان.