Принятое решение прекрасно работает, но IMO не хватает объяснения, почему оно работает. Пример ниже сводится к основам и отделяет важный CSS от несоответствующего CSS стиля. В качестве бонуса я также включил подробное объяснение того, как работает позиционирование CSS.
TLDR; если вам нужен только код, прокрутите вниз до «Результат» .
Проблема
Есть два отдельных элемента, родственных элемента, и цель состоит в том, чтобы расположить второй элемент (со знаком id
of infoi
), чтобы он появился в предыдущем элементе (тот, у которого есть class
of 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
.
Мы можем игнорировать порядок размещения в этом выпуске, поскольку естественная HTML-структура элементов означает, что элемент, на котором мы хотим отображаться, top
идет после другого элемента.
Итак, вернемся к проблеме - мы будем использовать контекст позиции для решения этой проблемы.
Решение
Как указано выше, наша цель - расположить #infoi
элемент так, чтобы он отображался внутри .navi
элемента. Чтобы сделать это, мы будем обернуть .navi
и #infoi
элементы в новом элементе <div class="wrapper">
таким образом , мы можем создать новый контекст позиции.
<div class="wrapper">
<div class="navi"></div>
<div id="infoi"></div>
</div>
Затем создайте новый контекст позиции, давая ..wrapper
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
вместо этого.