A solução aceita funciona muito bem, mas a IMO não tem uma explicação sobre o motivo. O exemplo abaixo é resumido ao básico e separa o CSS importante do CSS de estilo não relevante. Como bônus, também incluí uma explicação detalhada de como o posicionamento CSS funciona.
TLDR; se você deseja apenas o código, role para baixo até O resultado .
O problema
Existem dois elementos separados, irmãos, e o objetivo é posicionar o segundo elemento (com um idde infoi), para que ele apareça no elemento anterior (aquele com um classde navi). A estrutura HTML não pode ser alterada.
Solução proposta
Para alcançar o resultado desejado, vamos mover ou posicionar o segundo elemento, que chamaremos #infoipara que apareça no primeiro elemento, que chamaremos .navi. Especificamente, queremos #infoiser posicionados no canto superior direito de .navi.
Posição CSS Conhecimento necessário
CSS possui várias propriedades para elementos de posicionamento. Por padrão, todos os elementos são position: static. Isso significa que o elemento será posicionado de acordo com sua ordem na estrutura HTML, com poucas exceções.
Os outros positionvalores são relative, absolute, sticky, e fixed. Ao definir um elemento positionpara um desses outros valores, agora é possível usar uma combinação das quatro propriedades a seguir para posicionar o elemento:
Em outras palavras, ao definir position: absolute, podemos adicionar top: 100pxpara posicionar o elemento 100 pixels da parte superior da página. Por outro lado, se definirmos bottom: 100pxo elemento, ele será posicionado a 100 pixels da parte inferior da página.
Aqui é onde muitos novatos em CSS se perdem -position: absolutetem um quadro de referência. No exemplo acima, o quadro de referência é obodyelemento position: absolutecomtop: 100pxsignifica que o elemento está posicionado a 100 pixels da parte superior dobodyelemento.
O quadro de referência da posição, ou o contexto da posição, pode ser alterado definindo o positionelemento pai de qualquer valor diferente deposition: static . Ou seja, podemos criar um novo contexto de posição fornecendo um elemento pai:
position: relative;
position: absolute;
position: sticky;
position: fixed;
Por exemplo, se um <div class="parent">elemento é fornecido position: relative, qualquer elemento filho usa o <div class="parent">como contexto de posição. Se um elemento filho fosse fornecido position: absolutee top: 100px, o elemento seria posicionado a 100 pixels da parte superior do <div class="parent">elemento, porque <div class="parent">agora é o contexto da posição.
O outro fator a ser observado é a ordem da pilha - ou como os elementos são empilhados na direção z. O que você deve saber aqui é que a ordem dos elementos da pilha é, por padrão, definida pelo inverso de sua ordem na estrutura HTML. Considere o seguinte exemplo:
<body>
<div>Bottom</div>
<div>Top</div>
</body>
Neste exemplo, se os dois <div>elementos fossem posicionados no mesmo lugar na página, o <div>Top</div>elemento cobriria o <div>Bottom</div>elemento. Como <div>Top</div>vem depois <div>Bottom</div>na estrutura HTML, ele tem uma ordem de empilhamento mais alta.
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>
A ordem de empilhamento pode ser alterada com CSS usando as propriedades z-indexou order.
Podemos ignorar a ordem de empilhamento nesta edição, pois a estrutura HTML natural dos elementos significa que o elemento em que queremos que apareça topvem após o outro elemento.
Então, voltando ao problema em questão - usaremos o contexto da posição para resolver esse problema.
A solução
Como mencionado acima, nosso objetivo é posicionar o #infoielemento para que ele apareça dentro do .navielemento. Para fazer isso, agruparemos os elementos .navie #infoiem um novo elemento <div class="wrapper">para que possamos criar um novo contexto de posição.
<div class="wrapper">
<div class="navi"></div>
<div id="infoi"></div>
</div>
Em seguida, crie um novo contexto de posição dando .wrappera position: relative.
.wrapper {
position: relative;
}
Com este novo contexto de posição, podemos posicionar #infoidentro .wrapper. Primeiro, dê #infoia position: absolute, permitindo-nos posicionar #infoiabsolutamente .wrapper.
Em seguida, adicione top: 0e right: 0para posicionar o #infoielemento no canto superior direito. Lembre-se, como o #infoielemento está usando .wrappercomo contexto de posição, ele estará no canto superior direito do .wrapperelemento.
#infoi {
position: absolute;
top: 0;
right: 0;
}
Como .wrapperé apenas um contêiner para .navi, o posicionamento #infoino canto superior direito da .wrapperdá o efeito de ser posicionado no canto superior direito da .navi.
E aí está, #infoiagora parece estar no canto superior direito de .navi.
O resultado
O exemplo abaixo é resumido ao básico e contém alguns estilos mínimos.
/*
* 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>
Uma solução alternativa (grade)
Aqui está uma solução alternativa usando CSS Grid para posicionar o .navielemento com o #infoielemento na extrema direita. Eu usei as gridpropriedades detalhadas para deixar o mais claro possível.
: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>
Uma solução alternativa (sem invólucro)
Caso não possamos editar nenhum HTML, o que significa que não podemos adicionar um elemento wrapper, ainda podemos obter o efeito desejado.
Em vez de usar position: absoluteo #infoielemento, usaremos position: relative. Isso nos permite reposicionar o #infoielemento de sua posição padrão abaixo do .navielemento. Com position: relativepodemos usar um topvalor negativo para movê-lo para cima de sua posição padrão, e um leftvalor de 100%menos alguns pixels, usando left: calc(100% - 52px), para posicioná-lo próximo ao lado direito.
/*
* 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, use emoverflow: visiblevez disso.