Flexbox align with padding? - html

I am relatively new to flexbox and I find it awesome.
I am currently trying to align a text to the top right of a card section, but the problem I encounter occurs because I don't want it to stick to the right of the screen, but to the rightmost card - So if I have a single card, it wont go to the end of the screen, and also if I have more than the screen can hold (I also flex wrap it) it would still stick to the rightmost card.
I simplified the code for the example (enter on fullscreen and play with the width of the screen by shrinking/expanding devtools(F12))
.spacer {
padding-top: 300px;
}
.card {
height: 200px;
width: 200px;
background-color: blue;
margin-right: 16px;
margin-bottom: 16px;
}
.container {
display: flex;
flex-wrap: wrap;
}
.text-container {
display: flex;
justify-content: flex-end;
}
<div class="spacer"></div>
<div>
<div class="text-container">
<div> wow </div>
</div>
<div class="container">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
</div>
the card amount is not fixed as in the example, it is an *ngFor a changing list
I heard a thing from a colleague about fxFlexOffset, but couldn't understand how to use it, and if it is helpful in my example.
Anyone have any Idea how to do it except of media queries, And if it is impossible to do it without media queries, is there a simple one (the cards sizes are fixed)?
Thanks!

If you want an easy CSS solution without media query and without JS I can only thing about a hacky way to achieve this:
.card {
height: 200px;
width: 200px;
background-color: blue;
margin-right: 16px;
position:relative;
text-align:right
}
.card:before {
content:"WOW";
font-size:20px;
background:#fff;
position:absolute;
right:0;
left:-1000%;
top:-25px;
z-index:0;
}
.card:after {
content:"";
position:absolute;
bottom:0;
background:#fff;
left:0;
right:0;
height:20px;
z-index:1;
}
.container {
margin-top:50px;
display: flex;
flex-wrap: wrap;
}
.text-container {
display: flex;
justify-content: flex-end;
}
<div class="container">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>

Related

Divs laid out side by side with inline-block change layout when child elements added [duplicate]

This question already has an answer here:
Why does div with content move down in inline-block?
(1 answer)
Closed 1 year ago.
My goal is to create a list of divs, that lay out side by side, with a fixed width and height, some containing a bit of text and some not.
To achieve this I've used code similar to the following:
<div>
<div class="card"></div>
<div class="card">
<div>Testing 123</div>
</div>
<div class="card"></div>
</div>
.card {
background-color: red;
margin-left: 15px;
width: 100px;
height: 50px;
display: inline-block;
}
The outcome I'm seeing is that when a child div is added to my cards, they bump down as if they had a large top margin. What I'd expect to see is all 3 divs laid out exactly next to each other.
Why is this happening, and what can I do to prevent it? Thanks for any information!
.wrapper {
display: flex;
}
.card {
background-color: red;
margin-left: 15px;
width: 100px;
height: 50px;
display: inline-block;
}
Try wrapping the 3 divs in a `flexbox`.
<div class="wrapper">
<div class="card"></div>
<div class="card">
<div>Testing 123</div>
</div>
<div class="card"></div>
</div>
You can use flex-wrap property.
.card {
background-color: red;
margin-left: 15px;
width: 100px;
height: 50px;
display: inline-block;
}
#dom{
display:flex;
flex-wrap:wrap;}
<div id="dom">
<div class="card"></div>
<div class="card">
<div>Testing 123</div>
</div>
<div class="card"></div>
</div>

Two div in one line, but one div is fixed size, how to? [duplicate]

This question already has answers here:
Two divs side by side - Fluid display [duplicate]
(9 answers)
Expand a div to fill the remaining width
(21 answers)
Closed 1 year ago.
I'm sorry, I speak a little English. I would like see in one line the left and right div.
HTML:
<div id="header">header</div>
<div id="container">
<div id="left"></div>
<div id="right"></div>
</div>
<div id="footer">footer</div>
CSS:
#container { max-width: 1700px; }
#left { width: 100%-314px; }
#right { width: 314px; }
And I would like work if without #right div. See:
HTML (2):
<div id="header">header</div>
<div id="container">
<div id="left"></div>
</div>
<div id="footer">footer</div>
How to?
A possible workaround might be using the span tag, used in your code like this:
<div id="header">header</div>
<div id="container">
<span id="left"></span>
<span id="right"></span>
</div>
<div id="footer">footer</div>
that wont require a fixed size or anything.
Do you mean something like this?
I simply select the divs inside the container and gives them display: inline-block
#container { max-width: 1700px; }
#left { width: 100%-314px; }
#right { width: 314px; }
#container div {
display: inline-block;
}
<div id="header">header</div>
<div id="container">
<div id="left"><p>|left elem|</p></div>
<div id="right"><p>|right elem|</p></div>
</div>
<div id="footer">footer</div>
How about css grid?
.container {
display: grid;
grid-template-columns: 1fr auto;
}
.right {
width: 314px;
}
<div class="container">
<div class="left">A</div>
<div class="right">B</div>
</div>
You can use flexbox, make sure you set display:flex for your container and if you want to align your items with space in between, you can set justify-content:space-between.
#container {
display: flex;
max-width: 1700px;
justify-content: space-between;
}
#left {
background-color: green;
width: 314px;
}
#right {
background-color: red;
width: 314px;
}
<div id="header">header</div>
<div id="container">
<div id="left">left</div>
<div id="right">right</div>
</div>
<div id="footer">footer</div>
This should work for you!
#container {
max-width: 1700px;
display: flex;
}
#left {
width: calc(100% - 314px);
}
#right {
width: 314px;
}
Code Explained:
display:flex : The main idea behind the flex layout is to give the container the ability to alter its items' width/height (and order) to best fill the available space.
calc(100%-314px) : The calc() function performs a calculation that can be used on the property.
I hope this helped you!
You can do this by CSS flex property. div is block level element to get div in one line you can set div to display:inline-block; or inline
check example below.
.flex-container {
display: flex;
height:400px;
flex-flow: column wrap;
background-color: green;
align-content: space-between;
}
.flex-container > div {
background-color: #fff;
width: 100px;
margin: 10px;
text-align: center;
line-height: 75px;
font-size: 30px;
}
.container{
border:1px solid #000;
height:500px !important;
padding:20px;
}
.left{
margin:10px;
background:#f00;
padding:50px;
color:#fff;
float:left;
}
.right{
margin:10px;
background:#f00;
padding:50px;
color:#fff;
float:right;
}
<h1>Example 1</h1>
<div class="flex-container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
<h1>Example 2</h1>
<div class="container">
<div class="left">
<h3>Left</h3>
</div>
<div class="right">
<h3>Right</h3>
</div>
<div class="left">
<h3>Left</h3>
</div>
<div class="right">
<h3>Right</h3>
</div>
</div>

Using flexbox, how to overlay an image and expand to fill parent container

In the following html I want the txt-box div to be centered in the container, overlay the image, and expand to fill the container. It should have a margin of equal width on all sides allowing part of the image to show like a thick border.
The html shown is passable for what I want except the vertical vs. horizontal margins are always slightly different as the browser window is resized.
I feel like what I have here is a hack and that I am using flex-grow incorrectly. I understand flex-grow works to allow the txt-box div to expand since it is the only element with a grow value. If I can get that resolved I should be able to simply set a margin on txt-box and it should work.
What am I not understanding about flex-grow?
.container {
display: flex;
align-items: center;
justify-content: center;
border: solid 2px red;
position: relative;
}
.container img {
width: 100%;
flex-grow: 0;
flex-shrink: 0;
}
.txt-box {
background-color: white;
display: flex;
padding: 5px;
border: solid 2px blue;
flex-grow: 1;
position: absolute;
width: 90%;
height: 80%;
}
<div class="container">
<img src="blocks.png" />
<div class="txt-box">
hello world
</div>
</div>
Thanks to Michael Benjamin for putting me on the path to enlightenment. I finally got it figured out. My original question was actually a portion of what I was trying to accomplish. The answers are to use background-image:url('...') and make sure the table and row elements are display:flex.
JSFiddle
<html>
<head>
<style>
.flex-table {
flex-flow:column;
}
.flex-row {
flex-flow:row;
}
.container {
align-items: center;
justify-content: center;
padding: 20px;
border: solid 2px red;
background-image:url('https://i.imgur.com/BF3ty6o.jpg');
background-size:cover;
background-repeat:no-repeat;
max-width:500px;
}
.txt-box {
justify-self:stretch;
align-self:stretch;
border: solid 2px blue;
background-color: rgba(192,192,192,0.5);
}
body, .flex-table, .flex-row, .container, .txt-box {
display:flex;
flex-grow:1;
}
#media (max-width: 768px) {
.flex-row {
flex-flow:column;
}
}
</style>
</head>
<body>
<div class="flex-table">
<div class="flex-row">
<div class="container">
<div class="txt-box">
hello world 1
</div>
</div>
<div class="container">
<div class="txt-box">
hello world 2
</div>
</div>
<div class="container">
<div class="txt-box">
hello world 3
</div>
</div>
</div>
<div class="flex-row">
<div class="container">
<div class="txt-box">
hello world 4
</div>
</div>
<div class="container">
<div class="txt-box">
hello world 5
</div>
</div>
<div class="container">
<div class="txt-box">
hello world 6
</div>
</div>
</div>
</div>
</body>
</html>
What am I not understanding about flex-grow?
Flex properties don't work on absolutely positioned children of a flex container.
ยง 4.1. Absolutely-Positioned Flex
Children
As it is out-of-flow, an absolutely-positioned child of a flex
container does not participate in flex layout.
Therefore, flex-grow: 1 on txt-box is not doing anything. It's just being ignored.
Considering that you want the image simply laying in the background, while the text box has more requirements, I would suggest absolutely positioning the image and leaving the text box in the normal flow.
Then give the text box full width and height, with equal padding on the primary container to keep uniform "margins" across screen sizes.
Here's a demo, with a few extra features to help illustrate the concepts involved.
body {
height: 100vh;
display: flex;
margin: 0;
padding: 10px;
}
.container {
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
position: relative;
border: solid 2px red;
}
img {
position: absolute;
height: 100%;
width: 100%;
object-fit: contain; /* also try 'cover' for demo */
}
.txt-box {
z-index: 1;
width: 100%;
height: 100%;
border: solid 2px blue;
background-color: rgba(192,192,192,0.5);
}
* {
box-sizing: border-box;
}
<div class="container">
<img src="http://i.imgur.com/60PVLis.png">
<div class="txt-box">hello world</div>
</div>
jsFiddle demo

How to have each item in my flex row remain square (same width as height) without using JavaScript [duplicate]

This question already has answers here:
Responsive Square Divs Cross Browser Compatible
(3 answers)
Closed 5 years ago.
I'd like these letters to sit in the row, each letter div with same height and width. This is my demo of the problem https://codepen.io/danielyaa5/pen/BZRVyo
.container {
display: flex;
flex-direction: row;
background: cyan;
width: 50%;
}
.letter {
border: 1px solid black;
text-align: center;
}
<div class="container">
<div class="letter">A</div>
<div class="letter">B</div>
<div class="letter">C</div>
<div class="letter">D</div>
<div class="letter">E</div>
<div class="letter">F</div>
</div>
This is what I'd like to see: https://codepen.io/danielyaa5/pen/XgRYbE
Notice that divs have same height and width. Here though I manually set height and width to 50px, in my real life scenario I will not know the width because its dynamically set to a screen size percent. I was able to create a JavaScript solution but it increased the load time heavily in my actual app.
.container {
display: flex;
flex-direction: row;
background: cyan;
width: 50%;
}
.letter_wrap{
display: inline-block;
position: relative;
width: 20%;
}
.letter_wrap:after{
content: '';
display: block;
margin-top: 100%;
}
.letter {
border: 1px solid black;
display:flex;
align-items:center;
justify-content:center;
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
}
<div class="container">
<div class="letter_wrap">
<div class="letter">A</div>
</div>
<div class="letter_wrap">
<div class="letter">B</div>
</div>
<div class="letter_wrap">
<div class="letter">C</div>
</div>
<div class="letter_wrap">
<div class="letter">D</div>
</div>
<div class="letter_wrap">
<div class="letter">E</div>
</div>
</div>

Vertically & horinzontally align multiple div children in container

I currently have the following code:
<div id="container">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
</div>
<style>
#container{
width:100%;
height:100%;
overflow-y:auto;
position:absolute;
left:0; top:10px;
padding:10px;
}
.card{
width:100px; height:100px; margin:10px;
float:left;
}
</style>
I am trying to vertically and horizontally align the div boxes so that the more boxes that appear, it still stays both vertically and horizontally centred in the container. For example:
Example of what it would look like with 4 cards which fit in the container..
Example of what it would look like with 12 cards which overflow in the container..
Example of what it would look like with cards that dont fit in the container..
DEMO
HTML
<div class="container">
<div class="container-wrapper">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
</div>
CSS
.container {
position: relative;
display:table;
background: red;
width:100%;
height: 100%; /* auto is default, you can have ur height here */
}
.container-wrapper {
display: table-cell;
margin:auto;
text-align:center;
font-size:0;
width:90%;
height:90%;
vertical-align:middle;
}
.card {
display: inline-block;
height:100px;
width:100px;
border: 1px solid #ddd;
background: #eee;
margin:10px;
}
DEMO 2 with some height of the container
Try Flexbox DEMO
#container {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
min-height: 100vh;
margin: 0 auto;
flex-wrap: wrap;
box-sizing: border-box;
}
.inner {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
max-width: 750px;
margin: 0 auto;
flex-wrap: wrap;
}
.card{
width:100px;
height:100px;
margin:10px;
border: 1px solid black;
}
<div id="container">
<div class="inner">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">3</div>
<div class="card">4</div>
</div>
</div>
You may not be able to use external libraries for your project, but there is still much to learn from them in my opinion.
Your situation is a basic example of how a grid system can be useful. In deed, this problem has been solved and equated many times before by such systems.
Normally I would suggest Twitter Bootstrap 3, but since this framework is somewhat complex, I think it would be easier to read something more lightweight, like 960 grid system. Here are two links that can give you a brief introduction into the library:
http://sixrevisions.com/web_design/the-960-grid-system-made-easy/
http://webdesign.tutsplus.com/articles/using-the-960-grid-system-as-a-design-framework--webdesign-2036
Once you understand this, IMO, you have no other choice than to dive into the framework and see how it is done. It will be messy.
I also believe you will have to use JavaScript. Can you use jQuery?
Either way, when adding a new card, detect it using JavaSctipt, and then change the DOM based on that.
Hope I helped.