I am trying to create a sort of text carousel.
Heres a sketch of what I want to do:
I have a card and I might have multiple of them.
If there's one I just need it to be neatly centered both vertically and horizontally.
If there's two then try to put them next to one another.
But if there's more than there can be fit on the screen, then I just want the last one to overflow off
All the cards need to retain the same size
This is what I have tried:
Firstly I tried using align-items: flex-start
http://jsfiddle.net/7pdmeh6v/
This works with the logic but the problems are that if I had one item it wouldn't be centered and here I can't change the width.
Secondly I tried using align-items: center
http://jsfiddle.net/hr8ya9fg/
Logic works but
This cuts off the top of the cards and also doesn't let me change
the size of the cards.
Thirdly I removed align-items and just left justify-content: center http://jsfiddle.net/6hdzamq5/
which works with the logic but still doesn't let me change the size of the cards AND also I noticed here that it completely disregards margins and paddings
TLDR:
Flex-box doesn't seem to let me edit the size on any occasion without another problem occurring.
A couple of initial observations:
In a row-direction flex container, which is what you're using, the align-* properties control vertical, not horizontal, space and positioning. So I'm not sure how you plan to solve your horizontal scroll problem using align-items.
The initial value of the flex-shrink property is 1. This means that flex items will shrink in order to stay within the bounds of the container. So when you tell your flex items to be width: 500px, that is not a fixed length. The items can shrink. Add flex-shrink: 0 to disable flex shrink and make the items inflexible.
.container {
display: flex;
height: 240px;
overflow: auto;
margin: 10px;
padding: 10px;
border: 3px solid #000;
}
.box {
width: 500px;
flex-shrink: 0; /* toggle between 1 and 0 to see the differences */
background-color: red;
border: 1px solid #000;
color: #000;
padding: 10px;
}
.box {
margin-left: auto;
margin-right: auto;
}
.box ~ .box {
margin-left: 10px;
}
<div class="container">
<div class="box">
<h2>Heading</h2>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas corporis et nesciunt esse quas eos illum, facere voluptate, iure officiis.
</div>
</div>
<div class="container">
<div class="box">
<h2>Heading</h2>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas corporis et nesciunt esse quas eos illum, facere voluptate, iure officiis.
</div>
<div class="box">
<h2>Heading</h2>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas corporis et nesciunt esse quas eos illum, facere voluptate, iure officiis.
</div>
</div>
<div class="container">
<div class="box">
<h2>Heading</h2>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas corporis et nesciunt esse quas eos illum, facere voluptate, iure officiis.
</div>
<div class="box">
<h2>Heading</h2>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas corporis et nesciunt esse quas eos illum, facere voluptate, iure officiis.
</div>
<div class="box">
<h2>Heading</h2>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas corporis et nesciunt esse quas eos illum, facere voluptate, iure officiis.
</div>
</div>
You'll notice that the last margin / padding collapses. That issue is explained here:
Last margin / padding collapsing in flexbox / grid layout
I'd suggest you looking into flex property which is a shorthand for flex-shrink, flex-grow and flex-basis properties. It would help you to define behavior of your flex-items. (https://www.w3schools.com/cssref/css3_pr_flex.asp)
See the snippet below:
#container {
display: flex;
margin: 10px;
height: 180px;
overflow: auto;
border: 3px solid;
}
.box {
flex: 0 0 320px;
margin: 10px;
background: #9a6;
border: 1px solid;
color: #000;
padding: 10px;
}
<div id="container">
<div class="box">
<h2>Heading</h2>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas corporis et nesciunt esse quas eos illum, facere voluptate, iure officiis.
</div>
<div class="box">
<h2>Heading</h2>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas corporis et nesciunt esse quas eos illum, facere voluptate, iure officiis.
</div>
<div class="box">
<h2>Heading</h2>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas corporis et nesciunt esse quas eos illum, facere voluptate, iure officiis.
</div>
</div>
Related
Here is an example (with codepen included)
https://codepen.io/Sanjid-Chowdhury/pen/QWBBGbJ
.container {
display: flex;
flex-direction: column;
}
p {
height: 40px;
}
<div class="container">
<p>Your data</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam nesciunt quam et repellendus harum possimus sequi, iusto nam tempore qui, sit quasi! Velit nisi numquam, non accusamus atque perspiciatis aperiam?</p>
<p>WAFIjwaf oakd owad kalwd koawd sla ksa olafwa kosad </p>
<p>afwad op wafk ag jasglksakmdfgfi efkf aioefjw oafkw alfk awijf jf dasklfskjasf ds</p>
<p>eafifa osd okasg oeoagkesfal s;sdfpoasef ksadlf eaigjwg</p>
</div>
If you decrease the window size, you will see that the <p> tag overflows vertically. I am looking for a behavior where the <p> tag will expand just as much as it needs to, given its fixed height. If i set the width of the .container to width: max-content, the whole tag turns into a line of text. I want it to take the available fixed height and then expand its width if the text starts to overflow vertically.
Try to add white-space:nowrap to your p tag
.container {
display: flex;
flex-direction: column;
}
p {
height: 40px;
white-space: nowrap;
}
<div class="container">
<p>Your data</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam nesciunt quam et repellendus harum possimus sequi, iusto nam tempore qui, sit quasi! Velit nisi numquam, non accusamus atque perspiciatis aperiam?</p>
<p>WAFIjwaf oakd owad kalwd koawd sla ksa olafwa kosad </p>
<p>afwad op wafk ag jasglksakmdfgfi efkf aioefjw oafkw alfk awijf jf dasklfskjasf ds</p>
<p>eafifa osd okasg oeoagkesfal s;sdfpoasef ksadlf eaigjwg</p>
</div>
I'm a beginner Web Developer and I've recently started using Flexbox.
I find it is a great tool to use however I have a slight problem.
I have an image I want to put on my site, with a column of text beside it to the right.
As you can see from the code below I have created a wrapper div, with two nested divs inside it.
I have set the display attribute to 'flex' in the wrapper div and set the flex property to '1' for both of the divs inside. I thought this would make both of my divs take up 50% of the space each, but instead it seems like the image takes up more space than it should.
I've used an example image from Pexels. I'm wondering if the actual size of the raw image has an affect on this? For example do I have to manually resize all my photos before putting them on a site, or is there a way to have the image take up 50% of the width at all times, while having the text take up the other 50%, using flexbox?
Sorry if this post is hard to understand. Appreciate your help!
.wrapper
{
display: flex;
border: 3px solid red;
}
.image-div
{
flex: 1;
}
.text-div
{
flex: 1;
}
<div class="wrapper">
<div class="image-div">
<img src="https://images.pexels.com/photos/4403924/pexels-photo-4403924.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" />
</div>
<div class="text-div">
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. In itaque assumenda explicabo blanditiis! Mollitia adipisci voluptates doloremque porro eaque dolor blanditiis deserunt. Illum optio ut minus magni nemo ipsum obcaecati.
Lorem ipsum dolor sit, amet consectetur adipisicing elit. In itaque assumenda explicabo blanditiis! Mollitia adipisci voluptates doloremque porro eaque dolor blanditiis deserunt. Illum optio ut minus magni nemo ipsum obcaecati.</p>
</div>
</div>
Try this:
.wrapper {
display: flex;
border: 3px solid red;
}
.image-div {
flex: 1;
background-color: red;
width: 100%;
}
.image-div>img {
width: 100%;
}
.text-div {
flex: 1;
background-color: yellow;
width: 100%;
}
<div class="wrapper">
<div class="image-div">
<img src="https://images.pexels.com/photos/4403924/pexels-photo-4403924.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" />
</div>
<div class="text-div">
<p>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. In itaque assumenda explicabo blanditiis! Mollitia adipisci voluptates doloremque porro eaque dolor blanditiis deserunt. Illum optio ut minus magni nemo ipsum obcaecati. Lorem ipsum dolor sit,
amet consectetur adipisicing elit. In itaque assumenda explicabo blanditiis! Mollitia adipisci voluptates doloremque porro eaque dolor blanditiis deserunt. Illum optio ut minus magni nemo ipsum obcaecati.
</p>
</div>
</div>
You just have to set the width of the image-div and the text-div to 100%. This way, they will take 50% of the screen width.
Next, we have to set the width of the image inside the image-div to 100%. This way, it will take the whole width of it's parent div. And the same will be for the text div.
Hope it helps
Adding image width in your CSS fixes the issue:
.image-div img { width: 100%; }
You need to set a max-width and height for your image like this:
.image-div img {
max-width: 100%;
max-height: 100%;
}
Heres the example:
.wrapper
{
display: flex;
border: 3px solid red;
}
.image-div
{
flex: 1;
}
.image-div img {
max-width: 100%;
max-height: 100%;
}
.text-div
{
flex: 1;
}
<div class="wrapper">
<div class="image-div">
<img src="https://images.pexels.com/photos/4403924/pexels-photo-4403924.jpeg?cs=srgb&dl=silhouette-of-mountain-under-cloudy-sky-during-sunset-4403924.jpg&fm=jpg">
</div>
<div class="text-div">
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. In itaque assumenda explicabo blanditiis! Mollitia adipisci voluptates doloremque porro eaque dolor blanditiis deserunt. Illum optio ut minus magni nemo ipsum obcaecati.
Lorem ipsum dolor sit, amet consectetur adipisicing elit. In itaque assumenda explicabo blanditiis! Mollitia adipisci voluptates doloremque porro eaque dolor blanditiis deserunt. Illum optio ut minus magni nemo ipsum obcaecati.</p>
</div>
</div>
Set your image as position: absolute, stretched to the full extent of it's parent DIV element, and use object-fit to adapt the actual image to a desired value like contain or cover.
Doing so the image will adapt to the area which size is dictated by the text content in the other flex: 1 DIV element:
.wrapper {
display: flex;
border: 3px solid red;
}
.wrapper>* {
position: relative;
flex: 1;
}
.image-div img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="wrapper">
<div class="image-div">
<img src="//placehold.it/300x400&text=Some+image">
</div>
<div class="text-div">
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. In itaque assumenda explicabo blanditiis! Mollitia adipisci voluptates doloremque porro eaque dolor blanditiis deserunt. Illum optio ut minus magni nemo ipsum obcaecati. Lorem ipsum dolor sit,
amet consectetur adipisicing elit. In itaque assumenda explicabo blanditiis! Mollitia adipisci voluptates doloremque porro eaque dolor blanditiis deserunt. Illum optio ut minus magni nemo ipsum obcaecati.</p>
</div>
</div>
Background
I want to display the icon through background-image, but if the text is too long, it will be obscured by text.
.box {
display : inline-flex;
}
.box:before {
content : '';
background-image: url('https://imgur.com/TCc5A1P');
width: 60px;
height: 60px;
margin-right: 0.2em;
display: inline-block;
}
<div class="box">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure harum commodi totam sit, natus dolore reiciendis. Nihil possimus, magni praesentium molestias ab vel dolorum rem. Eos autem saepe magnam pariatur.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quasi
</div>
Question
When I use min-width instead of width or use inline-block for .box, it will work. Can anyone tell me why min-width or inline-block works?
use min-width instead of width
.box {
display : inline-flex;
}
.box:before {
content : '';
background-image: url('https://imgur.com/TCc5A1P');
min-width: 60px;
/* width: 60px; */
height: 60px;
margin-right: 0.2em;
display: inline-block;
}
<div class="box">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure harum commodi totam sit, natus dolore reiciendis. Nihil possimus, magni praesentium molestias ab vel dolorum rem. Eos autem saepe magnam pariatur.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quasi
</div>
--
use inline-block for .box
.box {
/* display : inline-flex; */
display : inline-block;
}
.box:before {
content : '';
background-image: url('https://imgur.com/TCc5A1P');
width: 60px;
height: 60px;
margin-right: 0.2em;
display: inline-block;
}
<div class="box">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure harum commodi totam sit, natus dolore reiciendis. Nihil possimus, magni praesentium molestias ab vel dolorum rem. Eos autem saepe magnam pariatur.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quasi
</div>
When I use min-width instead of width or use inline-block for .box, it will work. Can anyone tell me why min-width or inline-block works?
min-width
Sets the minimum width of an element.
width
Sets the width of an element.
display: inline-flex (and flex)
An initial setting on flex items is flex-shrink: 1. This means that flex items can shrink below their defined width / height to prevent their overflow of the container. In order to prevent this behavior, you need to disable flex-shrink.
For example:
.box::before {
width: 60px;
flex-shrink: 0; <------ add this to your code
content : '';
...
...
...
}
Or, for a cleaner version (which is also recommended by the flexbox spec), use this:
.box::before {
flex: 0 0 60px; /* flex-grow, flex-shrink, flex-basis */
content : '';
...
...
...
}
Note that flex-shrink applies to width and height, but not to min-width and min-height. By disabling flex-shrink on an element, you are effectively establishing its minimum length.
For example:
width: 60px;
flex-shrink: 0;
is equivalent to:
min-width: 60px;
For a more complete explanation, see "The flex-shrink factor" section in my answer here:
What are the differences between flex-basis and width?
display: inline-block (and block)
flex-shrink (described above) does not apply in a block formatting content.
revised code
.box {
display: inline-flex;
}
.box::before {
flex: 0 0 60px;
height: 60px;
background-image: url('http://i.imgur.com/60PVLis.png');
background-size: contain;
background-repeat: no-repeat;
margin-right: 0.2em;
content: '';
}
<div class="box">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure harum
commodi totam sit, natus dolore reiciendis. Nihil possimus, magni
praesentium molestias ab vel dolorum rem. Eos autem saepe magnam
pariatur. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Quasi
</div>
Width Property will change the horizontal image dimensions to the pixels you have defined (In your case 60px). Width = 60px
Min-Width will make sure that horizontal image width is greater that or equal to the pixel you have defined. Width >= 60px.
The ouput that you see in your case is because the image is taking its original dimensions. ie some value greater tha 60px.
width:
The width CSS property specifies the width of the content area of an element. The content area is inside the padding, border, and margin of the element.
min-width:
The min-width CSS property is used to set the minimum width of a given element. It prevents the used value of the width property from becoming smaller than the value specified for min-width.
max-width:
The max-width CSS property is used to set the maximum width of a given element. It prevents the used value of the width property from becoming larger than the value specified for max-width.
Please visit Info Source for more info.
Edited
this also apply with height,
to make it simpler and more general
something = 10px;
the value is neither less nor more then 10px.
min-something = 10px;
the minimum value can't below the given property value.
E.g.= 10px, 11px, 20px, 300px is above minimum level so it is accepted. So the image cant be lower then 10px in resolution.
max-something = 10px;
the maximum value can't exceed or above the given property value.
E.g.= 9px, 8px, 5px, 0px is below maximum level so it is accepted. So the image cant be higher then 10px in resolution.
Below is few example
min width and height is 100px
.box {
/*display : inline-flex;*/
display: inline-block;
}
.box:before {
content: '';
background-image: url('https://smartlogic.io/images/brand-assets/smartlogic-seal-teal-100.png');
min-width: 100px;
min-height: 100px;
margin-right: 0.2em;
display: inline-block;
}
<div class="box">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure harum commodi totam sit, natus dolore reiciendis. Nihil possimus, magni praesentium molestias ab vel dolorum rem. Eos autem saepe magnam pariatur. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Quasi
<br> please note that image is 100px *100px
</div>
min width and height is 60px
.box {
/*display : inline-flex;*/
display: inline-block;
}
.box:before {
content: '';
background-image: url('https://smartlogic.io/images/brand-assets/smartlogic-seal-teal-100.png');
min-width: 60px;
min-height: 60px;
margin-right: 0.2em;
display: inline-block;
}
<div class="box">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure harum commodi totam sit, natus dolore reiciendis. Nihil possimus, magni praesentium molestias ab vel dolorum rem. Eos autem saepe magnam pariatur. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Quasi
<br> please note that image is 100px * 100px
</div>
width and height is 60px
.box {
/*display : inline-flex;*/
display: inline-block;
}
.box:before {
content: '';
background-image: url('https://smartlogic.io/images/brand-assets/smartlogic-seal-teal-100.png');
width: 60px;
height: 60px;
margin-right: 0.2em;
display: inline-block;
}
<div class="box">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure harum commodi totam sit, natus dolore reiciendis. Nihil possimus, magni praesentium molestias ab vel dolorum rem. Eos autem saepe magnam pariatur. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Quasi
<br> please note that image is 100px * 100px
</div>
width and height is 100px
.box {
/*display : inline-flex;*/
display: inline-block;
}
.box:before {
content: '';
background-image: url('https://smartlogic.io/images/brand-assets/smartlogic-seal-teal-100.png');
width: 100px;
height: 100px;
margin-right: 0.2em;
display: inline-block;
}
<div class="box">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure harum commodi totam sit, natus dolore reiciendis. Nihil possimus, magni praesentium molestias ab vel dolorum rem. Eos autem saepe magnam pariatur. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Quasi
<br> please note that image is 100px * 100px
</div>
Also note that
in your case,
when you use max-width you need to define the min-width as well.
min-width will give you the space form image to show.
I am currently in the process of writing mark up which has content on either side and an image that floats either left or right towards the top - this works fine.
However, when you introduce too much content on the left or right hand side, the content box does not want to move down but moves up and then moves down to cover the gap. But i would like the gap.
Example Below: If you cant reproduce it below; please try: https://jsfiddle.net/171f14cg/
article {
min-height: 450px;
position: relative;
margin-bottom: 120px;
}
article.art-white-bg {
color: black;
}
article.art-white-bg .content-area-push {
background-color: white;
box-shadow: 0px 18px 26px -5px rgba(0, 0, 0, 0.74);
}
article .content-area-push {
position: absolute;
min-height: 350px;
bottom: 0;
}
article.right-image figure {
right: 0;
}
article figure {
position: absolute;
max-height: 360px;
z-index: 1;
}
article.right-image .art-content {
float: left;
width: 30%;
}
article .art-content {
padding: 50px 45px;
}
<article class="main-article right-image art-white-bg animated hidden visible fadeInUp">
<div class="content-area-push">
<div class="art-content">
<header>
<h2>Working example cause of low amount of content</h2>
</header>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem laborum, autem voluptates ipsam voluptate porro, quibusdam vero. Error, quod, voluptates. Ducimus nulla eum quos sequi, maxime vitae ut autem numquam?</p>
</div>
</div>
<figure>
<img src="https://placeholdit.imgix.net/~text?txtsize=52&txt=550%C3%97350&w=580&h=360" alt="Baby Orang Utan hanging from a rope">
</figure>
</article>
<article class="main-article right-image art-white-bg animated hidden visible fadeInUp">
<div class="content-area-push">
<div class="art-content">
<header>
<h2>Example that does not work</h2>
</header>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem laborum, autem voluptates ipsam voluptate porro, quibusdam vero. Error, quod, voluptates. Ducimus nulla eum quos sequi, maxime vitae ut autem numquam?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem laborum, autem voluptates ipsam voluptate porro, quibusdam vero. Error, quod, voluptates. Ducimus nulla eum quos sequi, maxime vitae ut autem numquam?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem laborum, autem voluptates ipsam voluptate porro, quibusdam vero. Error, quod, voluptates. Ducimus nulla eum quos sequi, maxime vitae ut autem numquam?</p>
</div>
</div>
<figure>
<img src="https://placeholdit.imgix.net/~text?txtsize=52&txt=550%C3%97350&w=580&h=360" alt="Baby Orang Utan hanging from a rope">
</figure>
</article>
I think you're looking for something like this:
https://jsfiddle.net/dee0gjaz/
I removed a number of attributes from several elements. Basically, you were over-styling a little bit. Your text content did not need absolute positioning. That should be static so that it can stretch the parent.
The image however, can remain absolute and with a negative top measure you will have consistent offset.
Let's say we have such html
<div class="at-end-holder">
Lorem ipsum dolor sit amet...
<img src="http://placehold.it/350x150" class="at-end">
</div>
And we want top edge of image to stick with bottom edge of it's parent.
If we'd know image height (let's say its 150px), then we can just set bottom: -150px. But what if we dont know it's height?
I don't want to use js. I mean - I don't.
Here is some playground. Bottom case looks exatcly as needed, but I assumed there I know image height.
Since the element is absolutely positioned relative to the parent, you could simply use top: 100% to position it at the bottom edge of the parent.
Updated Example
.at-end-holder.example .at-end {
top: 100%;
}
.at-end-holder {
background-color: #ddd;
position: relative;
margin-bottom: 200px;
}
.at-end-holder .at-end {
position: absolute;
left: 0;
right: 0;
top: 100%;
}
<div class="at-end-holder">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis vero veritatis, assumenda reiciendis vel voluptate, rem eaque, ut quisquam qui sit molestias omnis. Officia, illum repellat quasi eius, magni soluta?
<img src="http://placehold.it/350x150" class="at-end">
</div>
<div class="at-end-holder example">
<h1>THIS I NEED, BUT I DONT KNOW IMAGE HEIGHT</h1>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis vero veritatis, assumenda reiciendis vel voluptate, rem eaque, ut quisquam qui sit molestias omnis. Officia, illum repellat quasi eiusmagni soluta?
<img src="http://placehold.it/350x150" class="at-end">
</div>