How to make text in Flexbox, not defining width of flexbox? - html

I have this issue: I have flexbox with 3 photos in the center of the screen.
under these photos, I have some text like mobile number etc.
When I add this text into this boxes, this text is defining the width of my box, and it's moving boxes and they are not in the center anymore.
Final result should be: The box width should be the same but text should break and be centered.
Here you can see size of one box
Here you can see size od the other box
Snippet:
.ikony {
padding-top: 60px;
display: inline-flex;
justify-content: center;
width: 100%;
font-weight: 600;
font-size: 16px;
color: #020E46;
text-align: center;
font-family: Open Sans,Arial,sans-serif;}
.column {
padding: 90px 70px 0px 70px;}
<div class="ikony">
<div class="column prvy">
<img src="img/mobil-icon.png" alt="iconka-mobil" width="100px" height="100px">
<div class="txtpod">
<p>+421 918 000 000</p>
</div>
</div>
<div class="column">
<img src="img/pin-icon.png" alt="ikona pinu" width="100px" height="100px">
<div class="txtpod">
<p>address 273/14, Svit</p>
</div>
</div>
<div class="column">
<img src="img/email.png" alt="ikona pinu" width="100px" height="100px">
<div class="txtpod">
<p>myemail#gmail.com</p>
</div>
</div>
</div>
Thanks for any advice

Add flex-grow: 0 and width: 33% to the flex items (.column) to prevent them to get wider.
However, if you have something like an email address in one of the containers that forces it to be wider than 33% because it contains no spaces and therefore can't break into several lines (like in your snippet example), you should use a small font that lets it fit into the 33% width.

Related

Specific columns

I've been doing some stuff with HTML and I need to have a few columns. I know how to make them and the basics of how they work. However, there is a certain problem that I have. I need to have 3 columns that have an image on top, then text on bottom. However, the text on bottom can't flow into the next column if the browser is resized - it just needs to go up or down. What I have so far:
body {
background-color: white;
font-family: times, serif;
color: black;
}
div {
display: flex;
margin: 50px;
flex-wrap: wrap;
}
<div>
<div class="first">
<img src="Images/australia_flag.jpg" alt="Australian Flag" title="Australian Flag" height="200" width="300"> text as well </div>
<div class="second">
<img src="Images/brazil_flag.jpg" alt="Brazilian Flag" title="Brazilian Flag"> even more text </div>
<div class="third">
<img src="Images/china_flag.jpg" alt="Chinese Flag" title="Chinese Flag" height="200" width="300"> text again
</div>
</div>
not entirely sure if you mean columns or rows? Based on your code, it looks like rows. If that's the case, I'm not sure what you mean by "flow into the next column"? You might check out the relative and absolute values for CSS position.
If, in fact, you do actually mean columns, I'd strongly advise using Bootstrap's Grid System. This is great for creating responsive columns.
Please take a look at this simple 3 column layout with a full width content area on top and bottom here: https://jsfiddle.net/7drfva0o/2/
.top, .bottom {
width:98%;
padding:1%;
background-color: red;
clear:both;
}
.cols {
width:31%;
padding:1%;
float:left;
background-color:blue;
border: 1px solid #FFF;
}
Is that what you're looking for?
First, you'll need to improve your markup: having images and texts as DOM node to be "flexed"
HTML markup improved
<div class="wrapper">
<div class="column">
<img src="..." />
<p>text</p>
</div>
<div class="column">
<img src="..." />
<p>text</p>
</div>
<div class="column">
<img src="..." />
<p>text</p>
</div>
</div>
Then, each of your div is going to have display: flex + flex-direction: column to allow the image going on top and the text going below. You will be able to adjust margin or whatever. At the minimum, I'd go like this:
CSS improved
.wrapper {
display: flex;
}
.column {
margin: 5px;
display: flex;
flex-direction: column;
}
Wrapped altogether, here is a snippet of what I think you're trying to achieve
Snippet
.wrapper {
display: flex;
}
.column {
margin: 5px;
display: flex;
flex-direction: column;
}
<div class="wrapper">
<div class="column">
<img src="http://fakeimg.pl/300x200" />
<p>text as well</p>
</div>
<div class="column">
<img src="http://fakeimg.pl/300x200" />
<p>text as well</p>
</div>
<div class="column">
<img src="http://fakeimg.pl/300x200" />
<p>text as well</p>
</div>
</div>
Then, feel free to play with flexbox properties to align, wrap, adjust alignments, etc. Great documentation on CSS-Tricks : https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Lazy load column images without reflow or orphaned margins

I've seen fixes for individual parts of this problem but not one for a collective solution. I can solve everything without resorting to javascript formatting except for margins from elements being carried over to the top of the next column (I can't understand why it hasn't been fixed but it appears to be a bug in css3 for some time that's impeding compositing layouts 1, 2)
I've a responsive div container broken into three columns (though this can change depending on the width of the page, per responsive layout), containg divs with a varying number of nested images of varying aspect ratios that each have a margin-bottom property. The above problem is very apparent so I'm looking for a solution to this.
Typically the suggestion involves the use of a column-break-inside: avoid; property alongside switching my margin-bottom to padding-bottom. This hack has seen some success with others and this is where I point you to the subject of my question. I cannot implement this as I'm using a seperate hack to prevent reflow of images that are lazy loaded (using the lazy sizes plugin*) into the columns (the padding-bottom as a ratio hack, 3).
So if I use padding-bottom to ensure that my column elements align without orphaned margins, I lose the ability to correct the reflow from lazy loading the elements into the columns. I can't use fixed sized elements as the column layout is responsive and the elements shrink and enlarge dynamically with the column size.
Is there anybody who has succeeded in solving both issues simultaneously without javascript formatting?
I'm keen to stick to this particular lazy loading plugin for reasons outside of the scope of this problem.
HTML Code:
<div id='columncontainer'>
<div class='imagecontainer' style='padding-bottom:reflowPaddingAmountFromPHPvar;'>
<img class='lazyload'>
<div class='imagetextcontainer'>
<div class='vertaligncontainer'>
<p class='imagename'>Text</p>
<p class='imagedesc'>Text</p>
</div>
</div>
</div>
</div>
CSS Code:
#myContent {
position: relative;
width: 100%;
column-count: 3;
column-gap: 20px;
column-break-inside: avoid;
-moz-column-break-inside:avoid;
-webkit-column-break-inside:avoid;
}
.imagecontainer {
position: relative;
margin-bottom: 20px;
img {
position: absolute;
top: 0;
left: 0;
height: auto;
width: 100%;
}
}
Example jsFiddle:
https://jsfiddle.net/g0yjd9ov/1/
The elements should align at the top of each column but, instead, the margin-bttom on the element (imagecontainer) at the bottom of the first or second column is being carried over to the second or third column and orphaned, giving the impression of the next element having a margin-top value and breaking the top alignment. This serves no benefit to any situation that a deliberate margin-top value couldn't recreate. I've randomised the heights of the elements just for this example, so occasionally the problem won't show (emphasising how much of a nuisance it is. It's hard to deliberately show). Just refresh if it doesn't, as it occurs quite frequently.
This can be solved using an extra container that has padding on it. The container for the image (.imagecontainer) should contain only the image, as that is what its aspect ratio is set up for. The space between a block and the next block in the column can be achieved by setting a padding on that block. The block then gets the styling that prevents column breaks from occurring.
I have created a demo that builds upon the example code in the question, but also includes some things that are only described in the question text. This because I wanted to make sure that everything works the way I think it should (let me know if I misinterpreted the question).
In particular, I added the lazy sizes plugin and let it load some placeholder images. I also added some styling and added blocks that contain more than just a single image. For the rules that prevent breaks inside an element, I used some slightly different ones, as per this answer. Finally, I positioned the .imagetextcontainer as discussed in the question comments.
The demo can be found on JSFiddle. I also include it as a code snippet here.
#columncontainer {
width: 100%;
column-count: 3;
column-gap: 10px;
}
.block-wrap {
width: 100%;
padding-bottom: 10px;
/* prevent column breaks in item
* https://stackoverflow.com/a/7785711/962603 */
-webkit-column-break-inside: avoid; /* Chrome, Safari */
page-break-inside: avoid; /* Theoretically FF 20+ */
break-inside: avoid-column; /* IE 11 */
display:table; /* Actually FF 20+ */
}
.block {
width: 100%;
background-color: #ffff7f;
}
.block > p {
margin: 0;
padding: 10px;
}
.imagecontainer {
position: relative;
width: 100%;
height: 0;
background-color: #a00;
}
.imagecontainer > img {
width: 100%;
}
.imagetextcontainer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<script src="https://afarkas.github.io/lazysizes/lazysizes.min.js"></script>
<div id='columncontainer'>
<div class="block-wrap">
<div class="block">
<div class='imagecontainer' style='padding-bottom: 50%;'>
<img class='lazyload'
data-sizes='auto'
data-srcset='https://placehold.it/100x50/a00/fff 100w,
https://placehold.it/200x100/050/fff 200w,
https://placehold.it/400x200/057/fff 400w' />
<div class='imagetextcontainer'>
<div class='vertaligncontainer'>
<p class='imagename'>Name</p>
<p class='imagedesc'>Description</p>
</div>
</div>
</div>
<p>Some text. Followed by another figure.</p>
<div class='imagecontainer' style='padding-bottom: 100%;'>
<img class='lazyload'
data-sizes='auto'
data-srcset='https://placehold.it/100x100/a00/fff 100w,
https://placehold.it/200x200/050/fff 200w,
https://placehold.it/400x400/057/fff 400w' />
<div class='imagetextcontainer'>
<div class='vertaligncontainer'>
<p class='imagename'>Name</p>
<p class='imagedesc'>Description</p>
</div>
</div>
</div>
</div>
</div>
<div class="block-wrap">
<div class="block">
<div class='imagecontainer' style='padding-bottom: 50%;'>
<img class='lazyload'
data-sizes='auto'
data-srcset='https://placehold.it/100x50/a00/fff 100w,
https://placehold.it/200x100/050/fff 200w,
https://placehold.it/400x200/057/fff 400w' />
<div class='imagetextcontainer'>
<div class='vertaligncontainer'>
<p class='imagename'>Name</p>
<p class='imagedesc'>Description</p>
</div>
</div>
</div>
<p>Some text. No figure here.</p>
</div>
</div>
<div class="block-wrap">
<div class="block">
<p>Only text here.</p>
</div>
</div>
<div class="block-wrap">
<div class="block">
<div class='imagecontainer' style='padding-bottom: 50%;'>
<img class='lazyload'
data-sizes='auto'
data-srcset='https://placehold.it/100x50/a00/fff 100w,
https://placehold.it/200x100/050/fff 200w,
https://placehold.it/400x200/057/fff 400w' />
<div class='imagetextcontainer'>
<div class='vertaligncontainer'>
<p class='imagename'>Name</p>
<p class='imagedesc'>Description</p>
</div>
</div>
</div>
</div>
</div>
<div class="block-wrap">
<div class="block">
<div class='imagecontainer' style='padding-bottom: 100%;'>
<img class='lazyload'
data-sizes='auto'
data-srcset='https://placehold.it/100x100/a00/fff 100w,
https://placehold.it/200x200/050/fff 200w,
https://placehold.it/400x400/057/fff 400w' />
<div class='imagetextcontainer'>
<div class='vertaligncontainer'>
<p class='imagename'>Name</p>
<p class='imagedesc'>Description</p>
</div>
</div>
</div>
</div>
</div>
<div class="block-wrap">
<div class="block">
<p>Only text here.</p>
<p>Tow lines now.</p>
</div>
</div>
<div class="block-wrap">
<div class="block">
<div class='imagecontainer' style='padding-bottom: 200%;'>
<img class='lazyload'
data-sizes='auto'
data-srcset='https://placehold.it/100x200/a00/fff 100w,
https://placehold.it/200x400/050/fff 200w,
https://placehold.it/400x800/057/fff 400w' />
<div class='imagetextcontainer'>
<div class='vertaligncontainer'>
<p class='imagename'>Name</p>
<p class='imagedesc'>Description</p>
</div>
</div>
</div>
</div>
</div>
</div>
After a lot of back and forth I came up with an answer that fixes the problem and maintains the original's CSS properties. There seems to have been two problems causing this.
1 - margins were translating into the next column (but the element was staying into its own column)
2 - height was confined (was a problem in the solution)
solution: since the entire element stays in its own column but the margin is technically not part of the element (it can be tested using outline)
this problem can be solved by placing .imagecontainer into another div which has padding instead of margin. (so then its considered one object so the margin problem is avoided)
you also would need to move column-break-inside to the parent element so it registers without the margin.
a live version can be found at: https://jsfiddle.net/36pqdkd3/6/
Here is a solution using flex-boxes
HTML
<div id='columncontainer'>
<div class='imagecontainer'>
<img class='lazyload'>
<div class='imagetextcontainer'>
<div class='vertaligncontainer'>
<p class='imagename'>Text</p>
<p class='imagedesc'>Text</p>
</div>
</div>
</div>
<div class='imagecontainer'>
<img class='lazyload'>
<div class='imagetextcontainer'>
<div class='vertaligncontainer'>
<p class='imagename'>Text</p>
<p class='imagedesc'>Text</p>
</div>
</div>
</div>
<div class='imagecontainer'>
<img class='lazyload'>
<div class='imagetextcontainer'>
<div class='vertaligncontainer'>
<p class='imagename'>Text</p>
<p class='imagedesc'>Text</p>
</div>
</div>
</div>
<div class='imagecontainer' style=''>
<img class='lazyload'>
<div class='imagetextcontainer'>
<div class='vertaligncontainer'>
<p class='imagename'>Text</p>
<p class='imagedesc'>Text</p>
</div>
</div>
</div>
</div>
CSS
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#columncontainer {
position: relative;
width: 100%;
display: flex;
height: 40%;
/* use this if you want containter wrapping
flex-wrap: wrap; */
/* use this if you want container scrolling
overflow: auto; */
/* use this if you want container scrolling
justify-content: center; */
}
.imagecontainer {
min-width: 250px;
position: relative;
background-color: red;
overflow: hidden;
height: 100%;
margin: 5px;
z-index: 1;
}
example in jsfiddle
Here are some recommendations based on your question.
I would also recommend learning more about flex-boxes, that is very equipped to handle these kinds of situations.
by default the html and body elements default size is width 100% and no height.
here is a reference I use on flex-boxes
addressing aspect ratio
you can handle aspect ratio using px and vw/vh (measurements of DOM width and height). try playing around with min/max/width to find the perfect amount.
(1:2 aspect ratio)
element {
min-width: 10vw;
min-height: 20vh;
width: 50px;
height: 100px;
}
css size units
in my version you can edit ".imagecontainer".

Centering 2 images with label in a row in Bootstrap

The goal is that I want both images to have be side by side and centered in the middle of the row.
I tried to do that via adjusting the columns of the row
The problem is that even with trying to center via rows, it always looks a little off center and if I change the max-width to be a little bigger, the images are no longer side by side and are on top of one another
The height and width of the images are...
graft1/graft2 - height="333" width="500"
ivan1/ivan2 - height="542" width="400"
Here is my HTML
<section class="wrapper style1">
<div class="container">
<div id="content">
<!-- Content -->
<article>
<header>
<h2>Before and After</h2>
</header>
<div class="row">
<div class="div_baPics">
<img id="graft1" class="baPics" src="images/graft1.jpg" alt="">
<label for="graft1">Before</label>
<img id="graft2" class="baPics" src="images/graft2.jpg" alt="">
<label for="graft2">After</label>
</div>
</div>
<div class="row">
<div class="div_baPics">
<img id="ivan1" class="baPics" src="images/ivan1.jpg" alt="">
<label for="ivan1">Before</label>
<img id="ivan2" class="baPics" src="images/ivan2.jpg" alt="">
<label for="ivan2">After</label>
</div>
</div>
</article>
</div>
</div>
</section>
And here is the CSS for baPics
.baPics {
max-width: 30%;
}
.div_baPics {
text-align: center;
}
Since you're using Bootstrap, I went with its system. See this fiddle :
http://jsfiddle.net/Bladepianist/55gyp94n/
Well, i did use real image so that you could see the result but with that (when I tested anyway), your image should resize, following the screen.
.thumbnail {
border: none;
}
This code isn't needed, unless you don't want the border of the thumbnail ;).
Hope it will satisfy you and if that's the case, thumbs up :p.
You need to wrap img and corresponding label in a wrapper, like so:
/*Just to make a difference between pics*/
body {
background: grey;
}
/*Minimal CSS*/
.div_baPics {
text-align: center; /*Center alignment for the wrapper*/
font-size: 0; /*To remove the white space between pics*/
}
.pic {
display: inline-block;
}
.pic img {
display: block;
/*This should be set by default by Bootstrap*/
max-width: 100%;
height: auto;
}
.pic label {
display: block;
font-size: 16px; /*Or whatever font-size you use*/
}
<div class="div_baPics">
<div class="pic">
<img src="http://i.imgur.com/zNTWaR3.jpg" />
<label>Pic 1</label>
</div>
<div class="pic">
<img src="http://i.imgur.com/IqiJN2f.png" />
<label>Pic 2</label>
</div>
</div>

Alignment error

I have a bilingual page which is basically two columns with English text on the left and French on the right. The CSS for this is as follows:
div.ltext
{
margin: 10px 30px 0 60px;
line-height: 130%;
width:390px;
font-size:10pt;
font-weight:normal;
text-align:justify;
overflow:hidden;
float:left;
}
div.rtext
{
margin: 10px 60px 0 30px;
padding-left:30px;
line-height: 130%;
width:390px;
font-size:10pt;
font-weight:normal;
text-align:justify;
overflow:hidden;
}
At intervals the text is interspersed with an image (centered). The CSS of the images is as follows:
.pic
{
width:390px;
margin: 10px auto 10px auto;
}
The HTML looks like this:
<div class="ltext"><p>This grouping...</p></div>
<div class="rtext"><p><i>Cette plantation...</i> </p></div>
<div class="pic"><a onclick="loadImage('gdCG2013Jan05.jpg')" href="#4">
<imgwidth="390" border="0" src="gdCG2013Jan05tn.jpg"></img></a></div>
<div class="ltext"><p>Next,... </p></div>
<div class="rtext"><p><i>Suivant...</i> </p></div>
The problem is that whenever an image division (.pic) is inserted, the following text blocks are out of alignment (the French text on the right is approximately one line higher than the English. If I remove the image so that there are two consecutive blocks of bilingual text like this:
<div class="ltext"><p>This grouping...</p></div>
<div class="rtext"><p>Cette plantation...</p></div>
<! div class="pic"> removed
<div class="ltext"><p>Next...</p></div>
<div class="rtext"><p>Suivant deux...</p></div>
the alignment of the second set of blocks is correct. The problem is also corrected if I insert a dummy spacer division 1 pixel high between the image division and the following text divisions, thus:
.spacer {width:960px; height:1px; }
<div class="pic"> etc..</div>
<div class="spacer"> </div>
<div class="ltext"> etc... </div>
<div class="rtext"> etc. </div>
This last is a simple enough workaround but I would like to know what's going wrong here. (By the way, enclosing the following text blocks in a wrapper division doesn't solve the problem).
Create a container for the divs you dont want to move.
<div>
<div class="ltext"><p>This grouping...</p></div>
<div class="rtext"><p><i>Cette plantation...</i> </p></div>
</div>
<div class="pic"><a onclick="loadImage('gdCG2013Jan05.jpg')" href="#4">
<img width="390" border="0" src="gdCG2013Jan05tn.jpg"></img></a></div>
<div>
<div class="ltext"><p>Next,... </p></div>
<div class="rtext"><p><i>Suivant...</i> </p></div>
</div>
Your JSFiddle example does not have any image, but I suppose from what you've said the problem is that other elements appearing are moving the elements already existing.

Inner padding in a gallery of images

So, I have this gallery function that just shows images in a grid. I am currently using TABLE, but I want to move over to CSS in order to use width 100% on the images, so it scales nicely.
Right, so best explained by looking at this page: http://sandman.net/test/css_gallery.php
The blue border is on the outer DIV and the images are kept within to layers of DIV's. The code looks something like this:
<div class="thumbs">
<div class="thumb">
<div class="inner">
<img />
</div>
</div>
<div class="thumb">
<div class="inner">
<img />
</div>
</div>
</div>
And so on. And the stylesheets are currently this:
<style type='text/css'>
.thumbs {
width: 400px;
border: 1px solid blue;
overflow: hidden;
}
.thumb {
width: 25%;
float: left;
}
.thumb > .inner {
padding: 0 10px 10px 0;
}
</style>
SO - to my problem. As you can see, the padding is currently 10px, which it should be. But not on the fourth column!! Basically, I want the images to be four columns with three whitespace columns in between. As they are now, each .thumb contains an image with 90px width calculated and 10px padding to the right. But, they should instead be 92.5 pixels wide and be evenly spaced.
Because - one problem is that I can't sett different margins on the first three and the fourth column since then the 100% width image would change size, which is not desirable. So the padding has to somehow be applied uniformly over all the images.
So, do you have a good way to do it? :)
You can also add a container div in tumbs div that contains all the tumb divs and give this container a negative margin to compensate for the padding on the edges of the thumb divs, not a beautiful solution but it works in all browsers, even that one that rhymes with nternet xplorer. :)
<div class="thumbs">
<div class="container">
<div class="thumb">
<div class="inner">
<img />
</div>
</div>
<div class="thumb">
<div class="inner">
<img />
</div>
</div>
</div> <!--container-->
</div>
<style type='text/css'>
.container {
margin: 0 -10px 0 -10px;
}
</style>
Okay, so the simplest fix that I can see is to use just 1 more div and a tiny CSS tweak. Wrap the div.thumbs in another div, like this:
<div class="thumbs-wrapper">
<div class="thumbs>
<!-- same content here as before -->
</div>
</div>
and move the border off the div.thumbs, onto the new wrapper:
.thumbs-wrapper {
border: 1px solid blue;
overflow: hidden;
width: 390px; /* cuts off the pesky extra padding */
}
.thumbs {
width: 400px;
}
The rest of the CSS is unchanged. The result:
No point in using esoteric pseudo-classes... just make your own!
First of all, I'd just set a class to the image directly... no need to have a container on each image. I also think 'margin' is a smarter choice than 'padding,' so the HTML I end up with looks like:
<div class="thumbs">
<div class="thumb">
<img class="inner first" src="" />
</div>
<div class="thumb">
<img class="inner" src="" />
</div>
<div class="thumb">
<img class="inner" src="" />
</div>
<div class="thumb">
<img class="inner last" src="" />
</div>
<div class="thumb">
<img class="inner first" src="" />
</div>
<div class="thumb">
<img class="inner" src="" />
</div>
<div class="thumb">
<img class="inner" src="" />
</div>
<div class="thumb">
<img class="inner last" src="" />
</div>
</div>
etc...
Your math I assume is: (400px wide) - (3 x 10px margin) = 370px / 4 columns = 92.5 px per column... but typically you don't want to work with half of a pixel so I'll use 92px per column, with 368px total width after margins. So then, since you're setting up your own classes for first and last--your stylesheet should look something like:
.thumbs {
width: 398px; // 368px + 30px for margin
border: 1px solid blue; // 1px for each side, results in a total width of 400px
overflow: hidden;
}
.thumb {
width : 92px;
float : left;
}
.inner {
width : 92px;
margin : 0 10px 10px 10px;
}
.first {
margin : 0 10px 10px 0!important; //important should make sure it overrides .inner
}
.last {
margin : 0 0 10px 10px!important; //important should make sure it overrides .inner
}
Now, I haven't tested this but I think it should work... if nothing else, hopefully my strategy is insightful so that you could tailor it to your needs. You could apply the same theory of manually assigning and stacking classes to make sure the top and bottom rows both have 10px on top and bottom respectively.
Hope this helps!