Center text above wrapped, fixed-width items, ignoring container's leftover space - css

We want the layout that's shown below but don't know how to center the "Center here" text like that. Currently, we're centering it according to the width of the parent container. It's appearing too far to the right. In this example, only two items fit on a row, thus leaving empty space to the right of the items. We want the parent container's width to be as per the min width of the child flexbox to center the text above it. The flex box is flex row with wrapping for items that don't fit in. We basically want to ignore that extra space on the right where the item can't fit and set the width of the parent div accordingly
The blue color represents the flex-box's width. Here's the tailwind CSS classes that we're currently using:
className="flex flex-row overflow-x-hidden flex-wrap 3xl:flex-shrink 2xl:block 2xl:grid 2xl:grid-cols-3 3xl:grid-cols-3 justify-items-end "

Hard no sample code, but here I tried my best, hope it helps
This is my code sample, you can try it :
body{
padding: 5%;
}
.container{
border: 5px solid #000;
width: 300px;
height: 400px;
}
.container-box{
margin: auto;
display: flex;
flex-wrap: nowrap;
padding: 10px;
width: 200px;
height: 200px;
}
.box-1, .box-2{
margin: auto;
border: 5px solid #000;
width: 40%;
height: 40%;
}
<div class="container">
<div class="container-box">
<div class="box-1"></div>
<div class="box-2"></div>
</div>
</div>

Related

How set full screen width background on fixed width element?

I have simple structure of element container of dynamic height and fixed width (Markup below). On one hand the element's background should span the whole window width, on the other the children's size must be limited by the container (Desired layout below). The number of children and their sizes (which are equal on the image only for simplicity) are dynamic.
Is that possible without adding extra container? I want to avoid achieving the desired element content width by setting width on the children, because their number is dynamic and the size relationships become complicated to write unless their total width is already limited by container's width.
Here's a pen to experiment;
Markup
<div class="container">
<div class="child">
<div class="child">
...
</div>
.container {
width: <fixed-width>px;
}
Desired layout (the whitespace between children and container is irrelevant)
One route we can take to solve this is by using viewport width on the parent container padding, to force the children into a box that is only 500px wide (as per your codepen).
The important thing to remember when doing this is that box-sizing:border-box; will need to be set on the container, otherwise the padding goes ballistic.
We do this by using calc, vw and padding.
padding: 20px calc(50vw - /*half of container width*/);
Here's the full expanded code of your container on the linked codepen:
.container {
display: flex;
flex-flow: row nowrap;
justify-content: center;
margin-left: auto;
margin-right: auto;
height: 300px;
width: 100%;
padding: 20px calc(50vw - 250px);
background-color: #acffac;
background-size: 100vw auto;
background-position: center top;
box-sizing: border-box;
}
html {
overflow-y:scroll; /* fixes potential calculation errors caused by scroll bar - thanks to Roberts comment */
}
Here's a working version of the codepen, and for the sake of keeping all my eggs in one basket, here's an expandable code snippet:
.container {
display: flex;
flex-flow: row nowrap;
justify-content: center;
margin-left: auto;
margin-right: auto;
height: 300px;
width: 100%;
padding: 20px calc(50vw - 250px);
background-color: #acffac;
background-size: 100vw auto;
background-position: center top;
box-sizing: border-box;
}
.child {
flex: 1 0 auto;
width: 100px;
height: 100%;
background-color: #ff4444;
}
.child+.child {
margin-left: 20px;
}
<div class="container">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
I will finish off by pointing out that if someone else has a better solution, you may want to look at that for time being instead as there is some issues with using vw inside calc on older versions of Chrome and Safari.
EDIT:
As noted in the comments by Vadim and Robert there are a few things that can cause some snags.
Firstly, assuming you are working with a bare minimum template (i.e. no normalize/reset.css), your body will most probably still have the inherent margins that would mess with this kind of layout. You can fix this with:
body {
margin:0;
}
Secondly, depending on your OS (Yes I'm looking at you Microsoft!) your scrollbars can push your content to the side whilst simultaneously still being included in the calculation for vw.
We can fix this one of two way. The first being an adjustment on the padding calculation to include the scrollbar side, but you would have to write a script to ensure that scrollbar is actually present, and scrollbars differ in sizes (I.E -> 17px, Edge -> 12px).
The other alternative would be to use a custom content scroller, which would do a full overflow:hidden; over the content, thereby removing the scroll bar, before implementing it's own version of a scrollbar (which generally lies on top of the content with a position:fixed;) it.
Using vw and flex we can center the child elements and achieve exactly what you require. I have written a JSfiddle where you can check it out.
Basically what I have done is created a container with display set to flex. Using margin property of the first child element, I have centered all of the other child divs and then the regular properties were added to other divs.
Here's the code
body{
margin: 0;
padding: 0;
}
#container{
display: flex;
width: 100vw;
height: 40vw;
background-color: #333333;
align-items: center;
}
.child{
width: 4vw;
height: 80%;
background-color: red;
margin-right: 10vw;
}
.child:first-child{
margin-left: 28vw;
}
<div id="container">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

How to auto justify divs in CSS

I have a little question about CSS : I would like to do some responsive stuff with divs.
To be more precise, I would like to have a big div containing little divs inside. Those divs may vary in number, but they should all have a fixed size (for example, let's say 250px). So I would like to know if there is a way to make a kind of flex solution, so that divs are always justified, and as soon as the screen is to small to show for example 6 little divs per line, it only shows 5 divs per line.
I am pretty sure, that is not very clear, so here are two draws :
This is the first situation, the div is large enought to have 4 subdivs per line
Then, this div can't display 4 subdivs per line : so it shows 3 subdivs
Flexbox is useful here. Here's a Codepen that does what you're looking for:
https://codepen.io/ksmessy/pen/rmRbdL
As you shrink the window, the items will wrap to the next line. I separated the 3 flex properties in .flexparent with a line break so you can see what is causing this behavior.
HTML:
<div class="flexparent">
<div class="flexchild"></div>
<div class="flexchild"></div>
<div class="flexchild"></div>
<div class="flexchild"></div>
<div class="flexchild"></div>
</div>
CSS:
.flexparent {
border: 3px solid black;
width: 550px;
max-width: 100%;
padding: 10px;
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.flexchild {
border: 1px solid red;
width: 100px;
height: 100px;
margin: 10px;
}

Stacking divs from the bottom right

I am adding colour blocks (divs with bg colours) to a parent div. Each parent div can have a number of these colour blocks which are to display in the bottom right of the parent, with a maximum of three to a row.
My code (below) does what is required for 3 or less colours, but if a forth colour is added it jumps to the line below leaving two empty spaces on the bottom line. What I would like to happen is for the forth colour to be displayed on the line above so the bottom line has no blanks.
You can see the problem in action here along with a hardcoded example of what I would like to happen.
<style>
.container {
position: relative;
width: 200px;
height: 142px;
}
.colorSwatches {
position: absolute;
bottom: 0px;
right: 0px;
max-width: 100px;
max-height:60px;
text-align:right
}
.swatch {
display: inline-block;
width: 25px;
margin: 2px;
height: 25px;
background-color: rgb(255, 0, 0); ///or whatever
}
</style>
<div class="container">
<div class="colorSwatches">
<div class="swatch"></div>
<div class="swatch"></div>
<div class="swatch"></div>
<div class="swatch"></div>
</div>
</div>
Thanks for any help.
I think you can pull off that layout with some flexbox magic:
set your .swatches container, in your case .colorSwatches, with display: flex prop
then to this container and a flex-wrap rule of: flex-wrap: wrap-reverse, so that the children inside it will wrap, on to the next line, in opposite direction of the flex-direction, which by default is row I think.
and lastly, add to the container, the justify-content: flex-end; so that the items inside will start laying out at the end of their container.
Here's a jsfiddle demo and a couple of resources:
Flexbox
Justify-content
Flex-wrap

Margin: Auto not centering images

I want to center a set of images that are lined up side by side. Despite using margin: auto the images are still lined up to the left. I read in another thread to add display: block but that's not working either. Thoughts?
<div style="margin: auto; display:block;">
<p>
<img src="/wp-content/uploads/2015/05/tca_horizontal_blue.gif"
style="float: left;" alt="" width="200px" height="93px" />
<img src="/wp-content/uploads/2015/05/nea-logo-e1431885075484.png"
style="float: left;" alt="" width="218px" height="93px" />
<img src="/wp-content/uploads/2015/05/Arts-Committee-color1-e1431885177830.png"
style="float: left;" alt="" width="155px" height="93px" />
</p>
</div>
According to §10.3.3, margin: 0 auto centers block-level elements because
If both 'margin-left' and 'margin-right' are 'auto', their used values
are equal. This horizontally centers the element with respect to the
edges of the containing block.
However, this is useless if width is auto, because then the block will fill its containing block:
If 'width' is set to 'auto', any other 'auto' values become '0' and
'width' follows from the resulting equality.
Instead, you could use a tabular display. According to §17.5.2,
if the margins of a table are set to '0' and the width to 'auto', the
table will not automatically size to fill its containing block.
However, once the calculated value of 'width' for the table is found
(using the algorithms given below or, when appropriate, some other UA
dependent algorithm) then the other parts of section 10.3 do apply.
Therefore a table can be centered using left and right 'auto' margins,
for instance.
div {
display: table;
margin: 0 auto;
}
div {
display: table;
margin: 0 auto;
border: 2px solid blue;
}
span {
display: inline-block;
height: 20px;
width: 20px;
border: 2px solid red;
margin: 10px;
}
<div>
<span>1</span>
<span>2</span>
</div>
However, this may not be necessary. You say you want to center the images. Therefore, instead of attempting to center the block container, you can center its content, using §16.2 text-align:
This property describes how inline-level content of a block container
is aligned.
div {
text-align: center;
}
div {
text-align: center;
border: 2px solid blue;
}
span {
display: inline-block;
height: 20px;
width: 20px;
border: 2px solid red;
margin: 10px;
}
<div>
<span>1</span>
<span>2</span>
</div>
You need to set the width of the div, as well.
<div style="margin:auto;display:block;witdth:500px;">
Here's a demo: http://jsfiddle.net/qqyjgnhw/1/
Highly recommend reading about the box model of CSS. It makes a lot more sense after you take the hour to know what's going on under the hood.
If you remove float:left on img elements, and add display:block they will get centered...
When an element is floating, it is totally out of the flow.

Scrollbar not appearing in 2-column fluid width layout

I'm using a 2-column div layout where the widths of both the left and right columns is non-deterministic. The left column div holds an image. The right column div holds a header div and a text content div below it. The width of the left column image takes precedence over the right column, and the right column gets the scraps in terms of width. Both of these columns are inside a div container, which has a fixed height (and width, but that doesn't matter). This layout is working using the following code:
.container {
height: 200px;
border: 1px solid black;
overflow: hidden;
}
.left {
float: left;
}
.right {
overflow: hidden;
}
.scrollable-content-header {
font-size: 25px;
border-bottom: 1px solid black;
}
.scrollable-content {
font-size: 18px;
overflow: auto;
}
The text content div should be scrollable if it overflows the container height. But I can't get the scrollbar to appear on the .scrollable-content element. Here's some HTML:
<div class="container">
<div class="left">
<img id="image" src="http://www.webresourcesdepot.com/wp-content/uploads/image/css-icon.png"/>
</div>
<div class="right">
<div class="scrollable-content-header">Lorem Ipsum</div>
<div class="scrollable-content">
Lorem ipsum dolor sit amet, consectetur... etc.
</div>
</div>
</div>
If the container element has overflow: auto instead of hidden, then a scrollbar will appear. But it will allow scrolling of the entire container. I don't want that, only the .scrollable-content should be scrollable, not including the header. I'm assuming that the overflow: hidden trick on the right column div in order to achieve the fluid width effect is causing problems.
Here's a fiddle: http://jsfiddle.net/PJdNW/
Any help is appreciated.
UPDATE
From what I understand, CSS cannot figure out what the height of the scrollable-content needs to be, so in order for the scrollbar to work and be the correct height, the pixel height of the scrollable-content needs to be set.
In my case, the height of the overall container is dynamic, so I opted for a JS solution, which gets the height of the overall container and subtracts the height of the scrollable-content header in order to get the pixel value I need for the scrollable-content (plus some fine-tuning i.e. margins).
I'll leave this question open for the moment in the hopes that I'm wrong and CSS is up to the task.
You have to set the height of your container, otherwise the container will automatically resize to the content length. Also, set the overflow attribute to scroll. Fix below:
.container {
height: 200px;
border: 1px solid black;
overflow: hidden;
}
.left {
float: left;
}
.right {
overflow: hidden;
}
.scrollable-content-header {
font-size: 25px;
border-bottom: 1px solid black;
}
.scrollable-content {
font-size: 18px;
overflow: scroll;
height:200px;
}
Updated fiddle: http://jsfiddle.net/hdrenollet/PJdNW/1/

Resources