Прийняте рішення працює чудово, але 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>
Потім створіть новий контекст позиції, давши .wrapper
a position: relative
.
.wrapper {
position: relative;
}
З цим новим контекстом позиції ми можемо позиціонувати #infoi
всередині .wrapper
. По- перше, дати , що дозволяє нам позиціонувати абсолютно .#infoi
position: 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
замість цього.