Tại sao CSS vị trí Tuyệt đối không hoạt động?

Mỗi lần tôi làm việc trên một thành phần cần định vị tuyệt đối, tôi tự hỏi mình. nó có thực sự cần thiết không? . Tôi thấy điều này thú vị và tôi đã nghĩ đến việc ghi lại các trường hợp sử dụng mà tôi thường gặp phải khi làm việc trên các dự án giao diện người dùng

Trong bài viết này, tôi sẽ khám phá một số trường hợp sử dụng mà việc sử dụng định vị tuyệt đối với chúng là không thực sự cần thiết

Giới thiệu

Nếu chúng ta quay lại 5 năm trước, CSS flexbox vẫn còn mới và không thể được sử dụng với dự phòng phù hợp. Lưới CSS thậm chí không được hỗ trợ vào thời điểm đó. Cuối cùng, chúng tôi sẽ sử dụng định vị CSS để đạt được bố cục mong muốn. Tuy nhiên, một số trường hợp sử dụng này có thể được giải quyết bằng CSS flexbox hoặc grid ngày nay

Một ngày nọ, chúng tôi đang phát triển giao diện người dùng của trang đích và đối tác của tôi đã hỏi tôi về vấn đề bố cục mà cô ấy đang gặp phải. Sự cố xảy ra do

.card {
    position: relative;
    display: grid;
}

.card__content {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
5, vì vậy tôi đã can thiệp và cố gắng trợ giúp và chúng tôi đã khắc phục sự cố mà không cần sử dụng bất kỳ định vị CSS nào. Vào thời điểm đó, tôi thấy rằng mình nên ghi lại điều đó và đó là những gì tôi đang làm ngay bây giờ

Các trường hợp sử dụng và ví dụ

lớp phủ thẻ

Khi chúng tôi có một thẻ chứa văn bản trên một hình ảnh, chúng tôi thường sử dụng

.card {
    position: relative;
    display: grid;
}

.card__content {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
5 để đặt nội dung trên hình ảnh. Điều này không còn cần thiết với lưới CSS

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Đây là thẻ văn bản trên hình ảnh điển hình. Đây là HTML

 class="card">
     class="card__thumb">
        
Tại sao CSS vị trí Tuyệt đối không hoạt động?

Theo mặc định, lưới CSS sẽ tự động tạo các hàng dựa trên nội dung. Trong thẻ, chúng tôi có hai yếu tố chính và vì vậy chúng tôi có hai hàng nội dung

Để chồng chéo nội dung với hình ảnh, chúng ta cần đặt cả hai nội dung đó vào vùng lưới đầu tiên

.card__thumb,
.card__content {
    grid-column: 1/2;
    grid-row: 1/2;
}

Thậm chí tốt hơn, chúng ta có thể sử dụng tốc ký

.card__thumb,
.card__content {
    grid-column: 1/2;
    grid-row: 1/2;
}
1

.card__thumb,
.card__content {
    grid-area: 1/2;
}

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Cuối cùng, chúng ta cũng có thể sử dụng

.card__thumb,
.card__content {
    grid-column: 1/2;
    grid-row: 1/2;
}
2.
.card__thumb,
.card__content {
    grid-column: 1/2;
    grid-row: 1/2;
}
3 đại diện cho cột và hàng cuối cùng trong lưới, do đó, nó sẽ luôn kéo dài đến cuối cột hoặc hàng

thẻ thẻ

Dựa trên ví dụ trước, chúng tôi muốn mở rộng nó và bao gồm một thẻ ở khu vực trên cùng bên trái của thẻ. Để làm điều đó, chúng ta cần sử dụng kỹ thuật tương tự là

.card__thumb,
.card__content {
    grid-column: 1/2;
    grid-row: 1/2;
}
2, nhưng chúng ta không muốn thẻ lấp đầy toàn bộ thẻ, đúng không?

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Để khắc phục điều đó, chúng ta cần yêu cầu thẻ căn chỉnh và căn chỉnh chính nó ở đầu vùng chứa căn chỉnh của nó

.card__tag {
    align-self: start;
    justify-self: start;
    /* Other styles */
}

Gặp thẻ được định vị phía trên thẻ gốc của nó mà không sử dụng

.card {
    position: relative;
    display: grid;
}

.card__content {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
5

Thử nghiệm

phần anh hùng

Một trường hợp sử dụng hoàn hảo khác là phần anh hùng với nội dung chồng lên hình ảnh

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Điều này tương tự như ví dụ về thẻ, nhưng với kiểu dáng khác nhau cho chính nội dung. Trước khi đi sâu vào cách hiện đại, hãy suy nghĩ một phút về cách chúng tôi làm điều đó với định vị tuyệt đối

Chúng tôi có ba lớp

  • Hình ảnh
  • Lớp phủ dốc
  • Nội dung
Tại sao CSS vị trí Tuyệt đối không hoạt động?

Có nhiều cách khác nhau để thực hiện điều đó. Nếu hình ảnh hoàn toàn nhằm mục đích trang trí, chúng ta có thể sử dụng

.card__thumb,
.card__content {
    grid-column: 1/2;
    grid-row: 1/2;
}
6. Mặt khác, chúng ta có thể sử dụng phần tử
.card__thumb,
.card__content {
    grid-column: 1/2;
    grid-row: 1/2;
}
7

.hero {
    position: relative;
    min-height: 500px;
}

.hero__thumb {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The overlay */
.hero:after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: #000;
    opacity: 0.5;
}

.hero__content {
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 1;
    transform: translate(-50%, -50%);
    text-align: center;
}

Đó là cách chúng tôi có thể triển khai phần anh hùng bằng cách sử dụng định vị tuyệt đối. Tuy nhiên, chúng ta có thể làm tốt hơn. Hãy cùng khám phá phương pháp hiện đại

Đầu tiên, chúng ta cần thêm

.card__thumb,
.card__content {
    grid-column: 1/2;
    grid-row: 1/2;
}
0 vào phần tử anh hùng. Sau đó, chúng tôi sẽ áp dụng khái niệm tương tự như trong thành phần thẻ, đó là áp dụng
.card__thumb,
.card__content {
    grid-column: 1/2;
    grid-row: 1/2;
}
2 cho mọi mục con trực tiếp

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Thật không may, chúng tôi sẽ cần sử dụng chiều cao cố định cho phần anh hùng để

.card__thumb,
.card__content {
    grid-area: 1/2;
}
0 thực sự có thể hoạt động. (Một mục con có
.card__thumb,
.card__content {
    grid-area: 1/2;
}
1 sẽ cần cha của nó có một cố định rõ ràng là
.card__thumb,
.card__content {
    grid-area: 1/2;
}
2, không phải là
.card__thumb,
.card__content {
    grid-area: 1/2;
}
3)

.hero {
    display: grid;
    height: 500px;
}

.hero__content {
    z-index: 1; /* [1] */
    grid-area: 1/-1;
    display: flex;
    flex-direction: column;
    margin: auto; /* [2] */
    text-align: center;
}

.hero__thumb {
    grid-area: 1/-1;
    object-fit: cover; /* [3] */
    width: 100%;
    height: 100%;
    min-height: 0; /* [4] */
}

.hero:after {
    content: "";
    background-color: #000;
    opacity: 0.5;
    grid-area: 1/-1;
}

Tôi muốn xem qua các dòng mã được đánh số vì chúng rất quan trọng

  1. Chúng tôi có thể sử dụng
    .card__thumb,
    .card__content {
        grid-area: 1/2;
    }
    
    4 trên lưới hoặc vật phẩm linh hoạt. Không cần thêm
    .card__thumb,
    .card__content {
        grid-area: 1/2;
    }
    
    5 gì cả
  2. .card__thumb,
    .card__content {
        grid-area: 1/2;
    }
    
    6 là một mục lưới, sử dụng
    .card__thumb,
    .card__content {
        grid-area: 1/2;
    }
    
    7 sẽ căn giữa nó theo chiều ngang và chiều dọc
  3. Đừng quên bao gồm
    .card__thumb,
    .card__content {
        grid-area: 1/2;
    }
    
    8 khi xử lý hình ảnh
  4. Tôi đã sử dụng
    .card__thumb,
    .card__content {
        grid-area: 1/2;
    }
    
    9 trên hình ảnh chính trong trường hợp sử dụng hình ảnh lớn. Chà, điều này là để buộc lưới CSS phải tôn trọng
    .card__thumb,
    .card__content {
        grid-area: 1/2;
    }
    
    1 và tránh làm cho hình ảnh lớn hơn phần anh hùng trong trường hợp tác giả sử dụng một hình ảnh lớn. Bạn có thể đọc thêm về điều đó trong bài viết của tôi về kích thước nội dung tối thiểu trong lưới CSS

Lưu ý cách chúng tôi đã kết thúc với một giải pháp sạch hơn nhiều?

Thử nghiệm

CSS .card__tag { align-self: start; justify-self: start; /* Other styles */ } 1

Tôi nghĩ đây là trường hợp sử dụng thực tế đầu tiên cho

.card__tag {
    align-self: start;
    justify-self: start;
    /* Other styles */
}
1 mà tôi thấy hữu ích. Xem xét ví dụ sau nơi chúng tôi có nội dung và hình ảnh

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Đây là đánh dấu HTML

 class="hero">
     class="hero__content">
        

href="#">Order now
Tại sao CSS vị trí Tuyệt đối không hoạt động?

Lưu ý rằng hình ảnh hiện được chèn giữa tiêu đề và mô tả. Làm thế nào bạn có thể giải quyết vấn đề này?

 class="hero">
     class="hero__content">
        

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Trong ví dụ này, chúng tôi có một biến thể của thẻ đặt tiêu đề ở đầu thẻ. Chúng ta hãy xem đánh dấu HTML

.card {
    position: relative;
}

.card__content {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(to top, #000, rgba(0, 0, 0, 0) bottom/100% 60% no-repeat;
    padding: 1rem;
}
5

Lưu ý rằng chúng ta có hai phần tử con trực tiếp. ngón tay cái và nội dung. Với cách đánh dấu đó, làm cách nào chúng tôi có thể đặt tiêu đề

.hero {
    position: relative;
    min-height: 500px;
}

.hero__thumb {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The overlay */
.hero:after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: #000;
    opacity: 0.5;
}

.hero__content {
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 1;
    transform: translate(-50%, -50%);
    text-align: center;
}
3 ở trên cùng?

Chúng ta có thể làm điều đó với định vị tuyệt đối

.card {
    position: relative;
}

.card__content {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(to top, #000, rgba(0, 0, 0, 0) bottom/100% 60% no-repeat;
    padding: 1rem;
}
6

Tuy nhiên, giải pháp này có thể thất bại khi tiêu đề quá dài

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Điều đó xảy ra vì tiêu đề nằm ngoài quy trình bình thường, vì vậy trình duyệt không thực sự quan tâm đến độ dài hay ngắn của tiêu đề. Chúng ta có thể làm tốt hơn nhiều với

.card__tag {
    align-self: start;
    justify-self: start;
    /* Other styles */
}
1

.card {
    position: relative;
}

.card__content {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(to top, #000, rgba(0, 0, 0, 0) bottom/100% 60% no-repeat;
    padding: 1rem;
}
7

Điều này sẽ cho phép chúng tôi kiểm soát tất cả các mục con và có thể linh hoạt ghi lại chúng khi cần với thuộc tính

.hero {
    position: relative;
    min-height: 500px;
}

.hero__thumb {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The overlay */
.hero:after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: #000;
    opacity: 0.5;
}

.hero__content {
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 1;
    transform: translate(-50%, -50%);
    text-align: center;
}
5

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Chúng tôi vẫn có một vấn đề nhỏ kể từ khi chúng tôi thêm

.hero {
    position: relative;
    min-height: 500px;
}

.hero__thumb {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The overlay */
.hero:after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: #000;
    opacity: 0.5;
}

.hero__content {
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 1;
    transform: translate(-50%, -50%);
    text-align: center;
}
6 vào cấp độ gốc. Hình ảnh phải được dán vào các cạnh. Đây là cách chúng ta có thể khắc phục điều đó

.card {
    position: relative;
}

.card__content {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(to top, #000, rgba(0, 0, 0, 0) bottom/100% 60% no-repeat;
    padding: 1rem;
}
8

định tâm

Nói đến việc căn giữa, bạn sẽ thấy nhiều người đùa rằng nó khó và phức tạp. Ngày nay, việc căn giữa một phần tử trở nên dễ dàng hơn bao giờ hết

Không còn sử dụng

.card {
    position: relative;
    display: grid;
}

.card__content {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
5 với các biến đổi CSS. Ví dụ: chúng ta có thể sử dụng
.card__thumb,
.card__content {
    grid-area: 1/2;
}
7 để căn giữa một mục linh hoạt theo cả chiều ngang và chiều dọc

.card {
    position: relative;
}

.card__content {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(to top, #000, rgba(0, 0, 0, 0) bottom/100% 60% no-repeat;
    padding: 1rem;
}
9

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Tôi đã viết một hướng dẫn đầy đủ về định tâm trong CSS

Tỷ lệ khung hình ảnh

Thuộc tính CSS

.hero {
    position: relative;
    min-height: 500px;
}

.hero__thumb {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The overlay */
.hero:after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: #000;
    opacity: 0.5;
}

.hero__content {
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 1;
    transform: translate(-50%, -50%);
    text-align: center;
}
9 hiện được hỗ trợ trong tất cả các trình duyệt chính. Chúng tôi đã từng thực hiện hack đệm để buộc một hộp tôn trọng một tỷ lệ khung hình cụ thể

Đây là một ví dụ

.card {
    position: relative;
    display: grid;
}

.card__content {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
0

Với tài sản

.hero {
    position: relative;
    min-height: 500px;
}

.hero__thumb {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The overlay */
.hero:after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: #000;
    opacity: 0.5;
}

.hero__content {
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 1;
    transform: translate(-50%, -50%);
    text-align: center;
}
9 mới, mọi việc dễ dàng hơn nhiều

.card {
    position: relative;
    display: grid;
}

.card__content {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
1

Bạn có thể tìm hiểu thêm về chúng trong bài viết này bởi chính bạn

Đôi khi, sử dụng .card { position: relative; display: grid; } .card__content { display: flex; flex-direction: column; justify-content: flex-end; } 5 tốt hơn

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Trong ví dụ này, chúng tôi có nội dung (hình đại diện, tên và liên kết) trùng lặp với bìa thẻ. Chúng tôi có hai lựa chọn để thực hiện điều này

  1. Sử dụng
    .card {
        position: relative;
        display: grid;
    }
    
    .card__content {
        display: flex;
        flex-direction: column;
        justify-content: flex-end;
    }
    
    5 cho bìa thẻ
  2. Sử dụng lề âm cho nội dung

Hãy cùng khám phá các giải pháp và xem giải pháp nào phù hợp hơn cho trường hợp sử dụng đó

Sử dụng định vị tuyệt đối

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Với giải pháp này, chúng ta có thể định vị hình chữ nhật một cách tuyệt đối, sau đó thêm

.hero {
    position: relative;
    min-height: 500px;
}

.hero__thumb {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The overlay */
.hero:after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: #000;
    opacity: 0.5;
}

.hero__content {
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 1;
    transform: translate(-50%, -50%);
    text-align: center;
}
6 vào nội dung thẻ

.card {
    position: relative;
    display: grid;
}

.card__content {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
2

Bằng cách đó, khi tháo nắp thẻ, chúng tôi không phải chỉnh sửa hoặc thay đổi CSS

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Sử dụng lợi nhuận âm

Trong giải pháp này, thẻ sẽ không được định vị tuyệt đối. Thay vào đó, nội dung sẽ có lề âm từ trên xuống

.card {
    position: relative;
    display: grid;
}

.card__content {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
3

Mặc dù giải pháp này hoạt động khi có nắp thẻ, nhưng nó có thể gây ra sự cố khi chúng tôi có biến thể thẻ không có nắp thẻ

Tại sao CSS vị trí Tuyệt đối không hoạt động?

Lưu ý cách hình đại diện tắt cha mẹ của nó (Thẻ). Để khắc phục điều đó, chúng ta cần thay đổi CSS và loại bỏ lề âm

.card {
    position: relative;
    display: grid;
}

.card__content {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
4

Kết quả là, sử dụng

.card {
    position: relative;
    display: grid;
}

.card__content {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
5 hóa ra lại là một giải pháp tốt hơn trong trường hợp như vậy vì nó sẽ giúp chúng tôi không phải viết thêm CSS

Làm thế nào để vị trí tuyệt đối hoạt động CSS?

Phần tử được định vị tuyệt đối là phần tử có giá trị vị trí được tính là tuyệt đối hoặc cố định. Các thuộc tính top , right , bottom và left chỉ định độ lệch từ các cạnh của khối chứa phần tử . (Khối chứa là tổ tiên liên quan đến phần tử được định vị. )

Tại sao bạn không nên sử dụng vị trí tuyệt đối?

NẾU bạn sử dụng tất cả các thẻ div tuyệt đối bạn có thể dễ dàng đặt các thẻ của mình chồng lên nhau và ẩn lẫn nhau khi dữ liệu bên trong chúng thay đổi . Thứ hai, nhiều trang web tốt cho phép bọc thông tin tùy thuộc vào độ phân giải màn hình và kích thước trình duyệt mà người dùng sử dụng để truy cập trang web.

Định vị tuyệt đối có phải là CSS xấu không?

Không có gì sai khi sử dụng vị trí. tuyệt đối trong ví dụ trên, nhưng tại sao không sử dụng một giải pháp dễ dàng hơn? . Bước đầu tiên là thêm màn hình. lưới đến thành phần thẻ. Chúng tôi không cần đặt bất kỳ cột hoặc hàng nào.

Tôi có thể sử dụng cái gì thay vì vị trí tuyệt đối?

Chúng ta có thể sử dụng định vị tuyệt đối CSS để chồng lấp các phần tử, nhưng thay vào đó, có một số lợi thế khi sử dụng lưới CSS