Căn giữa văn bản (text) trong CSS

Căn giữa văn bản (text) có lẽ là phần căn giữa cơ bản nhất, và cũng dễ làm hơn cả (có vẻ không phải thực sự là nó dễ hơn cái khác, khả năng cao hơn là vì chúng ta phải thao tác với văn bản nhiều mà thôi).

Hôm nay tôi và các bạn sẽ đi vào thực hành căn văn bản trong nhiều hình thức khác nhau, để xem cụ thể thì chúng sẽ như thế nào, dù chúng ta đều biết rằng câu lệnh cơ bản để làm điều đó là text-align: center.


Căn giữa văn bản thuần túy

Tức là văn bản không bao trong các thẻ hay gặp như p, a, h, li (trong ol, ul), hay ít gặp hơn như button, input, submit.

Ví dụ về văn bản thuần được bao bởi thẻ div:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; text-align:center; }
        </style>    
    </head>
    <body>
        <div id="bigBox">Văn bản tôi cần căn giữa</div>
    </body>
</html>

Kết quả: văn bản căn giữa, và bám vào mép trên của thẻ div, không có lề.

Nếu chiều cao của thẻ div không được quy định thì nó vẫn căn giữa được, và lúc này div lấy chiều cao là chiều cao văn bản. Kết quả tương tự nếu để heightauto.

Nếu div để là inline-block (display mặc định của div là block), văn bản vẫn căn giữa bình thường.


Căn giữa văn bản trong thẻ p

Thẻ p là thẻ phổ biến để đánh dấu văn bản, nó là thẻ để chỉ các đoạn (paragraph), ví dụ dòng bạn đang đọc đây cũng được đánh dấu bằng thẻ p. Bản thân thẻ p có display mặc định là block.

Ví dụ về thẻ p bao văn bản, và p nằm trong div:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; text-align:center; }
        </style>    
    </head>
    <body>
        <div id="bigBox"><p>Văn bản tôi cần căn giữa</p></div>
    </body>
</html>

Kết quả: văn bản căn giữa, và có margin giữa nó và mép trên của thẻ div chứ không dính sát liền như văn bản thuần túy, điều đó là vì thẻ p có thiết lập margin mặc định.

Bản thân thẻ p cũng tự căn nó được mà không cần thông qua div, cũng bằng câu lệnh text-align: center;

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; }
            p {text-align:center; }
        </style>    
    </head>
    <body>
        <div id="bigBox"><p>Văn bản tôi cần căn giữa</p></div>
    </body>
</html>

Cũng có thể căn giữa thẻ p bằng câu lệnh margin: 0 auto; 0 có thể thay bằng số khác để tạo lề giữa các thẻ p. Tuy nhiên căn theo cách này p cần phải được chỉ định chiều rộng width, và nó căn là căn bản thân hộp p với width tương ứng đó, nếu văn bản đủ dài hơn chiều rộng của p thì nó mới căn giữa luôn được văn bản, cái này văn bản căn giữa theo kiểu “ăn theo” p mà thôi.

Ví dụ:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; }
            p {margin: 15px auto; width:150px; font-size:16px; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <p>Văn bản tôi cần căn giữa</p>
            <p>Văn bản tôi cần căn giữa 2</p>
            <p>Văn bản tôi cần căn giữa 345</p>
            <p>Văn bản tôi cần căn giữa 45678</p>
            <p>Văn bản tôi cần căn giữa 567891011</p>
        </div>
    </body>
</html>

Khi width của p dài hơn văn bản, bản thân box p được căn giữa, nhưng văn bản bên trong nó thì bám vào lề trái của p, và thực tế văn bản không ở chính giữa, ví dụ:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; }
            p {margin: 15px auto; width:250px; font-size:16px; border:1px solid green; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <p>Văn bản tôi cần căn giữa</p>
            <p>Văn bản tôi cần căn giữa 2</p>
            <p>Văn bản tôi cần căn giữa 345</p>
            <p>Văn bản tôi cần căn giữa 45678</p>
            <p>Văn bản tôi cần căn giữa 567891011</p>
        </div>
    </body>
</html>

Căn giữa văn bản trong thẻ h (từ h1 đến h6)

Thẻ h thường được dùng để tạo tiêu đề, từ h1 cho đến h6. Ví dụ tiêu đề của website, tiêu đề của bài, tiêu đề của các mục chính trong bài viết, vân vân. Bản thân thẻ h có display mặc định là block.

Các thẻ h có hành vi giống hệt thẻ p trong chuyện căn giữa. Tức là nó cũng tự căn được, hoặc căn qua thẻ cha bằng text-align.

Ví dụ:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; }
            h2 {text-align:center; }
            
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <h2>Văn bản tôi cần căn giữa</h2>
            <h2>Văn bản tôi cần căn giữa 2</h2>
            <h2>Văn bản tôi cần căn giữa 345</h2>
            <h2>Văn bản tôi cần căn giữa 45678</h2>
            <h2>Văn bản tôi cần căn giữa 567891011</h2>
        </div>
    </body>
</html>

Căn không tiêu chuẩn theo kiểu margin: 0 auto

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; }
            h2 {margin: 15px auto; width:250px; font-size:16px; border:1px solid green; }
            
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <h2>Văn bản tôi cần căn giữa</h2>
            <h2>Văn bản tôi cần căn giữa 2</h2>
            <h2>Văn bản tôi cần căn giữa 345</h2>
            <h2>Văn bản tôi cần căn giữa 45678</h2>
            <h2>Văn bản tôi cần căn giữa 567891011</h2>
        </div>
    </body>
</html>

Sự giống nhau này có lẽ bắt nguồn từ chuyện 2 thẻ có cùng kiểu display.


Căn giữa văn bản trong thẻ a

Thẻ a là thẻ dùng để tạo liên kết, nó là một trong các thẻ rất thường gặp, đặc biệt trên các trang có số lượng bài viết lớn- khi đó liên kết nội bộ sẽ dày.

Trên nhiều website nó chỉ kém thẻ p về độ phổ biến, và thường là hơn thẻ h. Display mặc định của thẻ a là inline.

Nếu là dạng một liên kết đứng độc lập, nó sẽ căn giữa và bám vào lề trên của box div, không có lề, hành vi này giống với văn bản thuần. Ví dụ:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; text-align:center; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <a href="https://kiencang.net/category/html/">Link HTML</a>
        </div>
    </body>
</html>

Vì display của thẻ a là inline nên các thuộc tính margin (lề), padding (đệm) sẽ không hoạt động. Ví dụ dưới đây không cho thấy thẻ xuất hiện đệm và lề:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; text-align:center; }
            a {margin-top:25px; padding-top:20px; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <a href="https://kiencang.net/category/html/">Link HTML</a>
        </div>
    </body>
</html>

Muốn lề, đệm hoạt động, bạn cần chuyển display của a về inline-block hoặc block. Ví dụ:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
           div#bigBox {width:600px; height:300px; border:1px solid black; text-align:center; }

           a {margin-top:25px; padding-top:20px; display:inline-block; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <a href="https://kiencang.net/category/html/">Link HTML</a>
        </div>
    </body>
</html>

Thẻ a vẫn căn giữa khi chuyển display sang inline-block hoặc block.


Không giống thể h và thẻ p, thẻ a không thể tự mình căn giữa nó bằng text-align, nếu nó không thay đổi trạng thái display mặc định, ví dụ câu lệnh dưới đây sẽ không hoạt động:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; }
            a {text-align:center; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <a href="https://kiencang.net/category/html/">Link HTML</a>   
        </div>
    </body>
</html>

Khi a chuyển thành block, nó sẽ tự căn được chính nó:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; }
            a {text-align:center; display: block;}
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <a href="https://kiencang.net/category/html/">Link HTML</a>   
        </div>
    </body>
</html>

Khi có nhiều thẻ a liên tiếp, trong mã dù bạn có xuống dòng thì chúng vẫn hiển thị cạnh nhau vì nó là inline, điều này không giống với thẻ p và thẻ h vốn là block.

Trường hợp có nhiều thẻ a:

Việc căn giữa vẫn diễn ra bình thường với câu lệnh text-align cho nhiều thẻ a, ví dụ:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; text-align:center; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <a href="https://kiencang.net/category/html/">Link HTML</a>
            <a href="https://kiencang.net/category/css/">Link CSS</a>
            <a href="https://kiencang.net/category/speed-js/">Link JS</a>    
        </div>
    </body>
</html>

Nếu bạn muốn nó ngắt dòng, và vẫn căn giữa thì thẻ a cần chuyển thuộc tính display về block, ví dụ:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; text-align:center; }
            a {display:block; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <a href="https://kiencang.net/category/html/">Link HTML</a>
            <a href="https://kiencang.net/category/css/">Link CSS</a>
            <a href="https://kiencang.net/category/speed-js/">Link JS</a>    
        </div>
    </body>
</html>

Chuyển về inline-block không làm nó ngắt dòng được.

Nếu bạn muốn nó có lề thì thêm thuộc tính margin vào nữa:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; text-align:center; }

            a {display:block; margin-top:15px; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <a href="https://kiencang.net/category/html/">Link HTML</a>
            <a href="https://kiencang.net/category/css/">Link CSS</a>
            <a href="https://kiencang.net/category/speed-js/">Link JS</a>    
        </div>
    </body>
</html>

Có một cách ngắt dòng khác mà không cần thay đổi thuộc tính display của a, đó là thêm thẻ br vào, nhưng cách này không tiện lắm, đặc biệt khi chúng ta có nhiều thẻ a, nó sẽ làm mã dài thêm đáng kể:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; text-align:center; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
            <a href="https://kiencang.net/category/html/">Link HTML</a><br>
            <a href="https://kiencang.net/category/css/">Link CSS</a><br>
            <a href="https://kiencang.net/category/speed-js/">Link JS</a>   
        </div>
    </body>
</html>

Căn giữa văn bản trong thẻ li

Thẻ li nằm trong thẻ ul (danh sách dạng chấm tròn) hoặc ol (danh sách dạng số), nó là thẻ dùng để định dạng dữ liệu kiểu liệt kê không có thứ tự (ul) hoặc có thứ tự (ol).

Đây là một dạng thẻ tương đối phổ biến khi trình bày văn bản. Việc căn giữa nó cũng dễ dàng thông qua lệnh text-align, nếu bạn muốn loại bỏ chấm tròn mặc định thì chỉ cần thêm lệnh ul {list-style-type: none;}, ví dụ:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; text-align:center; }
            ul {list-style-type: none; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
           <ul>  
               <li>Link HTML</li>
               <li>Link CSS</li>
               <li>Link JS</li>
           </ul>   
        </div>
    </body>
</html>

Một trường hợp phổ biến khác là thẻ li bao ngoài thẻ a, kết quả của câu lệnh trên vẫn không thay đổi.


Thẻ ul li. ol li có tự căn giữa được không? Tôi đoán là có vì nó là dạng block như thẻ p và thẻ h, kết quả quả đúng như vậy, ul, ol tự căn giữa được:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; }
            ul {list-style-type:none; text-align:center; }
            ol {list-style-type:none; text-align:center; }
            
        </style>    
    </head>
    <body>
        <div id="bigBox">
           <ul>  
               <li>Link HTML</li>
               <li>Link CSS</li>
               <li>Link JS</li>
           </ul>
           
           <ol>  
               <li>PHP</li>
               <li>Python</li>
               <li>C++</li>
           </ol> 
        </div>
    </body>
</html>

Câu lệnh CSS sau cho kết quả tương tự, dùng li để căn giữa cho cả ul li và ol li thay vì phải viết riêng tứng cái:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; }
            ul {list-style-type: none; }
            ol {list-style-type: none; }
            li {text-align:center; }
            
        </style>    
    </head>
    <body>
        <div id="bigBox">
           <ul>  
               <li>Link HTML</li>
               <li>Link CSS</li>
               <li>Link JS</li>
           </ul>
           
           <ol>  
               <li>PHP</li>
               <li>Python</li>
               <li>C++</li>
           </ol> 
        </div>
    </body>
</html>

Căn giữa văn bản trong thẻ span

Trong HTML thẻ span được dùng để đánh dấu văn bản, display mặc định của nó là inline. Ngoài ra thì nó không có giá trị CSS mặc định nào khác như của các thẻ đánh dấu văn bản thường gặp.

W3Schools có ví nó giống với div dành riêng cho văn bản, khác là mặc định div có display là block.

Vì tính chất “tinh khiết” trong việc là thẻ đánh dấu, nên khi bạn sử dụng thẻ này mà không chỉ thị gì thêm, nó hệt như là không dùng, ví dụ:

<!DOCTYPE html>
<html>
    <head>
        <title>căn giữa văn bản</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            div#bigBox {width:600px; height:300px; border:1px solid black; }
        </style>    
    </head>
    <body>
        <div id="bigBox">
                <span>Văn bản này nằm trong thẻ span</span>
        </div>
    </body>
</html>

Bạn có thể căn giữa văn bản trong thẻ span bằng cách:

  • Để text-align của thẻ cha là center;
  • Hoặc để span căn giữa chính nó cũng bằng text-align:center nhưng bổ sung thêm thuộc tính display: block; Cụ thể: span {text-align:center; display:block;}
  • Căn giữa không tiêu chuẩn bằng chỉ thị margin: 0 auto; ví dụ: span {margin: 0 auto; width:100px; display:block;}
  • Căn bằng margin cũng giống các trường hợp khác, bạn cần thiết lập width cho thẻ đó, và cần chỉnh lại display, nếu display mặc định khác block;

Nút bấm dạng button hoặc submit

Nút bấm rất phổ biến trong các form như tìm kiếm, gửi bình luận, và dù ít khi xuất hiện, thẻ này rất hay cần điều chỉnh vị trí, và một trong các vị trí quan trọng của nó là căn giữa.

Với form chúng ta sẽ có nhiều điều để nói, vì việc căn của nút bấm cũng thường hay liên đới đến căn các thẻ input sao cho thuận mắt.

Tôi sẽ viết một bài riêng về căn giữa form sẽ phù hợp hơn.


Tổng kết

Căn giữa văn bản thường được thực hiện với câu lệnh CSS text-align:center với bộ chọn (selector) là thẻ cha (parent- tức thẻ bao bên ngoài văn bản thuần, a, h, p, ul li, ol li).

Ngoài ra, ngoại trừ thẻ a, các thẻ còn lại có khả năng tự căn giữa chính nó mà không cần phải thay đổi thuộc tính display.

Căn giữa bằng margin: 0 auto với văn bản không phải là cách căn giữa thực sự chuẩn xác, mặc dù về vị trí nó cũng ở giữa, nhưng nó sẽ căn không đều hai bên. Vì về bản chất đây là căn giữa box của thẻ a, h, p, ul li, ol li chứa văn bản, do đó khi văn bản không chiếm đủ độ dài của box, việc căn sẽ lệch. Tuy nhiên nếu đủ dài chúng ta có thể coi đây cũng là một hình thức căn giữa không tiêu chuẩn, và có thể hữu dụng trong một số trường hợp.


Xin chào và hẹn gặp lại các bạn trong bài viết khác.

Leave a Comment