Centering non-text content in a center division? - html

In my page, I need to make something that looks like this, with a center division with images of different widths all center-aligned within the division (the lines won't be visible, that's just to make it easier to explain):
---------------------------------------
| | IMAGE 1 | |
| <stuff> | IMAGE 2 | <stuff> |
| | IMAGE 123 | |
---------------------------------------
There's a parent division for the whole "pseudo-table", and three divisions for each pseudo-column. However, no matter what I try, it seems to always look like this, where the left edge of the images aligns with each other:
---------------------------------------
| | IMAGE 1 | |
| <stuff> | IMAGE 2 | <stuff> |
| | IMAGE 123 | |
---------------------------------------
My HTML looks like this:
<div class="parent">
<div class="leftcol">STUFF HERE</div>
<div class="centercol">
<img="URL HERE"><br>
<img="URL HERE"><br>
<img="URL HERE">
</div>
<div class="rightcol">STUFF HERE</div>
</div>
For my CSS, I have pared it down for the sake of troubleshooting to:
.parent {
display:flex;
justify-content:space-between;
}
.leftcol {
}
.centercol {
justify-items:center;
}
.rightcol {
}
I've also tried align-items:center to the same lack of results. Any ideas?

Add display: flex, align-items: center and flex-direction: column to the center column div:
.parent {
display:flex;
justify-content:space-between;
}
.leftcol {
}
.centercol {
display: flex;
align-items: center;
flex-direction: column;
}
.rightcol {
}
<div class="parent">
<div class="leftcol">STUFF HERE</div>
<div class="centercol">
<img src="https://picsum.photos/100"><br>
<img src="https://picsum.photos/150/100"><br>
<img src="https://picsum.photos/120/100">
</div>
<div class="rightcol">STUFF HERE</div>
</div>

You may also imbricate flex and grid to allow also X,Y centering on each columns : example
.parent {
display:flex;
}
.parent>div {
flex:1;
display:grid;
justify-content:center;
align-items:center;
gap:0.25em;/* optional */
}
/* see what is going on */
div div {
border:solid 1px;
background:linear-gradient(90deg,transparent 50%, rgba(200,100,100,0.1) 50%),linear-gradient(0deg,transparent 50%, rgba(100,0,100,0.1) 50%)
}
<div class="parent">
<div class="leftcol">STUFF HERE</div>
<div class="centercol">
<img src="https://picsum.photos/50"><br>
<img src="https://picsum.photos/50/40"><br>
<img src="https://picsum.photos/60/30">
</div>
<div class="rightcol">STUFF HERE</div>
</div>

Related

Centering buttons regardless of how many in list

I've created a relatively simple layout using two DIVs. The idea is that everything is centered within their own DIVs but if there's not enough to fill a row the ones below would center also.
.row {
display: table;
width: 95%;
text-align: center;
margin-left: 2.5%;
margin-right: 2.5%;
margin-top: 2.5vh;
margin-bottom: 2.5vh;
}
.item {
width: 16.6%;
float: left;
}
#media only screen and (max-device-width: 500px) {
.item {
width: 33.3%;
float: left;
}
}
<div class="row">
<div class="item">
1
</div>
<div class="item">
2
</div>
<div class="item">
3
</div>
<div class="item">
4
</div>
<div class="item">
5
</div>
<div class="item">
6
</div>
</div>
</div>
These work fine and are all aligned. The issue comes when there's an odd number of items.
For example:
| 1 | 2 | 3 |
| 4 | 5 | 6 |
Works fine on mobile but...
| 1 | 2 | 3 |
| 4 | 5 | |
doesn't. I'd want something like this...
| 1 | 2 | 3 |
| 4 | 5 |
That means no matter how many items are added within the HTML they'll distribute properly when those rules are broken. Thanks in advance :)
Hopefully this makes sense.
Here you go with a solution using Flexbox
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
.item {
display: flex;
width: 20%;
height: 100px;
border: 1px Solid;
justify-content: center;
align-items: center;
margin: 5px;
}
<div class="row">
<div class="item">
1
</div>
<div class="item">
2
</div>
<div class="item">
3
</div>
<div class="item">
4
</div>
<div class="item">
5
</div>
</div>
jsfiddle

Using CSS, how to display another div on top of original on the hover

I have 4 divs in a some kind of boxes and I would like to hide original div (on hover) with another pair of hidden divs. So at the beginning it would looks like
_______ _______
| Q1 | | Q2 |
|_______| |_______|
_______ _______
| Q3 | | Q4 |
|_______| |_______|
and after hover on Q1 pair of hidden divs would appear and hide Q1, something like:
___ ___ _______
| Y || N | | Q2 |
|___||___| |_______|
_______ _______
| Q3 | | Q4 |
|_______| |_______|
Is it possible to get this behavior using CSS?
My code so far looks like this (there is just changing colors on hovering, every time I add new div it messes up my table:
.table {
display: grid;
grid-template-columns: 100px 100px;
grid-gap: 10px;
background-color: #eee;
color: #232794;
}
.boxes {
background-color: #232794;
color: #fff;
border-radius: 7px;
padding: 33px;
text-align: center;
transition: 0.3s;
}
.boxes:hover {
background-color: #000000;
}
<body>
<div class="table">
<div class="boxes">Q1</div>
<div class="boxes">Q2</div>
<div class="boxes">Q3</div>
<div class="boxes">Q4</div>
</div>
Basically you need to add elements inside your boxes to hide/show. You can either do this with pseudo-elements or by adding something to the DOM. Since I assume you're going to be able to click the "yes/no" actions, you should actually add an element.
.table {
display: grid;
grid-template-columns: 100px 100px;
grid-gap: 10px;
background-color: #eee;
color: #232794;
}
.boxes {
width: 100px;
height: 100px;
background-color: #232794;
color: #fff;
border-radius: 7px;
text-align: center;
transition: 0.3s;
}
.boxes .question, .boxes .answer {
/* center horizontally & vertically */
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
.boxes .answer {
/* hide this until hover */
display:none;
}
.boxes:hover {
cursor:pointer;
}
.boxes:hover .question {
/* hide question */
display:none;
}
.boxes:hover .answer {
/* show answer */
display:block;
}
<body>
<div class="table">
<div class="boxes">
<div class="question">Q1</div>
<div class="answer">
<button>Yes</button>
<button>No</button>
</div>
</div>
<div class="boxes">
<div class="question">Q2</div>
<div class="answer">
<button>Yes</button>
<button>No</button>
</div>
</div>
<div class="boxes">
<div class="question">Q3</div>
<div class="answer">
<button>Yes</button>
<button>No</button>
</div>
</div>
<div class="boxes">
<div class="question">Q4</div>
<div class="answer">
<button>Yes</button>
<button>No</button>
</div>
</div>
</div>

css to keep aspect ratio of 1:1 (square) based on parent height

I'm trying to make a calendar-like display where the dates' boxes are square-shaped but the whole calendar itself cannot have any scrolling..
it's supposed to look like this:
----------------------------------
| header element |
|--------------------------------|
| additional element |
|--------------------------------|
| ----------------- | --> start calendar (.box_fit-container)
| |sun|mon|tue|wed| |
| ----------------- |
| |d1 |d2 |d3 |d4 | |
| |d1 |d2 |d3 |d4 | |
| |d1 |d2 |d3 |d4 | | --> bottom of screen/viewport
| |d1 |d2 |d3 |d4 | | where it usually starts scrolling
| |d1 |d2 |d3 |d4 | |
| ----------------- |
----------------------------------
I managed to create the outer "frame" by using flex so that the outer container fills the remaining height of the original viewport, and I can also create an individual square shape, thanks to various SO contributors. but for whatever reason, I can't create a square shape where the object's width follows it's parent's height.
these are the code I have so far:
.box_fit-container {
display: flex;
flex-direction: column;
height: 80vh; /* this was supposed to be 100% according to the SO source I found, but since I'm working on a legacy code and there are other elements above this new one so I changed into 80vh to fit as close as possible */
}
.box_fit-header {
flex: 0 1 auto;
}
.box_fit-content {
flex: 1 1 auto;
}
.square-box {
position: relative;
width: 100%;
padding-top: 100%;
}
<div class="container">
<div class="box_fit-container">
<div class="box_fit-header">
<div>some header content
</div>
<div class="box_fit-content">
<!--
I need this .square-box elem to be square-shaped
but doesn't overflow outside the .box_fit-content
-->
<div class="square-box"></div>
</div>
</div>
</div>
If you can identify the height of the header or this one will always be fixed you can consider max-width to be 80vh - height of header
.box_fit-container {
display: flex;
flex-direction: column;
height: 80vh; /* this was supposed to be 100% according to the SO source I found, but since I'm working on a legacy code and there are other elements above this new one so I changed into 80vh to fit as close as possible */
border:1px solid;
}
.box_fit-header {
flex: 0 1 auto;
border:1px solid red;
}
.box_fit-content {
flex: 1 1 auto;
border:1px green;
}
.square-box {
position: relative;
width: 100%;
margin:auto;
max-width:calc(80vh - 25px);
border:2px solid;
}
.square-box:before {
content:"";
display:inline-block;
padding-top: 100%;
}
* {
box-sizing:border-box;
}
<div class="container">
<div class="box_fit-container">
<div class="box_fit-header">
<div>some header content
</div>
<div class="box_fit-content">
<!--
I need this .square-box elem to be square-shaped
but doesn't overflow outside the .box_fit-content
-->
<div class="square-box"></div>
</div>
</div>
</div>

Make unknown amount of divs fill nicely

Now, the title might be a bit vague, but I didn't know any other way to word it. What I basically want is this:
--------- --------- ---------
| DIV 1 | | DIV 2 | | DIV 3 |
--------- --------- ---------
--------- --------- ---------
| DIV 4 | | DIV 5 | | DIV 6 |
--------- --------- ---------
These div's are in a parent with a width of 1000px. So each div is 30% of width (with the proper gap inbetween basically).
The HTML:
<div id="matches">
<div class="match_box">
DIV 1
</div>
<div class="match_box">
DIV 2
</div>
<div class="match_box">
DIV 3
</div>
<div class="match_box">
DIV 4
</div>
<div class="match_box">
DIV 5
</div>
<div class="match_box">
DIV 6
</div>
</div>
The CSS:
#matches {
height: 100%;
width: 1000px;
}
How would I go about doing this? (.match_box being the div that need to flow nicely).
Thanks in advance!
If you don't have to target older browsers, you can use flexbox. This allows you to space the elements nicely. Here they go to the edges on both sides.
#matches {
height: 100%;
width: 500px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.match_box {
width:30%;
background-color: #eee;
margin-bottom: 10px;
}
https://jsfiddle.net/ekhts0fs/5/
Changing justify-content to space-between or center (see the link to flexbox above) can position them differently.
Try this:
#matches {
height: 100%;
width: 1000px;
}
.match_box {
width:30%;
float: left;
background-color: #ccc;
margin: 5px;
padding: 5px;
}
Live:
https://jsfiddle.net/Lu8p6gr3/2/

Center a <span> relative to container div, align another span with right-aligned text left of it

I'm trying to align a span element in the center of a container div, and have another span with right-aligned text aligned left of it:
+--------------------------------------------------------+
| <div> |
+----------------------+----------+ |
| <span> | <span> | |
| | | |
| | | |
| | | |
| right-aligned | centered | |
| | | |
| | | |
| | | |
| | | |
+----------------------+----------+ |
| |
+--------------------------------------------------------+
The contents of both spans are dynamically generated, so I'd like to avoid any absolute pixel widths if possible.
Any idea how to achieve this type of layout?
Here is the markup I eventually went with based on Persinj's answer:
HTML
<nav class="navbar">
<span class="nav-aside">Right-aligned: </span>
<span class="nav-menu">centered</span>
<span class="nav-aside"></span>
</nav>
CSS
nav.navbar {
display: flex;
}
span.nav-aside {
flex-grow: 1;
flex-basis: 0;
text-align: right;
}
span.nav-menu {
align-self: center;
text-align: center;
}
I left the vendor prefixes out of my markup since I have limited browser requirements, and I'm relying on autoprefixer to take care of that. Please see the accepted answer if you need them.
Flexbox design / layout
This can be sloved using flex:
Setting tree boxes:
Aside, center and a hidden one, will fill the required space.
Setting a flex-grow will make make them take up different parts of the page.
Setting flex-grow: 1; on each will make them take up equal space.
Setting one of them to flex-grow: 0.5; will give this part less space to grow.
Adding a wrapper with the flex property we can use align-items:center to make sure they stay in the center of the wrapper.
Fiddle
.wrapper {
height: 250px;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-wrap: nowrap;
flex-direction: row;
align-items: center;
text-align: center;
}
.center,
.aside,
.not-shown {
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
.center {
flex-grow: 0.5;
background-color: lightblue;
height: 50px;
}
.aside {
text-align: right;
background-color: 1;
background: lightgreen;
height: 50px;
}
.not-shown {
visibility: hidden;
flex-grow: 1.5;
height: 50px;
}
<div class="wrapper">
<div class="aside">
aside
</div>
<div class="center">
center
</div>
<div class="not-shown">
</div>
</div>
HTML:
<div class="wrapper">
<span class="span-left">right-aligned</span>
<span class="span-center">centered</span>
</div>
CSS:
.span-left, .span-center { display: inline-block; }
.span-left {
width: 40%;
text-align: right;
}
.span-center {
width: 20%;
text-align: center;
}
Alternatively, use display: block and float: left; on your spans (don't forget to clear after the wrapper).