Kabul edilen çözüm harika çalışıyor, ancak IMO'nun neden çalıştığına dair bir açıklama yok. Aşağıdaki örnek, temel bilgilerle kaynatılmıştır ve önemli CSS'yi ilgili olmayan stil CSS'sinden ayırır. Bir bonus olarak, CSS konumlandırmasının nasıl çalıştığına dair ayrıntılı bir açıklama da ekledim.
TLDR; yalnızca kodu istiyorsanız, aşağıya kaydırın Sonuç .
Sorun
İki ayrı, kardeş, elemanlardır ve hedef (bir ikinci eleman konumlandırmaktır idarasında infoiönceki eleman (bir kez görünecek şekilde,) classarasında navi). HTML yapısı değiştirilemez.
Önerilen çözüm
İstenen sonucu elde etmek için arayacağımız ikinci elemanı taşıyacağız ya da konumlandıracağız, #infoiböylece arayacağımız ilk elemanın içinde görünecektir .navi. Özellikle, öğesinin #infoisağ üst köşesine yerleştirilmek istiyoruz .navi.
CSS Konumu Gerekli Bilgi
CSS'nin konumlandırma elemanları için çeşitli özellikleri vardır. Varsayılan olarak, tüm öğeler position: static. Bu, öğenin birkaç istisna dışında, HTML yapısındaki sırasına göre konumlandırılacağı anlamına gelir.
Diğer positiondeğerlerdir relative, absolute, sticky, ve fixed. Bir öğeyi positionbu diğer değerlerden birine ayarlayarak, öğeyi konumlandırmak için aşağıdaki dört özelliğin bir kombinasyonunu kullanmak artık mümkün:
Başka bir deyişle, ayarlayarak position: absolute, top: 100pxöğeyi sayfanın üstünden 100 piksel konumlandırmayı ekleyebiliriz . Tersine, bottom: 100pxöğeyi ayarlarsak sayfanın altından 100 piksel konumlandırılır.
Burada birçok CSS yeni gelen kayboluyor -position: absolutebir referans çerçevesi var. Yukarıdaki örnekte, referans çerçevesibodyöğedir. position: absoluteiletop: 100pxaracılığıyla elemanı üstünden 100 piksel konumlandırılmışbodyelemanı.
Referansın pozisyon çerçevesi veya pozisyon bağlamı, positionbir ana elemanın dışında herhangi bir değereposition: static ayarlanmasıyla değiştirilebilir . Yani, bir üst öğe vererek yeni bir konum bağlamı oluşturabiliriz:
position: relative;
position: absolute;
position: sticky;
position: fixed;
Örneğin, bir <div class="parent">öğe verilirse position: relative, herhangi bir alt öğe <div class="parent">konum bağlamı olarak kullanır . Bir alt öğe verildiyse position: absoluteve top: 100pxöğe şu anda konum bağlamı <div class="parent">olduğundan, öğenin üstünden 100 piksel <div class="parent">konumlandırılırsa.
Dikkat edilmesi gereken diğer bir faktör , yığın sırası veya elemanların z yönünde istiflenmesidir. Burada bilinmesi gereken, öğelerin yığın sırasının varsayılan olarak HTML yapısındaki sıralarının tersi ile tanımlanmış olmasıdır. Aşağıdaki örneği düşünün:
<body>
<div>Bottom</div>
<div>Top</div>
</body>
Bu örnekte, iki <div>öğe sayfada aynı yere yerleştirildiyse, <div>Top</div>öğe öğeyi kaplar <div>Bottom</div>. Yana <div>Top</div>sonra gelen <div>Bottom</div>HTML yapısında daha yüksek istifleme düzeni vardır.
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>
Yığınlama sırası z-indexveya orderözellikleri kullanılarak CSS ile değiştirilebilir .
Öğelerin doğal HTML yapısı üzerinde görünmesini istediğimiz topöğenin diğer öğeden sonra gelmesi anlamına geldiğinden, bu sayıdaki yığınlama sırasını göz ardı edebiliriz .
Dolayısıyla, eldeki soruna geri dönersek - bu sorunu çözmek için konum bağlamını kullanacağız.
Çözüm
Yukarıda belirtildiği gibi, hedefimiz #infoiöğeyi öğenin içinde görünecek şekilde konumlandırmaktır .navi. Bunu yapmak için, yeni bir konum bağlamı oluşturabilmemiz için .navive #infoiöğelerini yeni bir öğeye <div class="wrapper">sararız.
<div class="wrapper">
<div class="navi"></div>
<div id="infoi"></div>
</div>
Ardından, .wrappera position: relative.
.wrapper {
position: relative;
}
Bu yeni pozisyon bağlamıyla, #infoiiçeride konumlandırabiliriz .wrapper. İlk olarak, vermek #infoibir position: absolutepozisyona bizi izin #infoikesinlikle .wrapper.
Sonra eklemek top: 0ve right: 0konumlandırmak için #infoisağ üst köşede elemanı. Unutmayın, #infoiöğe .wrapperkonum bağlamı olarak kullandığından öğenin sağ üst köşesinde olacaktır .wrapper.
#infoi {
position: absolute;
top: 0;
right: 0;
}
Çünkü .wrappersadece bir kap olduğu için .navi, #infoisağ üst köşesinde .wrapperkonumlandırma, sağ üst köşesinde konumlandırılma etkisi verir .navi.
Ve işte elimizde, #infoişimdi sağ üst köşede gibi görünüyor .navi.
Sonuç
Aşağıdaki örnek temel bilgilere göre kaynatılmıştır ve bazı minimal stiller içermektedir.
/*
* 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>
Alternatif (Izgara) Çözüm
İşte konumlandırmak için CSS grid kullanımının alternatif çözüm .naviile eleman #infoisağında yer eleman. gridMümkün olduğunca net hale getirmek için ayrıntılı özellikleri kullandım .
: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>
Alternatif (Sarıcı Yok) Çözümü
Herhangi bir HTML'yi düzenleyemezsek, yani bir sarmalayıcı öğe ekleyemeyiz, yine de istenen efekti elde edebiliriz.
Bunun yerine kullanmanın position: absoluteüzerine #infoielemanı, biz kullanacağız position: relative. Bu, #infoiöğeyi öğenin altındaki varsayılan konumundan yeniden konumlandırmamızı sağlar .navi. İle , varsayılan konumundan yukarı taşımak için position: relativenegatif topbir leftdeğer ve sağ tarafa yakın konumlandırmak için 100%kullanarak eksi birkaç piksel değerini left: calc(100% - 52px)kullanabiliriz.
/*
* 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, kullanmakoverflow: visibleyerine.