Прийняте рішення працює чудово, але IMO бракує пояснень, чому воно працює. Наведений нижче приклад зведений до основ і відокремлює важливий CSS від невідповідного стилю CSS. Як бонус я також включив детальне пояснення того, як працює позиціонування CSS.
TLDR; якщо ви хочете лише код, прокрутіть униз до Результат .
Проблема
Є два окремих, брат, елементи і мета полягає в тому, щоб помістити другий елемент (з idз infoi), так що з'являється в межах попереднього елемента (один з classз navi). Структуру HTML неможливо змінити.
Пропоноване рішення
Щоб досягти бажаного результату, ми збираємося рухатись або розміщувати другий елемент, який ми будемо називати, #infoiщоб він з'явився в межах першого елемента, який ми будемо називати .navi. Зокрема, ми хочемо #infoiрозмістити його у правому верхньому куті .navi.
Позиція в CSS Необхідні знання
CSS має кілька властивостей для позиціонування елементів. За замовчуванням усі елементи є position: static. Це означає, що елемент буде розміщений відповідно до його порядку в структурі HTML, за невеликими винятками.
Решта positionзначення relative, absolute, stickyі fixed. Встановивши елемент positionна одне з цих інших значень, тепер можна використовувати комбінацію наступних чотирьох властивостей для позиціонування елемента:
Іншими словами, встановивши position: absolute, ми можемо додати top: 100pxелемент для розміщення 100 пікселів у верхній частині сторінки. І навпаки, якщо ми встановимо, bottom: 100pxелемент розміщувався б на 100 пікселів знизу сторінки.
Ось де багато новачків CSS загубляться -position: absoluteмає орієнтир. У наведеному вище прикладі орієнтиром єbodyелемент. position: absoluteізtop: 100pxзасобом елемент розташований на 100 пікселів у верхній частиніbodyелемента.
Опорний кадр позиції або контекст позиції можна змінити, встановивши positionбатьківський елемент на будь-яке значення, відмінне відposition: static . Тобто ми можемо створити новий контекст позиції, надавши батьківський елемент:
position: relative;
position: absolute;
position: sticky;
position: fixed;
Наприклад, якщо <div class="parent">елемент заданий position: relative, будь-які дочірні елементи використовують <div class="parent">як свій позиційний контекст. Якби дочірній елемент був наданий position: absoluteі top: 100px, він би розміщувався на 100 пікселів у верхній частині <div class="parent">елемента, оскільки <div class="parent">це зараз контекст позиції.
Інший фактор, про який слід пам’ятати, - це порядок стеку - або те, як елементи розміщуються у напрямку z. Необхідно знати, що порядок складання елементів за замовчуванням визначається зворотним їх порядком у структурі HTML. Розглянемо наступний приклад:
<body>
<div>Bottom</div>
<div>Top</div>
</body>
У цьому прикладі, якби два <div>елементи були розміщені в одному місці на сторінці, <div>Top</div>елемент охоплював би <div>Bottom</div>елемент. Оскільки <div>Top</div>з'являється після <div>Bottom</div>в структурі HTML, він має вищий порядок укладання.
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>
Порядок укладання можна змінити за допомогою CSS за допомогою властивостей z-indexабо order.
У цьому питанні ми можемо ігнорувати порядок укладання, оскільки природна структура елементів елементів означає, що елемент, на якому ми хочемо з'явитися, topз’являється після іншого елемента
Отже, повернемося до проблеми, яка існує, - ми будемо використовувати контекст позиції для вирішення цього питання.
Рішення
Як було сказано вище, наша мета - розташувати #infoiелемент так, щоб він виявився всередині .naviелемента. Для цього ми обернемо .naviі #infoiелементи в новий елемент, <div class="wrapper">щоб ми могли створити новий контекст позиції.
<div class="wrapper">
<div class="navi"></div>
<div id="infoi"></div>
</div>
Потім створіть новий контекст позиції, давши .wrappera position: relative.
.wrapper {
position: relative;
}
З цим новим контекстом позиції ми можемо позиціонувати #infoiвсередині .wrapper. По- перше, дати , що дозволяє нам позиціонувати абсолютно .#infoiposition: absolute#infoi.wrapper
Потім додайте top: 0та right: 0розташуйте #infoiелемент у правому верхньому куті. Пам'ятайте, оскільки #infoiелемент використовується .wrapperяк контекст його позиції, він буде знаходитися в правому верхньому куті .wrapperелемента.
#infoi {
position: absolute;
top: 0;
right: 0;
}
Оскільки .wrapperлише контейнер для .navi, розміщення #infoiу правому верхньому куті .wrapperдає ефект розташування у правому верхньому куті .navi.
І ось у нас це, #infoiсхоже, знаходиться у правому верхньому куті .navi.
Результат
Наведений нижче приклад зведений до основ та містить мінімальний стиль.
/*
* 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>
Альтернативне (сіткове) рішення
Ось альтернативне рішення за допомогою CSS Grid для позиціонування .naviелемента з #infoiелементом в правій крайній частині. Я використовував багатослівні gridвластивості, щоб зробити це максимально зрозумілим.
: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>
Альтернативне рішення (без обгортки)
Якщо ми не можемо редагувати жоден HTML, тобто ми не можемо додати елемент обгортки, ми все одно можемо досягти бажаного ефекту.
Замість того , щоб використовувати position: absoluteна #infoiелементі, ми будемо використовувати position: relative. Це дозволяє нам переставити #infoiелемент з його за замовчуванням положення під .naviелементом. З position: relativeми можемо використовувати негативне topзначення , щоб перемістити його зі своєї позиції по замовчуванням, і leftзначення 100%мінус декількох пікселів, використовуючи left: calc(100% - 52px), щоб розташувати його поруч з правого боку.
/*
* 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замість цього.