Giải pháp được chấp nhận hoạt động rất tốt, nhưng IMO thiếu một lời giải thích về lý do tại sao nó hoạt động. Ví dụ dưới đây được đưa vào các khái niệm cơ bản và tách CSS quan trọng khỏi CSS kiểu dáng không liên quan. Như một phần thưởng, tôi cũng đã bao gồm một lời giải thích chi tiết về cách hoạt động của định vị CSS.
TLDR; nếu bạn chỉ muốn mã, cuộn xuống Kết quả .
Vấn đề
Có hai riêng biệt, anh chị em, các yếu tố và mục tiêu là để xác định vị trí phần tử thứ hai (với một id
số infoi
), vì vậy nó xuất hiện trong các yếu tố trước đó (một với một class
số navi
). Cấu trúc HTML không thể thay đổi.
Giải pháp đề xuất
Để đạt được kết quả mong muốn, chúng tôi sẽ di chuyển, hoặc vị trí, phần tử thứ hai, mà chúng tôi sẽ gọi #infoi
để nó xuất hiện trong phần tử đầu tiên, chúng tôi sẽ gọi .navi
. Cụ thể, chúng tôi muốn #infoi
được định vị ở góc trên bên phải .navi
.
Kiến thức CSS cần thiết
CSS có một số thuộc tính cho các yếu tố định vị. Theo mặc định, tất cả các yếu tố là position: static
. Điều này có nghĩa là phần tử sẽ được định vị theo thứ tự của nó trong cấu trúc HTML, với một vài ngoại lệ.
Khác position
giá trị relative
, absolute
, sticky
, và fixed
. Bằng cách đặt một phần tử position
thành một trong những giá trị khác, giờ đây có thể sử dụng kết hợp bốn thuộc tính sau để định vị phần tử:
Nói cách khác, bằng cách cài đặt position: absolute
, chúng ta có thể thêm top: 100px
vào vị trí phần tử 100 pixel từ đầu trang. Ngược lại, nếu chúng ta đặt bottom: 100px
thành phần sẽ được định vị 100 pixel từ cuối trang.
Đây là nơi nhiều người mới CSS bị lạc -position: absolute
có một khung tham chiếu. Trong ví dụ trên, khung tham chiếu làbody
phần tử. position: absolute
vớitop: 100px
nghĩa là phần tử được định vị 100 pixel từ đỉnh củabody
phần tử.
Khung vị trí của tham chiếu hoặc bối cảnh vị trí, có thể được thay đổi bằng cách đặt position
phần tử cha thành bất kỳ giá trị nào khácposition: static
. Đó là, chúng ta có thể tạo bối cảnh vị trí mới bằng cách đưa ra một phần tử cha:
position: relative;
position: absolute;
position: sticky;
position: fixed;
Ví dụ: nếu một <div class="parent">
phần tử được đưa ra position: relative
, bất kỳ phần tử con nào cũng sử dụng <div class="parent">
làm bối cảnh vị trí của chúng. Nếu một phần tử con được đưa ra position: absolute
và top: 100px
, phần tử đó sẽ được định vị 100 pixel từ đỉnh của <div class="parent">
phần tử, vì <div class="parent">
bây giờ là bối cảnh vị trí.
Yếu tố khác cần lưu ý là thứ tự ngăn xếp - hoặc cách các yếu tố được xếp chồng theo hướng z. Điều cần biết ở đây là thứ tự ngăn xếp của các phần tử, theo mặc định, được xác định bởi sự đảo ngược thứ tự của chúng trong cấu trúc HTML. Hãy xem xét ví dụ sau:
<body>
<div>Bottom</div>
<div>Top</div>
</body>
Trong ví dụ này, nếu hai <div>
phần tử được định vị ở cùng một vị trí trên trang, <div>Top</div>
phần tử sẽ bao phủ <div>Bottom</div>
phần tử. Vì <div>Top</div>
xuất hiện sau <div>Bottom</div>
trong cấu trúc HTML, nó có thứ tự xếp chồng cao hơn.
div {
position: absolute;
width: 50%;
height: 50%;
}
#bottom {
top: 0;
left: 0;
background-color: blue;
}
#top {
top: 25%;
left: 25%;
background-color: red;
}
<div id="bottom">Bottom</div>
<div id="top">Top</div>
Thứ tự sắp xếp có thể được thay đổi bằng CSS bằng cách sử dụng z-index
hoặc order
các thuộc tính.
Chúng ta có thể bỏ qua thứ tự sắp xếp trong vấn đề này vì cấu trúc HTML tự nhiên của các phần tử có nghĩa là phần tử mà chúng ta muốn xuất hiện xuất hiện top
sau phần tử khác.
Vì vậy, quay trở lại vấn đề trong tay - chúng tôi sẽ sử dụng bối cảnh vị trí để giải quyết vấn đề này.
Giải pháp
Như đã nêu ở trên, mục tiêu của chúng tôi là định vị #infoi
phần tử để nó xuất hiện trong .navi
phần tử. Để làm điều này, chúng tôi sẽ bọc .navi
và #infoi
các yếu tố trong một yếu tố mới <div class="wrapper">
để chúng tôi có thể tạo bối cảnh vị trí mới.
<div class="wrapper">
<div class="navi"></div>
<div id="infoi"></div>
</div>
Sau đó tạo bối cảnh vị trí mới bằng cách đưa ra .wrapper
a position: relative
.
.wrapper {
position: relative;
}
Với bối cảnh vị trí mới này, chúng ta có thể định vị #infoi
trong .wrapper
. Đầu tiên, đưa ra #infoi
một position: absolute
, cho phép chúng tôi vị trí #infoi
hoàn toàn trong .wrapper
.
Sau đó thêm top: 0
và right: 0
định vị #infoi
phần tử ở góc trên bên phải. Hãy nhớ rằng, vì #infoi
phần tử đang sử dụng .wrapper
làm bối cảnh vị trí của nó, nên nó sẽ nằm ở phía trên bên phải của .wrapper
phần tử.
#infoi {
position: absolute;
top: 0;
right: 0;
}
Bởi vì .wrapper
chỉ đơn thuần là một thùng chứa .navi
, định vị #infoi
ở góc trên bên phải .wrapper
mang lại hiệu quả của việc được định vị ở góc trên bên phải .navi
.
Và ở đó chúng tôi có nó, #infoi
bây giờ dường như ở góc trên bên phải của .navi
.
Kết quả
Ví dụ dưới đây được đưa vào những điều cơ bản và chứa một số kiểu dáng tối thiểu.
/*
* position: relative gives a new position context
*/
.wrapper {
position: relative;
}
/*
* The .navi properties are for styling only
* These properties can be changed or removed
*/
.navi {
background-color: #eaeaea;
height: 40px;
}
/*
* Position the #infoi element in the top-right
* of the .wrapper element
*/
#infoi {
position: absolute;
top: 0;
right: 0;
/*
* Styling only, the below can be changed or removed
* depending on your use case
*/
height: 20px;
padding: 10px 10px;
}
<div class="wrapper">
<div class="navi"></div>
<div id="infoi">
<img src="http://via.placeholder.com/32x20/000000/ffffff?text=?" height="20" width="32"/>
</div>
</div>
Một giải pháp thay thế (lưới)
Đây là một giải pháp thay thế sử dụng CSS Grid để định vị .navi
phần tử với #infoi
phần tử ở phía bên phải. Tôi đã sử dụng các grid
thuộc tính dài dòng để làm cho nó rõ ràng nhất có thể.
:root {
--columns: 12;
}
/*
* Setup the wrapper as a Grid element, with 12 columns, 1 row
*/
.wrapper {
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
grid-template-rows: 40px;
}
/*
* Position the .navi element to span all columns
*/
.navi {
grid-column-start: 1;
grid-column-end: span var(--columns);
grid-row-start: 1;
grid-row-end: 2;
/*
* Styling only, the below can be changed or removed
* depending on your use case
*/
background-color: #eaeaea;
}
/*
* Position the #infoi element in the last column, and center it
*/
#infoi {
grid-column-start: var(--columns);
grid-column-end: span 1;
grid-row-start: 1;
place-self: center;
}
<div class="wrapper">
<div class="navi"></div>
<div id="infoi">
<img src="http://via.placeholder.com/32x20/000000/ffffff?text=?" height="20" width="32"/>
</div>
</div>
Một giải pháp thay thế (Không có Wrapper)
Trong trường hợp chúng tôi không thể chỉnh sửa bất kỳ HTML nào, có nghĩa là chúng tôi không thể thêm phần tử trình bao bọc, chúng tôi vẫn có thể đạt được hiệu quả mong muốn.
Thay vì sử dụng position: absolute
trên #infoi
phần tử, chúng tôi sẽ sử dụng position: relative
. Điều này cho phép chúng ta định vị lại #infoi
phần tử từ vị trí mặc định bên dưới .navi
phần tử. Với position: relative
chúng ta có thể sử dụng một top
giá trị âm để di chuyển nó lên từ vị trí mặc định của nó và left
giá trị 100%
trừ đi một vài pixel, bằng cách sử dụng left: calc(100% - 52px)
, để đặt nó ở gần bên phải.
/*
* The .navi properties are for styling only
* These properties can be changed or removed
*/
.navi {
background-color: #eaeaea;
height: 40px;
width: 100%;
}
/*
* Position the #infoi element in the top-right
* of the .wrapper element
*/
#infoi {
position: relative;
display: inline-block;
top: -40px;
left: calc(100% - 52px);
/*
* Styling only, the below can be changed or removed
* depending on your use case
*/
height: 20px;
padding: 10px 10px;
}
<div class="navi"></div>
<div id="infoi">
<img src="http://via.placeholder.com/32x20/000000/ffffff?text=?" height="20" width="32"/>
</div>
overflow: hidden
,overflow: visible
thay vào đó hãy sử dụng .