TL;DR: Here's a CodePen.
I have a UI with an image and a grid of text with long lines which looks like this:
I'm using CSS Flexbox with two elements: the image and the text. And then to lay out the text, I'm using CSS Grid. Now, when I view this on a narrow screen for mobile, it correctly wraps everything and stacks the two elements:
But on desktop, with a slightly narrower div, the flex box wraps before the grid text like this:
How can I get the text to wrap while leaving the flex box alone in this case? I fear I may need to use some media queries, but I'm not even sure if I'm using the right CSS components for this.
Here's the code:
index.html:
<div class="media-callout">
<div class="media-thumb">
<img height="170" width="120">
</div>
<div class="media-callout-grid">
<div class="media-callout-key">Authors</div>
<div>Babalola, J & Ogunkola, Babalola</div>
<div class="media-callout-key">Year</div>
<div>2013</div>
<div class="media-callout-key">Title</div>
<div class="media-callout-value">Scientific Literacy: Conceptual Overview, Importance and Strategies for Improvement</div>
<div class="media-callout-key">Journal</div>
<div><em>Journal of Educational and Social Research</em></div>
<div class="media-callout-key">Location</div>
<div>vol. 3, no. 1, pp. 265–274</div>
<div class="media-callout-key">DOI</div>
<div>10.5901/jesr.2013.v3n1p265</div>
</div>
</div>
style.css:
.media-callout {
display: flex;
flex-wrap: wrap;
justify-content: center;
row-gap: 20px;
column-gap: 10px;
padding: 1em;
max-width: max-content;
}
.media-thumb img {
float: left;
height: 175px;
width: auto;
}
.media-callout-grid {
display: grid;
font-size: 12pt;
grid-template-columns: 6em 1fr;
align-content: center;
gap: 0 15px;
}
.media-callout-key {
text-align: right;
font-weight: bold;
}
.media-callout-value {
word-break: break-word;
word-wrap: break-all;
}
A media query does indeed resolve this:
#media screen and (min-width: 600px) {
.media-callout {
flex-wrap: nowrap;
}
}
The query must come AFTER the .media-callout block. I also had to use this approach to prevent the image from being squashed.
I finished my website but I didn't realize that safari doesn't support the flexbox gap. Is there a way around this without having the mess anything up? This is mostly for my media queries.
<div class="social-media">
<a href="https://github.com/">
<img class="social-media__icon" src="img/github.png" alt="Github">
</a>
<a href="https://www.linkedin.com/">
<img class="social-media__icon" src="img/linkedin.png" alt="LinkedIn">
</a>
</div>
.social-media {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
gap: 8rem;
margin-top: 10rem;
padding-bottom: 2rem;
}
.social-media img {
width: 90px;
height: 90px;
}
#media only screen and (max-width: 400px) {
.social-media {
gap: 3rem;
margin-top: 5rem;
}
.social-media img {
width: 62px;
height: 62px;
}
}
Use the Lobotomized owl selector: .parent > * + * {} to add a margin-left that gives you space between the elements that come after another element, this way you eliminate the undesired margin it creates when you put the margin directly to the child's first element (.social-media img{})
.social-media > * + * { margin-left: 8rem;}
Here you can read more about the Lobotomized Owl Selector
Edit: Gap is now supported in safari so you should be able to use it no problem.
Property gap with display: flex is not supported by Safar version < 14 https://caniuse.com/flexbox-gap .
You might want to replace display flex with grid:
display: grid;
grid-gap: 8rem; /* Safari 10-11 */
gap: 8rem; /* Safari 12+ */
because grid's gap is supported in older Safari versions: https://caniuse.com/mdn-css_properties_gap_grid_context
The accepted answer has the problem, that you will have a wrong margin on the first element if when there is only one row. Also centered elements will always be 8rem too far the right.
Better solution that will always work with correct spacings:
.container {
display: flex;
// the trick is to set margins around boxes, but correct the margins around elements that are situated at the border of the container with negative margins
margin: 0 -10px -20px -10px;
}
.box {
min-width: 100px;
height: 100px;
background-color: deeppink;
margin: 0 10px 20px 10px;
}
<div class='container'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
<div class='box'>4</div>
</div>
You can remove the gap class and add another one to child elements
<div class="d-flex"> // it was "d-flex gap" previously
<div class="mx-2">
//content
</div>
<div class="mx-2">
//content
</div>
</div>
I think you could make a div container and put justify-content: space-between; then i think it should work
Image captions are aligned bottom by flexbox within a gallery where images have different heights. How can I achieve that first lines of text (titles) are aligned horizontally?
<style type="text/css">
* {
box-sizing: border-box; }
.flex-container {
display: flex;
flex-wrap: wrap; }
.flex-item {
width: 50%;
padding: 20px;
display: flex;
flex-direction: column; }
.flex-item img {
width: 100%;
height: auto; }
.flex-image {
flex: 1 0 auto; }
</style>
<div class="flex-container">
<div class="flex-item">
<div class="flex-image">
<img src="img-1.jpg" alt="" />
</div>
<p>title</p>
</div>
<div class="flex-item">
<div class="flex-image">
<img src="img-2.jpg" alt="" />
</div>
<p>title<br>Lorem ipsum dolor sit amet.</p>
</div>
</div>
Please check my codepen: https://codepen.io/tinusmile/pen/MoeORG
Many thanks!
With the existing markup, where the images can have different heights, you need to do something like this, where you give the p a height.
As an element's overflow defaults to visible, it will flow out of its boundaries, so I recommend to set the height so it can accommodate 2-3 lines of text.
On smaller screens you might need to add a #media query to adjust that height, as if the text is very long it might overflow any element below itself.
.flex-item p {
height: 50px; }
Updated codepen
Note, using min-height instead would solve the might overflow any element below itself issue, though it will make the first line to not align horizontally if the value does not accommodate all the possible amount of lines.
Another option is to remove the flex-item wrapper and use Flexbox's order property, as I suggested in a previous question of yours, align-horizontally-3-elements-over-3-divs
I am trying to make a nice layout of items in a grid using a bin packing algorithm like packery or masonry. I Already have isotope installed so will use the packery plugin for that.
If you look at the example here http://codepen.io/desandro/pen/vdwmb this is exactly the kind of thing I need, but the problem I think I'm going to face is the content of the items are via a CMS.
<h1>Isotope - packery layout mode</h1>
<div class="grid">
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--width2 grid-item--height2"></div>
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
* { box-sizing: border-box; }
body { font-family: sans-serif; }
/* ---- grid ---- */
.grid {
background: #DDD;
max-width: 1200px;
}
/* clear fix */
.grid:after {
content: '';
display: block;
clear: both;
}
/* ---- .grid-item ---- */
.grid-item {
float: left;
width: 100px;
height: 100px;
background: #0D8;
border: 2px solid #333;
border-color: hsla(0, 0%, 0%, 0.7);
}
.grid-item--width2 { width: 200px; }
.grid-item--height2 { height: 200px; }
$('.grid').isotope({
layoutMode: 'packery',
itemSelector: '.grid-item'
});
Possibly more of a maths question, but Im assuming for packery to work the items all have to be of a size in relation to each other, ie in the example above all the items are multiples of the smallest item.
Is this assumption correct, and is there anything else i need to consider?
I have a strange issue using flexslider. The Slide LIs don't get the correct width so that all slides are shown. This only occurs on first page load. As soon as I switch to another tab and switch back everything looks fine. Maybe a JS Loading Problem?!
Screenshot: here
flexslider.css
.flexslider {margin: 0; padding: 0;}
.flexslider .slides > li {text-align: center; display: none; -webkit-backface-visibility: hidden;} /* Hide the slides before the JS is loaded. Avoids image jumping */
.flexslider .slides li.flex-active-slide img {text-align:center; width: auto; -webkit-border-radius: 6px; -moz-border-radius: 6px; -o-border-radius: 6px; border-radius: 6px; box-shadow: 0 1px 4px rgba(0,0,0,.2); -webkit-box-shadow: 0 1px 4px rgba(0,0,0,.2); -moz-box-shadow: 0 1px 4px rgba(0,0,0,.2); -o-box-shadow: 0 1px 4px rgba(0,0,0,.2); }
JS
$(window).load(function() {
$('.flexslider').flexslider({
controlNav: true,
directionNav: true
});
});
I've tried it with $(document).ready(function() too, but still the same problem.
Any ideas?
Well, Werner.
I ended up with your solution. Unfortunately.
This is otherwise another way to do it.
/* SLIDERS in content */
$('.flexslider').flexslider({
animation: "slide",
start: function(slider){
$('.flexslider').resize();
}
});
The reason I chose not to use the above code is that there was a delay and made a little jump when the slides updated to the correct width.
If anyone has a cleaner solution - please tell me. I am using the latest flexslider there is - and this issue only seems to occur sometimes. But when it does... arghhh.
I had the same problem.
At first load in a session, Flexslider get the width of the slider container which, if it is not explicit, has value 0px.
Then slides have width 0px and you can't see them.
To avoid this problem is sufficient to fix a width in slider container, in my case 604px:
<div class="flexslider" style="width: 604px">
<ul class="slides">
<li>
<img id="slide1" />
</li>
<li>
<img id="slide2" />
</li>
</ul>
</div>
I faced the same issue with flexi slider.
Tried above mentioned solutions, but it didn't work for me.
I tried to updated css with following code as turn-around for this issue.
.flexslider .slides {
zoom: 1.1 !important;
}
It fixed the problem. You can try this code and let me know if it worked for you or not.
This code/order below may help; well at least I have had success with it.
<script src="js/jquery-1.8.3.min.js"></script>
<script src="js/jquery.easing.js"></script>
<script defer src="js/jquery.flexslider-min.js"></script>
<script>
$(document).ready(function(){
$('.flexslider').flexslider({
controlNav: true,
directionNav: true,
});
});
</script>
I resolved this issue by removing minItems in my flexslider call. Seems to work with maxItems though.
I found out why it was doing this, and it is pretty simple.
It is because of CSS!!! on the ul in the slider.
take off the paddings and the margins on the ul.slides
.slides{
padding:0;
margin:0;
}
after i did THIS the resizing worked perfect every time on all browsers and mobile.
For me, the problem was the markup. I had this:
<div class='carousel-slides'>
<div class='carousel-slide'></div>
<div class='carousel-slide'></div>
</div>
$('.carousel-slides', context).flexslider({
selector: '.carousel-slide'
});
... but it seemed that it needed to be applied to an inner div on each slide, which is ridiculous.
<div class='carousel-slides'>
<div class='carousel-slide'>
<div class='carousel-slide-inner'></div>
</div>
<div class='carousel-slide'>
<div class='carousel-slide-inner'></div>
</div>
</div>
$('.carousel-slides', context).flexslider({
selector: '.carousel-slide > .carousel-slide-inner'
});
Maybe it's a bit late for another answer, but after trying all the answers here and in other forums, I ended up with my own solution, similar to others, but at least I find it pretty coherent and clean.
I had the problem in mobile environment, where the slider is inside a tab that is opened as soon one clicks on the title. The content was in display:none, and this causes the problem to flexslider (v. 2.5), that is not able to determine the correct width of the contained slides.
So i corrected my css and put the container hidden by playng with visibility and opacity.
Html sampl
<dd class="tab-container with-slider">
<div class="flexslider">
<ul class="slides">
<li>whatever </li>
</ul>
</div>
</dd>
Css:
/*all other containers behave well with display none/block so I leave them with normal behavior*/
.parent dd.tab-container {
display: none; position: relative;
}
/*container with flexslider inside uses visibility and opacity to be hidden*/
.parent dd.tab-container.with-slider{
display: block;
height: 0px;
visibility: hidden;
opacity: 0;
}
.parent.accordion-open dd.tab-container.with-slider{
height: auto;
visibility: visible;
opacity: 1;
}
Js is straighforward from the basic example, nothing more.
$j('.myTabOpener').click(function () {
var mySlider = $j(this).find('.flexslider');
mySlider.flexslider({
animation: "slide",
animationLoop: false,
itemWidth: 210,
itemMargin: 5,
minItems: getGridSize(),
maxItems: getGridSize()
});
});