CSS Flex dynamic horizontal width based on nested element width - html

I'm trying to create the following layout using CSS Flex. It seems simple but there's a tricky part to it which I will explain below.
HTML:
<div class="flex">
<div class="icon-col">
<div class="icon" style="max-width:120px;">
<svg>image code here...</svg>
</div>
</div>
<div class="text-col">
<h4>Awesome Design</h4>
<p>Nullam vel sem. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur blandit mollis lacus. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc.</p>
</div>
</div>
CSS:
.flex {
display: flex;
flex-direction: row;
}
.icon-col, .text-col {
flex: 1;
}
.icon {
width: 100%;
}
Codepen preview: https://codepen.io/anon/pen/KEjJeO
As you can see in the preview, there is too much space between the icon and the text. The icon has to be 120px as specified in the inline CSS and the width of the text column should grow or shrink based on the icon size.
Try tricky part:
The icon has a dynamic width.
I can define a width for the icon using only an inline style in the HTML, in the .icon element as seen above in the HTML.
I have no control over the .icon-col element as far as adding a dynamic width to it. It would have been easy if I could just add the width to .icon-col.
I also can't add a width to .text-col because it has to resize automatically based on the icon size.
How can .icon-col be the same width as its child element .icon and have the text column resize automatically?

You can group and move things around but its just to get an idea.
.flex2 {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
background-color: blue;
}
.icon-col {
flex: 1 1 20%;
background-color: #ff0000;
position: relative;
padding: 20px;
}
.abacadabra {
width: 120px;
max-width: 120px;
position: relative;
float: right;
right: 5px
}
.text-col {
flex: 1 1 80%;
background-color: #ffff00;
padding: 20px
}
<div class="flex2">
<div class="icon-col">
<div class="abacadabra">
<svg aria-hidden="true" data-prefix="fas" data-icon="tools" class="svg-inline--fa ugbfa-tools fa-w-16 " role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M501.1 395.7L384 278.6c-23.1-23.1-57.6-27.6-85.4-13.9L192 158.1V96L64 0 0 64l96 128h62.1l106.6 106.6c-13.6 27.8-9.2 62.3 13.9 85.4l117.1 117.1c14.6 14.6 38.2 14.6 52.7 0l52.7-52.7c14.5-14.6 14.5-38.2 0-52.7zM331.7 225c28.3 0 54.9 11 74.9 31l19.4 19.4c15.8-6.9 30.8-16.5 43.8-29.5 37.1-37.1 49.7-89.3 37.9-136.7-2.2-9-13.5-12.1-20.1-5.5l-74.4 74.4-67.9-11.3L334 98.9l74.4-74.4c6.6-6.6 3.4-17.9-5.7-20.2-47.4-11.7-99.6.9-136.6 37.9-28.5 28.5-41.9 66.1-41.2 103.6l82.1 82.1c8.1-1.9 16.5-2.9 24.7-2.9zm-103.9 82l-56.7-56.7L18.7 402.8c-25 25-25 65.5 0 90.5s65.5 25 90.5 0l123.6-123.6c-7.6-19.9-9.9-41.6-5-62.7zM64 472c-13.2 0-24-10.8-24-24 0-13.3 10.7-24 24-24s24 10.7 24 24c0 13.2-10.7 24-24 24z"></path></svg>
</div>
</div>
<div class="text-col">
<h4>Awesome Design</h4>
<p>Nullam vel sem. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur blandit mollis lacus. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc.</p>
</div>
</div>

Related

How to make the image displays right below the text, not behind the next div content?

I'm new to StackOverflow, still learning fullstack web-development.
Just started creating my own website and I'm stuck at my image keeps displaying behind the next div's item, not right below the text. :(
Please help me!! Thank you :D
HTML
<div class="wrapper">
<div class="container">
<div class="row">
<div class="col-sm-8 text-container">
<p>
<h1>laoreet ante eget, vehicula ligula.</h1><br />
sed odio eu, eleifend aliquet urna. Donec ultrices dapibus ipsum.
Suspendisse ac hendrerit augue. Pellentesque massa eros, auctor ac sapien a, lacinia
luctus dolor. Proin et eleifend quam. Mauris tristique dictum tellus vitae molestie.
Praesent
auctor justo nisl, eu porta leo aliquam at.
</p>
</div>
<div class="col-sm-4">
<img src="images/picture.png" class="picture-container my-picture" alt="">
</div>
</div>
</div>
CSS
.wrapper {
width: 100%;
height: 700px;
background-color: #ed8d8d;
}
.container {
height: 500px;
padding: 80px 0px;
}
.text-container {
width: 700px;
height: 500px;
float: left;
margin-top: 80px;
text-align: right;
}
.picture-container {
overflow: hidden;
}
/* IMAGES */
.sophie-picture {
height: 450px
}
Inside your HTML code, the "picture-container" class on the IMG element should likely be moved, so it sits on the "col-sm-4"-div above.
I suspect the "my-picture" class on the IMG and the "sophie-picture" class in the CSS should be the same thing ? most likely you've renamed one of them and forgot to do the same in the other file, If so you should rename one so their names match up again.
There's a </div> missing at the end of the HTML code here, but i suspect that is likely just the case here because you only pasted part of your HTML document, and not the case in your own version.
The reason your image and text-container overlap is the use of float.
Removing that likely solves most of the issue.
But judging by the col-sm-8 style classnames i'm guessing you're using something like bootstrap ? Those classes apply a whole bunch of CSS (that you don't particularly have to worry about), but they provide the "column(s) within row; row(s) within container"-style of rapidly building a layout. If you're using those classes its best not to mix it with floats, manual width/height and margin statements, or really any significant CSS (just cosmetic only things like colors, font bold/italic, ...). Bootstrap has many classes so you effectively don't have to write any CSS yourself (classes like mb-4 or such for margins for example).
I would suggest using 1 or the other for a given container:
either building it the bootstrap-way with container/row/col and then using the margin/color/etc classes from boostrap.
or writing the CSS yourself, but then not using those bootstrap classes.
move the h1 tag above the p tag and set margin-bottom on the p tag to 0. also picture-container has no declared height so overflow:hidden won't do anything there. aplly overflow:hidden to wrapper.
.wrapper {
width: 100%;
height: 700px;
background-color: #ed8d8d;
border:solid 2px red;
overflow:hidden;
}
.container {
height: 500px;
padding: 80px 0px;
border:solid 2px blue;
}
.text-container {
width: 700px;
height: 500px;
float: left;
margin-top: 80px;
text-align: right;
border:solid green 2px;
}
.picture-container {
overflow: hidden;
}
p{
margin-bottom:0}
/* IMAGES */
.sophie-picture {
height: 450px
}
<div class="wrapper">
<div class="container">
<div class="row">
<div class="col-sm-8 text-container">
<h1>laoreet ante eget, vehicula ligula.</h1>
<p>
sed odio eu, eleifend aliquet urna. Donec ultrices dapibus ipsum.
Suspendisse ac hendrerit augue. Pellentesque massa eros, auctor ac sapien a, lacinia
luctus dolor. Proin et eleifend quam. Mauris tristique dictum tellus vitae molestie.
Praesent
auctor justo nisl, eu porta leo aliquam at.
</p>
</div>
<div class="col-sm-4">
<img src="https://via.placeholder.com/450" class="picture-container my-picture" alt="">
</div>
</div>
</div>
</div>

How to evenly line three p elements next to each other with flexbox

I am making three boxes next to each other. Each box has a image + header + text.
The first box contains a header with two words. When shrinking the browser the p content of box 2 and 3 are lined up higher than box 1.
The code which i used is:
<section id="boxes">
<div class="container">
<div class="box">
<img src="https://www.w3.org/html/logo/downloads/HTML5_1Color_Black.png" alt="html5 logo">
<h3>HTML 5 Website</h3>
<p>Curabitur porttitor metus odio, fringilla bibendum sem faucibus quis. C</p>
</div>
<div class="box">
<img src="https://www.w3.org/html/logo/downloads/HTML5_1Color_Black.png" alt="html5 logo">
<h3>Webbie</h3>
<p>Curabitur porttitor metus odio, fringilla bibendum sem faucibus quis. C</p>
</div>
<div class="box">
<img src="https://www.w3.org/html/logo/downloads/HTML5_1Color_Black.png" alt="html5 logo">
<h3>Informatie</h3>
<p>Curabitur porttitor metus odio, fringilla bibendum sem faucibus quis. C</p>
</div>
</div>
</section>
and the CSS:
#boxes .container {
display: flex;
max-width: 900px;
}
.box {
display: flex;
flex-direction: column;
}
.box img {
/*prevents image from being larger than it's container, but doesn't stretch it if it's smaller than the container*/
/*if you had a 20x20px image, then it would not get stretched to match the container's width, but it would stay 20x20px. Whereas a 2000x2000px image would get scaled down to fit the container*/
max-width: 100%;
}
jsfiddle:
https://jsbin.com/gudomuyora/edit?html,css,output
How to line up the top of the p elements within the 3 boxes evenly.
You can use justify-content: space-between on .box to achieve this.
#boxes .container {
display: flex;
max-width: 900px;
}
.box {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.box img {
max-width: 100%;
flex: 0 0 auto;
}
.box h3 {
flex: 1 1 auto;
}
.box p {
flex: 0 1 auto;
}
<section id="boxes">
<div class="container">
<div class="box">
<img src="https://www.w3.org/html/logo/downloads/HTML5_1Color_Black.png" alt="html5 logo">
<h3>HTML 5 Website</h3>
<p>Curabitur porttitor metus odio, fringilla bibendum sem faucibus quis. C</p>
</div>
<div class="box">
<img src="https://www.w3.org/html/logo/downloads/HTML5_1Color_Black.png" alt="html5 logo">
<h3>Webbie</h3>
<p>Curabitur porttitor metus odio, fringilla bibendum sem faucibus quis. C</p>
</div>
<div class="box">
<img src="https://www.w3.org/html/logo/downloads/HTML5_1Color_Black.png" alt="html5 logo">
<h3>Informatie</h3>
<p>Curabitur porttitor metus odio, fringilla bibendum sem faucibus quis. C</p>
</div>
</div>
</section>

How to fit an image to “above the fold” without vertical scrollbar [duplicate]

This question already has answers here:
Image inside div has extra space below the image
(10 answers)
How wide is the default `<body>` margin?
(4 answers)
Closed 4 years ago.
starting from this question I have created the following layout:
html, body {
height: 100%;
}
.flexcontainer {
height: 100%;
display: flex;
flex-direction: row;
}
.left-container {
flex: 3 0 0;
}
.left-container .header {
display: flex;
}
.right-container {
flex: 1 0 0;
}
.right-container img {
height: 100%;
width: 100%;
object-fit: contain;
object-position: top right;
}
<div class="flexcontainer">
<div class="left-container">
<div class="header">
<div class="avatar">
<img src="https://i2.wp.com/oneword365.com/wp-content/uploads/oph-Avatar.png?resize=73%2C73"/>
</div>
<div class="user">
<span class="title">Sue Smith</span>
<div class="subtitle">PincoPallino</div>
<div class="time">15th August 2017</div>
</div>
</div>
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vel porttitor risus. Integer dictum massa ac mollis posuere. Etiam dapibus odio euismod lacus tempus tempor. Donec sagittis eget purus non rhoncus. Ut ac est turpis. Ut et ornare felis. Vestibulum at facilisis sed.
</div>
</div>
<div class="right-container">
<img src="http://www.fulltimefba.com/wp-content/uploads/2014/04/bigstock-obstacle-ahead-caution-for-dan-41515888.jpg"/>
</div>
</div>
(CodePen mirror).
I would like to have that the image on the right should fit the above the fold section, and even have some padding arount it. As you can see it can't and a vertical scrollbar appears.
How can i fit the image to the above the fold?
If I set padding and margin of body to 0 it works and I get rid of the vertical scroll bar. But... isn't this a dirty solution?

I would like flex box to grow in width (horizontally) but not in height (vertically)

Is there anyway to allow flex items to grow in width but only in height when necessary. I love flexbox but find it painful that flex items in a row all grow to the same height even when there is not content to fill them and then display additional items further down the page. Ideally I would like flex items to arrange themselves into available space when previous items don't have sufficient content to fill the box and not leave a big space.
Is this my lack of knowledge or is it just not possible? If it's not possible, could the facility be added in updates etc.
(Sorry. I tried to upload diagrams to explain but my reputation isn't enough!)
[EDIT. Code added as request. Some style left to demonstrate the white space I want to be taken up by the other flex items.]
<!doctype html>
<html>
<head>
<style>
.content {
font-size: 2em;
width: 100%;
margin: 0px;
padding: 0px;
background-color: coral;
display:flex;
flex-direction:row;
flex-wrap: wrap;
justify-content: center;
align-content: stretch;
align-items: flex-start;
}
.flex-item {
box-sizing: border-box;
flex-grow: 1;
flex-shrink: 0;
flex-basis:40vw;
background-color: rgba(255, 255, 255, 0.9);
border: 2px solid white;
border-radius: 2px;
margin: 2vmin;
padding: 2vmin;
}
</style>
</head>
<body>
<div class="content">
<div class="flex-item">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eu venenatis nisi. Sed nec purus consectetur, sodales mi vel, efficitur arcu. Vivamus id congue quam. Fusce imperdiet bibendum egestas. Mauris porttitor risus id pharetra pharetra. Vivamus et lorem erat. Nullam ac nulla ex. Nulla sit amet semper ligula. Integer augue sem, pharetra in ex ut, finibus mollis neque. Integer vulputate dolor massa, a maximus sem vehicula malesuada. Morbi a nulla ornare, egestas nisl in, ultrices est. Integer ut maximus elit. Cras ac velit condimentum, dapibus dui quis, mattis ex.
</div>
<div class="flex-item"><img src="https://pixabay.com/get/ec8630811c846e5862cb/1442266437/wheat-797086_1280.jpg" width="100%">
</div>
<div class="flex-item">Vivamus semper at tortor a lacinia. Nulla a suscipit felis. Aliquam erat volutpat. Integer dignissim suscipit nibh a accumsan.Fusce gravida nisl nec elit placerat porta. Ut feugiat feugiat lorem nec commodo. Morbi porttitor vel sapien id tincidunt. Vivamus venenatis pellentesque tempus.
</div>
<div class="flex-item"><img src="https://pixabay.com"/get/ec8630811c846e5862cb/1442266437/wheat-797086_1280.jpg" width="100%"> </div>
</div>
</body>
</html>
Apparently my question is not clear enough! I will try and expand with the sites constraints but not being allowed to post a diagram doesn't help.
There are Flex item boxes containing text, images or both. Flex item boxes containing images scale to the available space.
With high resolutions, text only boxes are the same width and height (square) so images scale ok (square) and all is chipper. However at say viewports of 400 px wide, the boxes containing just text, become long (say 200 x 1000px for sake of argument) and the image boxes are 200 x 200px (square). The next line is then display after the bottom of the flex item text leaving a big gap (say 800px high) below the image. Other flex boxes could fit in the space after the shrunk image but they don't move into the gap. Is that clear people who put the question on hold??
what you are looking for is the 'align-content' property which is default set to 'stretch' and justifies elements vertically (the cross-axis).
Opposed to 'justify-content', default 'flex-start' which justifies elements horizontally (main-axis).
'align-self', default 'auto', can be used to control individual items.
In other cases giving the max-height and height properties the same value will work too.
Which option to use depends on your personal requirement.
A very good resource for background info: Codrops CSS Reference - Flexbox
#Sharon
I believe here is your answer. Essentially everything in your solution has a relative width and height. Thus your inner box too. Giving your 'flex-item' both a min and max height will prevent height resizing. You need to do some more stuff, so have a look at the code.
body {
overflow: hidden;
/* just for testing, remove */
}
.flex-content {
width: 100%;
margin: 0;
padding: 0;
display: flex;
flex-flow: row wrap;
}
.flex-item {
flex: 1 1 40vw;
min-height: 50px;
max-height: 50px;
background-color: rgba(255, 255, 255, 0.7);
text-align: center;
border: 2px solid white;
border-radius: 2px;
margin: 2vmin;
padding: 2vmin;
background-color: #fce4ec; /* for testing*/
}
<div class="flex-content">
<div class="flex-item">some text</div>
<div class="flex-item">some text data</div>
<div class="flex-item">some more text data</div>
<div class="flex-item">again some more text data</div>
<div class="flex-item">some text</div>
<div class="flex-item">some text data</div>
<div class="flex-item">some more text data</div>
<div class="flex-item">again some more text data</div>
<div class="flex-item">some text</div>
<div class="flex-item">some text data</div>
<div class="flex-item">some more text data</div>
<div class="flex-item">again some more text data</div>
</div>

dynamical height of article tag

Have trouble dynamically adjusting content blocks, their height in particular.
have code structure(don't mind if missed any closing tags or etc., they are there in running version):
<div class="wrapper">
<article>
<div class="inner-wrap">
<div class="front_panel">
<a>some content(might involve image)</a>
</div>
<div class="back_panel">
<a>some more content</a>
</div>
</div>
<div class="outer-wrap">
<a>some more content</a>
<a>some bottom content</a>
</div>
</article>
.....
<!--more articles here-->
<article>..</article>
</div>
So issue, sometimes some of content is to long so it overflows my default height of 265px. I would like to make it more dynamical and make height adapt, but as all articles need to align according to design guidelines, the height of all articles need to be the same, in other words, if I dynamically adjust height from 265px to 280px on one article it should be the same height on all other. I was thinking about some js checks, but as there is a lot events(filters, searches and etc., everything is asynchronous it is a lot to cover with js).
Any ideas on CSS solutions?
Looked into flexbox CSS solution, but it doesn't seem to adapt good on so many layers of content in article.
Any suggestions, possible solutions or links would help a lot.
Thanks in forward!
Here you have a good article about the topic with different approaches.
I like the One True Layout Method:
HTML:
<div id="one-true" class="group">
<div class="col">
<h3>I am listed first in source order.</h3>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>
</div>
<div class="col">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit
amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
</p>
</div>
<div class="col">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>
</div>
</div>
CSS:
#one-true { overflow: hidden; }
#one-true .col {
width: 27%;
padding: 30px 3.15% 0;
float: left;
margin-bottom: -99999px;
padding-bottom: 99999px;
}
#one-true .col:nth-child(1) { margin-left: 33.3%; background: #ccc; }
#one-true .col:nth-child(2) { margin-left: -66.3%; background: #eee; }
#one-true .col:nth-child(3) { left: 0; background: #eee; }
#one-true p { margin-bottom: 30px; } /* Bottom padding on col is busy */
demo
Is this what you're looking for? http://jsfiddle.net/swm53ran/91/
<div class="content">
Here is some content
</div>
<div class="content">
Here is some content<br/>
Here is some content<br/>
Here is some content
</div>
$(document).ready(function() {
var height = 0;
$('.content').each(function() {
if (height < $(this).height()) {
height = $(this).height();
}
});
$('.content').each(function() {
$(this).height(height);
});
});
Enclose the articles in divs and then use flex box. Then use the flex-box-grow and flex-box-shrink properties on the items