Flexbox item within css grid cell appears to wrap - html

I'm new to using css grid, and I am trying to position two items within a single grid cell using flexbox to position the items. There is a logo on the left and a nav bar on the right, but the nav bar is not centered within cell "a", it appears to go below the lower boundary of cell "a" (I tried to upload a jpeg image, but Stack Overflow is having problems right now accepting image uploads, see Image upload fails with "imgur is rejecting the request").
Here is the html code:
<div class="a">
<div class="a_left">
Logo for Project
</div>
<div class="a_right">
<div class="topnav">
<a class="active" href="#home">Home</a>
News
Contact
About
</div>
</div>
</div>
Here is the css code:
.a{
display: grid;
font-family: sans-serif;
color: green;
font-size: 16pt;
}
.a_left{
display: flex;
text-align: left;
vertical-align: left;
flex-wrap: nowrap;
}
.a_right{
display: flex;
height: 100%;
flex-wrap: nowrap;
justify-content: right;
vertical-align: right;
}
.topnav {
align-content: right;
justify-content: center;
overflow: hidden;
background-color: #333;
height: 100%
}
The grid container is "a", and the nav bar is in the a_right flexbox. I have tried a lot of the likely height, width and centering properties without success, but I don't know if the property should be applied to a or to a_right.
Thanks for any help centering this nav bar.

If you want to have the logo on the left and menu on the right, you can simply do:
.a {
display: flex;
justify-content: space-between;
}
<div class="a">
<div class="a_left">
Logo for Project
</div>
<div class="a_right">
<div class="topnav">
<a class="active" href="#home">Home</a>
News
Contact
About
</div>
</div>
</div>

Flexbox is a container for centering its children - right now it looks like you're making the children into flexboxes, which won't do you a whole lot.
If you need to maintain the "grid" display property, add a container for both your logo and nav bar. This is the container that you will want with display:flex, and it will be the container that you apply your flex-related alignment properties to.
Also, to vertically align content in a flexbox, use align-items. Horizontal alignment requires justify-content.

So you set your element .a to be a grid container:
.a {
display: grid;
}
… and you want to know why the children (.a_left and .a-right) are stacking vertically instead of on the same row.
The reason is that you haven't defined explicit tracks with grid-template-columns or grid-template-areas. Because you haven't defined explicit columns, grid-auto-columns comes into play to create implicit columns.
The default value of grid-auto-columns is auto, which essentially allows each grid item to occupy an entire row. That's what you're seeing; it's like block elements stacking.
Try this instead:
.a {
display: grid;
grid-template-columns: auto 1fr; /* define explicit columns */
color: green;
font-size: 16pt;
}
.a_left {
display: flex;
}
.a_right {
display: flex;
justify-content: center;
}
.topnav {
background-color: yellow;
}
<div class="a">
<div class="a_left">Logo for Project</div>
<div class="a_right">
<div class="topnav">
<a class="active" href="#home">Home</a>
News
Contact
About
</div>
</div>
You may also want to read this post about centering elements on a row having other elements: Center and right align flexbox elements

Related

Why won't this second item center in the div?

HTML
<div id="flexbox-container">
<h1 id="test1">test1</h1><h1 id="test2">test2</h1><h1 id="test3">test3</h1>
</div>
CSS
#flexbox-container {
display:inline-flex;
}
#test1 {
float:left;
}
#test2 {
justify-content:center;
align-items:center;
text-align:center;
align-self:center;
align-content:center;
}
#test3 {
position:relative;
left:1000px;
}
Why does test2 not center itself in the flex? I would prefer not to have to set px or margin to get it to centre. I tried all sorts of aligning stuff on it yet it still sticks to the left. I need the three items to be inline, so setting it to flex wouldn't work (though it does center align if I make it flex), PLEASE HELP IVE BEEN TRYING FOR DAYS
https://codepen.io/throwaway123/pen/mdpJJKY
Only this much code is enough. No need for all those styles for separate h1 tags. You have to give the aligning styles to the parent div.
#flexbox-container {
width: 100%;
display:inline-flex;
justify-content: space-between;
}
<div id="flexbox-container">
<h1 id="test1">test1</h1>
<h1 id="test2">test2</h1>
<h1 id="test3">test3</h1>
</div>
Basically that isn't how flex works.
You don't want the contents of the second item to be justified within itself, you want the container to have that element centered.
If you scrap all the positioning of the three items you can get flex to do the work for you. There are several ways of telling it how you want the items set out in the line. For example justify-content: space-between.
From MDN:
The items are evenly distributed within the alignment container along the main axis. The spacing between each pair of adjacent items is the same. The first item is flush with the main-start edge, and the last item is flush with the main-end edge.
#flexbox-container {
display: inline-flex;
justify-content: space-between;
width: 100vw;
}
<div id="flexbox-container">
<h1 id="test1">test1</h1>
<h1 id="test2">test2</h1>
<h1 id="test3">test3</h1>
</div>
Using IDs for css is bad practice. I'd suggest you to start using class selectors
Anyway, here is solution to your problem :
<style>
#flexbox-container {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
If you want the h1 tags centered too you can wrap the h1 tag by a div. Then you can assign the div text-align: center CSS Property.
#flexbox-container {
background: green;
display:flex;
justify-content: space-between;
text-align: center;
}
#flexbox-container div {
width: 100%;
}
<div id="flexbox-container">
<div>
<h1 id="test1">test1</h1>
</div>
<div>
<h1 id="test2">test2</h1>
</div>
<div>
<h1 id="test3">test3</h1>
</div>
</div>

Using flex, one element centrally aligned and others spaced between the centre and right

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>

How to get two pieces of text to sit next to each other and be responsive to screen width changes?

Website imageI'm trying to get these two pieces of text to sit next to each other rather than on top of each other. I also want them to be responsive to screen size adjustment.
'Carttext' is positioned where I want it on the screen when 'Icontext' is removed and is responsive to screen size adjustment.
I want 'Icontext' to sit just to the left of it but I can't seem to achieve this with it still being responsive to screen size changes. Any tips would be much appreciated, Code is below.
<div id="Icontext";
style="position: relative;">Login</DIV>
<div id="Carttext";
style="position: relative;">Cart</DIV>
you can achieve this using simply display:inline-block to both element or you can use display: flex. for spacing between element you can use margin or padding
.flex-container {
display: flex;
margin: 20px; /* spacing to screen*/
justify-content: flex-end;
}
.flex-container div:first-child {
margin-right: 20px; /* for spaceing between element */
}
<div class="flex-container">
<div id="Icontext">Login</div>
<div id="Carttext">Cart</div>
</div>
Try adding the following css:
#Icontext, #Carttext{
display:inline-block;
}
Here is the kind of thing that #mplungjan is suggesting with display: inline-block; which is probably preferable than using float: left;.
Also note that I removed the ; between the ID and style references. It's also probably best to be doing these style changes in CSS as shown below.
You can add margin: 10px; to add space between them and above them.
.links {
margin: 10px;
position: relative;
display: inline-block;
}
<div id="Icontext" class="links">Login</div>
<div id="Carttext" class="links">Cart</div>
Another way is using Flexbox. You can adjust the space between the items with margin-right.
.container {
display: flex;
justify-content: flex-start;
}
#Icontext {
margin-right: 10px;
}
<div class="container">
<div id="Icontext">Login</div>
<div id="Carttext">Cart</div>
</div>

CSS: How to resize the right side element only?

I'd like to display price and description this way. And when the window width is resized, I want only middle part (inside blue rectangle) to be resized.
The red rectangle's width should not change for any window dimension.
I tried to use <table> tag, but it makes the first part to be wrapped.
Here is HTML snippet for this:
<table class="notfootable">
<tbody>
<tr>
<td><span class="usd">$</span><span class="monthly-cost">744.58</span></td>
<td>
<h4>Monthly Cost</h4>
<p class="nomargin">This includes your Account's Subscription Plan as well as any Add-ons for your Account.</p>
</td>
</tr>
</tbody>
</table>
Note that <span class="usd"> has the following CSS attributes.
.usd {
vertical-align: top;
display: inline-block;
font-size: 11px;
color: #1587AC;
margin-top: 0.3em;
}
I added display: inline-block to add margin-top.
First, you don't want this to be formed inside of a table tag. It's not tubular data that inside of it. It's content.
Secondly, flexbox can come in handy to address this problem that you're having. It's easy to use and has many options to align your content on the x-axis and the y-axis within a div.
The CSS3 Flexible Box, or flexbox, is a layout mode providing for the
arrangement of elements on a page such that the elements behave
predictably when the page layout must accommodate different screen
sizes and different display devices.
You can read more about flexbox at MDN.
With that in mind, I made a little sample to recreate what you want to achieve.
.container {
display: flex;
flex-flow: row wrap;
width: 100%;
}
.info {
display: flex;
}
.price {
display: flex;
align-items: center;
padding-right: 30px;
}
.cta {
display: flex;
width: 100%;
justify-content: flex-end;
}
#media screen and (min-width: 600px) {
.container {
display: flex;
width: 100%;
align-items: center;
}
.info {
width: 80%;
}
.cta {
display: block;
justify-content: initial;
width: 20%;
padding-left: 30px;
box-sizing: border-box;
}
}
<div class="container">
<div class="info">
<div class="price">
<span class="usd">$</span><span class="monthly-cost">744.58</span>
</div>
<div class="description">
<h4>Monthly Cost</h4>
<p>This includes your Account's Subscription Plan as well as any Add-ons for your Account.</p>
</div>
</div>
<div class="cta">
<button>Billing details</button>
</div>
</div>
I believe to accomplish this you can use position: absolute on a <div> surrounding the blue rectangle and use position:relative on the parent container surrounding that element. On all other elements inside that container use position: relative.
Here is a somewhat similar question to yours:
DIV absolute positioning - maintain position after browser window resize
Hope this helps.
Enclose the two span of "usd" and "monthly-cost" within a div that has display display attributes of "inline-block" and a fixed width that is wide enough to accommodate the widest cost amount displays. This should keep those two spans inline as the display width is decreased.
You can make use of flex layouts as below:
HTML:
<div class="main">
<div class="left">
<span class="usd">$</span><span class="monthly-cost">744.58</span>
</div>
<div class="right">
<div class="right-top">
<h4>Monthly Cost</h4>
<p class="nomargin">This includes your Account's Subscription Plan as well as any Add-ons for your Account.</p>
</div>
<div class="right-bottom">
<button>billing details</button>
</div>
</div>
CSS:
.main {
display: flex;
flex-direction: row;
}
.left {
align-self: center;
padding-right: 55px;
}
.right {
flex-direction:column;
}
More on flex layouts:https://css-tricks.com/snippets/css/a-guide-to-flexbox/

CSS Flexbox Centering Horizontally Issue

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