I have a flexbox container containing 2 div items. The flexbox container is setup for a row that centers the content inside. I am trying to figure out a way to center the contents of the row on the first item, and then have the second item be to the right of the first centered item.
Below is what I ended having to to do: have a the first item centered using the flexbox, but then I have to absolute position the second item to the desired position. Is there a way to remove the absolute positioning of the second item and have it appear just to the right of the first item, which is centered?
HTML
<div class="center-container">
<div class="time">
<span id="time">00:00</span>
</div>
<div class="time-ampm">
<span id="time-ampm">XX</span>
</div>
</div>
CSS
.center-container {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
}
.time {
flex: 1;
font-size: 50px;
font-weight: 300;
color: #262626;
}
.time-ampm {
position: absolute;
top: 115px;
left: 288px;
/* flex: 1; <= this is what I want to use, not the absolute positioning used above */
font-size: 20px;
font-weight: 400;
color: #858585;
}
This line shows where the flexbox centers the content if both of the items are set using flexbox (not the absolute positioning as above)
This line shows where I want the flexbox to center the items (centered on the first item)
What about setting the offset item width to 0?
HTML:
<div class="container">
<div>12:20</div>
<div class="offset">AM</div>
</div>
And CSS:
.container {
display:flex;
justify-content: center;
align-items:baseline;
}
.offset {
width:0;
}
http://codepen.io/anon/pen/dopQqo
Related
What I have is the following:
I have an icon on the left that represents a product. Then in H1, I have a product category, and with an h2, I have a product name.
The icon, h1, and h2 are in a parent div with flex and align-items value of baseline. So the text is baseline aligned.
Due to the dynamic nature of how the page title here is retrieved, the icon has to be in this parent div that is baseline aligned.
How can I vertically center the icon within this parent div with flexbox? I know how to accomplish this with vertical alignment and setting line height, but I'd prefer a flexbox approach.
Parent:
.parent {
display: flex;
align-items: baseline;
}
HTML skeleton:
<div class="parent">
<div>Icon</div>
<div>Product Category</div>
<div>Product Name</div>
</div>
Use baseline and center vertical alignment in combination
In the snippet below, I've added a wrapper div to hold the text elements together which get aligned around their baseline. The parent div will align its children vertically center, so that the icon and the text block will be nicely aligned.
.parent {
display: flex;
align-items: center;
font-family: sans-serif;
}
img {
border-radius: 100px;
margin-right: 8px;
}
.text {
display: flex;
align-items: baseline;
}
h3 {
font-size: 24px;
line-height: 32px;
}
p {
font-size: 16px;
line-height: 24px;
}
h3+p {
margin-left: 12px;
}
<div class="parent">
<img src="https://picsum.photos/50" alt="icon" />
<div class="text">
<h3>Product Category</h3>
<p>Product Name</p>
</div>
</div>
You can set align-self:center on the icon if you cannot change the parent div's align-items value to center. Find below an example:
.parent {
display: flex;
align-items: baseline;
gap:1rem; /* added just for readability, you can remove it */
}
.parent div:first-child{
align-self:center;
}
<div class="parent">
<div>Icon</div>
<h1>Product Category</h1>
<h2>Product Name</h2>
</div>
This question already has answers here:
How can I position my div at the bottom of its container?
(25 answers)
Closed 1 year ago.
I know this question came up many times but none of the suggested solutions is working for me so I opened up a code sandbox and made an example.
What I want
I want to place an item at the bottom of a div that already has some children. In my code sandbox the desired div to place at the bottom has a className of note__actions.
What I tried
Setting the container to position: relative and the item to position: absolute
Using flexbox and setting the container to display: flex and the item to align-self: flex-end
Multiple other things like vertical-align, and making empty items to fill up the space in-between
Div setup
<div className="flexBoxContainer" />
<div className="item">
<div>Header</div>
<div>Title</div>
<div>Paragraph</div>
<div className="bottom__item">Actions>/div> // Only this div should go to the bottom of the "item" div
</div>
</div>
Sandbox
https://codesandbox.io/s/infallible-sound-wf166?file=/src/App.js
Give the container display: flex; justify-content: space-between; - that will pull the content from top to bottom. If you want only the last item on the bottom and the rest on the top, wrap the rest with a div, like
<div className="flexBoxContainer" />
<div className="item">
<div>
<div>Header</div>
<div>Title</div>
<div>Paragraph</div>
</div>
<div className="bottom__item">Actions>/div>
</div>
</div>
You are already using flexbox which is great. Now, use margin-top:auto on note__actions to push the div to the bottom.
.note__actions {
margin-top: auto;
}
You could add a flex: 1; to the flexible content, for instance
.note {
background-color: rgb(255, 255, 211);
border-radius: 15px;
height: 400px;
width: 200px;
padding: 24px;
display: flex;
flex-direction: column;
}
.note-content {
flex: 1;
}
.note-action {
align-self: flex-end;
}
<div class="note">
<div>Peter Holbert - 09. Jul 21 23:28</div>
<div>Note Title</div>
<div class="note-content">Aldus PageMaker including versions of Lorem Ipsum.</div>
<div class="note-action">Action 1</div>
</div>
You can use a grid for that.
Change this in your Style on codesandbox.io:
.note {
background-color: rgb(255, 255, 211);
border-radius: 15px;
width: 200px;
padding: 24px;
display: grid;
/*flex-direction: column;*/
grid-template-rows: 50px 80px 1fr 80px; /* height: 100%; */
/* align-items: flex-end; */
/* position: relative; */
}
.note__actions_bot {
background-color: red;
height: 100px;
display: grid;
justify-content: center;
align-items: center;
}
I recommend this awesome Video to get a nice overview and some hint's how to do, and when to use which one of flex, grid and other solutions:
https://www.youtube.com/watch?v=qm0IfG1GyZU&feature=youtu.be
Add margin-top : auto to the note__actions element
I'm having a bit of trouble to produce the below with flex box. I'd like a centrally aligned "title" with some buttons to the right (2,3,4).
The code below gets me close, but it's not perfectly aligned and loses it when the window resizes.
Any suggestions?
.header {
display: flex;
height: 50px;
align-items: center;
justify-content: center;
}
.title {
width: 250px;
margin-left: auto;
margin-right: 15%;
}
.btn-group {
margin-right: 15%;
}
<div class="header">
<h1 class="title"></h1>
<div class="btn-group">
<button id="btn_1" class="selected">2</button>
<button id="btn_2">3</button>
<button id="btn_3">4</button>
</div>
</div>
Here's a clean and simple process to get you to your layout:
First, note that CSS pseudo-elements (i.e., ::before and ::after), when applied to flex containers, are treated as flex items.
Create a pseudo-element to serve as the first flex item in the container.
Make the pseudo consume all available space (i.e., set it to flex: 1)
Do the same with your button group (.btn-group) on the opposite end (i.e., set it to flex: 1)
Now, with the outer items pressuring from both sides, the title is pinned to the middle of the container.
Make the button group container a flex container.
Set that container to justify-content: center.
Now, the individual buttons are horizontally centered on the right side of the already centered title.
.header {
display: flex;
height: 50px;
align-items: center;
}
.header::before {
content: "";
flex: 1;
}
.btn-group {
flex: 1;
display: flex;
justify-content: center;
}
<div class="header">
<h1 class="title">1</h1>
<div class="btn-group">
<button id="btn_1" class="selected">2</button>
<button id="btn_2">3</button>
<button id="btn_3">4</button>
</div>
</div>
To better understand the concepts and methodology at work here, see this post:
Center and right align flexbox elements
Here are my suggestions when using flexbox layout. You do not need to set the width on the element because the width will resize dynamically. When you set display as flex in the container, the x-axis would change to row by default then use flex property for 'title' class to expand the width to double the width of 'btn-group'. As the result, the second div will push all the way to the right and you can add the width of margin-right as how much you want it to be. Also, I would create another div after header and give it a class name as 'title' instead of giving it on h1. That way you would have two children that allow you to control it. See below how I fixed it:
h1 {
text-align: center;
}
.header {
border: 1px solid red;
display: flex;
align-items: center;
justify-content: center;
}
.title {
flex: 1;
}
<div class="header">
<div class="title">
<h1>This is a title</h1>
</div>
<div class="btn-group">
<button id="btn_1" class="selected">2</button>
<button id="btn_2">3</button>
<button id="btn_3">4</button>
</div>
</div>
This question already has answers here:
Center one and right/left align other flexbox element
(11 answers)
Keep the middle item centered when side items have different widths
(12 answers)
Closed 4 years ago.
What I want as a result:
I have three elements in a container that is a display: flex I want the left item to be aligned to the left, and the right item to the right. With the center item aligned in the center.
space-between is not the fix. It is not the solution I am looking for. This is because the elements are differing widths. Even with differing widths, I still want the middle element to be centered.
This could be fixed with a wrapper. and then put a flex: 1 on the wrappers, then within those wrappers, have the elements themselves. Again, this is not the fix I am looking for. I cannot use wrappers in my situation.
.parentContainer {
display: flex;
justify-content: center;
align-items: center;
}
.parentContainer > *{
background: red;
text-align: center;
}
<div class="parentContainer">
<div class="left">small</div>
<div class="middle">medium element here</div>
<div class="right">longer element is here too</div>
</div>
The primary way to achieve this layout – because it's clean and valid – is with flex: 1 on the items. That method is explained in the following post, but is also ruled out in this question.
Keep the middle item centered when side items have different widths
An alternative method involves CSS absolute positioning:
.parentContainer {
display: flex;
justify-content: space-between;
position: relative;
}
.middle {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
/* non-essential decorative styles */
.parentContainer > * { background: orange; text-align: center; padding: 5px; }
p { text-align: center;}
p > span { background-color: aqua; padding: 5px; }
P > span:first-child { font-size: 1.5em; }
<div class="parentContainer">
<div class="left">small</div>
<div class="middle">medium element here</div>
<div class="right">longer element is here too</div>
</div>
<p>
<span>↑</span><br>
<span>true center</span>
</p>
This method is explained in the following posts:
Methods for Aligning Flex Items along the Main Axis (see Box #71)
Element will not stay centered, especially when re-sizing screen
I think you can use a different approach. This is my suggestion.
.parentContainer {
display: table;
width: 100%;
background: lightblue;
border-collapse: collapse;
}
.parentContainer > div {
display: table-cell;
width: 33%;
}
.parentContainer > div:nth-child(1) {
text-align: left;
}
.parentContainer > div:nth-child(2) {
text-align: center;
}
.parentContainer > div:nth-child(3) {
text-align: right;
}
<div class="parentContainer">
<div>small</div>
<div>medium element here</div>
<div>longer element is here too</div>
</div>
This question already has answers here:
Keep the middle item centered when side items have different widths
(12 answers)
Closed 5 years ago.
I know flexbox offers a great solution for centering items. But I run into an issue when I have 3 items and I'd like the center (2nd) item to be centered with respect to the window, regardless of the size of the other 2 items.
In my pen you can see the second item "Client Index" is off-center because the content on the right is larger than the content on the left. How can I force it to center itself?
.flex {
display: flex;
align-items: center;
justify-content: space-between;
}
<div class="flex">
<span style="font-size:12px;">small</span>
<span style="font-size:20px;">Client Index</span>
<span style="font-size:18px;">Lots of content that moves the center</span>
</div>
My Codepen
One way would be to set flex-grow: 1; flex-basis: 0 so the 3 columns are distributed evenly, then you can center the text or the content in the middle one.
I'm using text-align to center the middle column. You could also use display: flex; justify-content: center; to do the same thing.
.flex {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex > span {
flex: 1 0 0;
}
.flex > span:nth-child(2) {
text-align: center;
}
<div class="flex">
<span style="font-size:12px;">small</span>
<span style="font-size:20px;">Client Index</span>
<span style="font-size:18px;">Lots of content that moves the center</span>
</div>
Use nested flex containers and auto margins.
.flex-container {
display: flex;
}
.flex-item {
flex: 1;
display: flex;
justify-content: center;
}
.flex-item:first-child>span {
margin-right: auto;
}
.flex-item:last-child>span {
margin-left: auto;
}
/* non-essential */
.flex-item {
align-items: center;
border: 1px solid #ccc;
background-color: lightgreen;
height: 40px;
}
<div class="flex-container">
<div class="flex-item"><span>short</span></div>
<div class="flex-item"><span>medium</span></div>
<div class="flex-item"><span>lonnnnnnnnnnnnnnnnnnnng</span></div>
</div>
Here's how it works:
The top-level div is a flex container.
Each child div is now a flex item.
Each item is given flex: 1 in order to distribute container space equally.
Now the items are consuming all space in the row and are equal width.
Make each item a (nested) flex container and add justify-content: center.
Now each span element is a centered flex item.
Use flex auto margins to shift the outer spans left and right.
You could also forgo justify-content and use auto margins exclusively.
But justify-content can work here because auto margins always have priority. From the spec:
8.1. Aligning with auto
margins
Prior to alignment via justify-content and align-self, any
positive free space is distributed to auto margins in that dimension.