Solusi yang diterima bekerja dengan baik, tetapi IMO tidak memiliki penjelasan mengapa itu bekerja. Contoh di bawah ini diringkas menjadi dasar-dasar dan memisahkan CSS penting dari CSS styling yang tidak relevan. Sebagai bonus, saya juga menyertakan penjelasan terperinci tentang cara kerja pemosisian CSS.
TLDR; jika Anda hanya menginginkan kode, gulir ke bawah ke Hasil .
Masalah
Ada dua terpisah, saudara, unsur-unsur dan tujuannya adalah untuk posisi elemen kedua (dengan iddari infoi), agar muncul dalam elemen sebelumnya (yang dengan classdarinavi ). Struktur HTML tidak dapat diubah.
Solusi yang Diusulkan
Untuk mencapai hasil yang diinginkan, kita akan memindahkan, atau memposisikan, elemen kedua, yang akan kita panggil #infoisehingga muncul di dalam elemen pertama, yang akan kita panggil .navi. Secara khusus, kami ingin #infoidiposisikan di sudut kanan atas.navi .
Pengetahuan yang Diperlukan Posisi CSS
CSS memiliki beberapa properti untuk elemen penentuan posisi. Secara default, semua elemen adalah position: static. Ini berarti elemen akan diposisikan sesuai dengan urutannya dalam struktur HTML, dengan beberapa pengecualian.
Yang lain positionnilai-nilai relative, absolute, sticky, dan fixed. Dengan menyetel elemen positionke salah satu dari nilai-nilai lain ini sekarang mungkin untuk menggunakan kombinasi dari empat properti berikut untuk memposisikan elemen:
Dengan kata lain, dengan mengatur position: absolute, kita dapat menambahkan top: 100pxke posisi elemen 100 piksel dari bagian atas halaman. Sebaliknya, jika kita mengatur bottom: 100pxelemen akan diposisikan 100 piksel dari bagian bawah halaman.
Di sinilah banyak pendatang CSS tersesat -position: absolutememiliki kerangka referensi. Dalam contoh di atas, kerangka acuan adalahbodyelemen. position: absolutedengantop: 100pxcara elemen diposisikan 100 piksel dari bagian atasbodyelemen.
Kerangka posisi referensi, atau konteks posisi, dapat diubah dengan mengatur positionelemen induk ke nilai apa pun selainposition: static . Artinya, kita dapat membuat konteks posisi baru dengan memberikan elemen induk:
position: relative;
position: absolute;
position: sticky;
position: fixed;
Misalnya, jika <div class="parent">elemen diberikan position: relative, elemen anak mana pun menggunakan <div class="parent">konteks posisi mereka. Jika elemen anak diberikan position: absolutedan top: 100px, elemen akan diposisikan 100 piksel dari bagian atas <div class="parent">elemen, karena<div class="parent"> sekarang adalah konteks posisi.
Faktor lain yang harus diperhatikan adalah susunan tumpukan - atau bagaimana elemen ditumpuk dalam arah-z. Yang harus diketahui di sini adalah susunan elemen, secara default, ditentukan oleh kebalikan dari urutannya dalam struktur HTML. Perhatikan contoh berikut:
<body>
<div>Bottom</div>
<div>Top</div>
</body>
Dalam contoh ini, jika dua <div>elemen diposisikan di tempat yang sama pada halaman, <div>Top</div>elemen tersebut akan menutupi <div>Bottom</div>elemen tersebut. Sejak <div>Top</div>muncul setelah <div>Bottom</div>dalam struktur HTML memiliki urutan susun yang lebih tinggi.
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>
Urutan susun dapat diubah dengan CSS menggunakan properti z-indexatau order.
Kita dapat mengabaikan urutan penumpukan dalam masalah ini karena struktur HTML alami dari elemen berarti elemen yang ingin kita tampilkan topmuncul setelah elemen lainnya.
Jadi, kembali ke masalah yang ada - kita akan menggunakan konteks posisi untuk menyelesaikan masalah ini.
Solusinya
Seperti yang dinyatakan di atas, tujuan kami adalah memposisikan #infoielemen sehingga muncul di dalam .navielemen. Untuk melakukan ini, kami akan membungkus .navidan #infoielemen dalam elemen baru <div class="wrapper">sehingga kami dapat membuat konteks posisi baru.
<div class="wrapper">
<div class="navi"></div>
<div id="infoi"></div>
</div>
Kemudian buat konteks posisi baru dengan memberikan .wrappera position: relative.
.wrapper {
position: relative;
}
Dengan konteks posisi baru ini, kita dapat memposisikan #infoidalam .wrapper. Pertama, beri #infoia position: absolute, yang memungkinkan kita untuk memposisikan secara #infoimutlak .wrapper.
Kemudian tambahkan top: 0dan right: 0posisikan #infoielemen di sudut kanan atas. Ingat, karena #infoielemen menggunakan .wrapperkonteks posisinya, elemen akan berada di kanan atas .wrapperelemen.
#infoi {
position: absolute;
top: 0;
right: 0;
}
Karena .wrapperhanyalah wadah untuk .navi, memposisikan #infoidi sudut kanan atas .wrappermemberikan efek diposisikan di sudut kanan atas.navi .
Dan begitulah, #infoisekarang tampaknya berada di sudut kanan atas .navi.
Hasil
Contoh di bawah ini diringkas ke dasar-dasarnya, dan berisi beberapa gaya minimal.
/*
* 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>
Solusi Alternatif (Kotak)
Inilah solusi alternatif menggunakan CSS Grid untuk memposisikan .navielemen dengan #infoielemen di paling kanan. Saya telah menggunakan gridproperti verbose untuk membuatnya sejelas mungkin.
: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>
Solusi Alternatif (Tanpa Pembungkus)
Jika kami tidak dapat mengedit HTML apa pun, artinya kami tidak dapat menambahkan elemen pembungkus, kami masih dapat mencapai efek yang diinginkan.
Alih-alih menggunakan position: absolutepada #infoielemen, kita akan menggunakan position: relative. Ini memungkinkan kami untuk memposisikan ulang #infoielemen dari posisi default di bawah .navielemen. Dengan position: relativekita dapat menggunakan topnilai negatif untuk memindahkannya dari posisi default, dan leftnilai 100%minus beberapa piksel, menggunakan left: calc(100% - 52px), untuk memposisikannya di dekat sisi kanan.
/*
* 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, gunakanoverflow: visiblesebagai gantinya.