css-grid div not resizing when used in react component - html

I have made a css grid layout in a sample portfolio page i have made, when i did it with just html / css it worked fine and was responsive: The code is here:
https://codepen.io/abhinavthinktank/full/YevQNq/
The one which isn't responsive is hosted here:
https://abhinav-m.github.io/
The react components for the same are here: https://github.com/abhinav-m/personal-portfolio/tree/master/src/components
I made the same using react, sass and node, however this one is not responsive, to be exact the div with the class techStack is not resizing.
Here's the grid layout css:
.gridContainer {
display: grid;
grid-template-rows: 15px 10% 20% 10% 20% 20% 20% 25px;
grid-template-columns: 10% 80% 10%;
grid-row-gap: 25px;
justify-items: center; }
and the div class='techStack' css:
.techStack {
grid-row: 6 / 7;
grid-column: 2 / 3;
background: bisque; }
The CSS of both of these appear to be the same! I can't understand why one of these is not working.
LINK FOR JSFIDDLE : https://jsfiddle.net/69z2wepo/121098/ (not responsive)

Your image icons (.dev-icon-* colored) are a list of inline-level ::before pseudo-elements, which are each contained inside an inline-level i element, which are all contained inside a block-level div element.
The icons are provided by a third party service (devicon).
For whatever reason, these pseudo-elements, as devicon icons, don't wrap.
However, if you switch out the devicon code (e.g. content: "\e845") with plain text (e.g. content: "text text text text"), then the pseudo-elements do wrap.
Alternatively, if you switch the div container from display: block (the default) to display: flex, the devicons wrap, as well.
So the problem seems to boil down to devicons in a block container.
Here's a simple overall solution:
div.icons {
display: flex;
flex-wrap: wrap;
}

I had a look but I can't work out what the cause of the difference is. I'm guessing it's a style somewhere else on the page or because of a slightly different structuring of elements.
However, if you set the style of your icons to display: inline-block then it fixes your problem.

Related

CSS Grid inside Max-width Container

I have a parent section div with a max-width of 1760px.
I can put a carousel directly inside a section container and it will take the width of the viewport up to 1760px i have set, works as expected. *carousel will try to fill 100% of space given.
However, the issue is that i want to put the content inside a 2 col grid, inside container, but the first part of the grid has the carousel that takes the max-width of parent section, rather than stopping at width of page. So, rather than take 2fr of the viewport (map takes 1fr), it fills whole of 1760px so the screen overflows.
Style wise, The best example i can find online to show what i mean is Airbnb listing, it has 2 cols, 1 with listing and 1 with map. This is pretty much what i am trying to replicate.
Here is the carousel directly in section (pretty simple and works as explained above). If i put the carousel inside this it doesn't overflow page.
<section>
<div>Carousel</div>
</section>
section{
max-width: 1760px;
padding: 50px 40px;
margin: 0 auto;
}
Once i add it inside a grid it ignores the viewport size and simply fills max-width of section (1760px) and overflows viewport width.
<section>
<div class="grid">
<div>Carousel</div>
<div>Map</div>
</div>
</section>
.grid{
display: grid;
grid-template-columns: 2fr 1fr;
grid-gap: 20px;
}
It actually works using grid-template-columns: 60% 40%; instead of 2fr 1fr, and removing margin: 0 auto. But this means i cannot use gap (which is fine).
To summerize, how can i use fr sizing and make sure it takes notice of viewport size, and not just take up the max-width value by default.
I went through your pen and made some changes and it gave the result as you wanted it to be, no overflowing of the image.
If you do following changes, it will work for you too:
These are not mandatory, if you wish you can do the changes or else you can keep as it is.
Remove the max-width: 1760px from section style.
Add max-width: 1760px to the grid element, since you are providing the max-width to the grid, the parent section will also have this max-width, since grid is the child element.
Now make sure you are applying the width: 100% to the images (This is mandatory). Like this:
.listing > img {
width: 100%;
}
OR, if you have nested elements inside .listing element and img tag is not the immediate child of the .listing element, then you can go with this way:
.listing img {
width: 100%;
}
So every img tag which is direct or indirect descendent of .listing element will have width 100%
Here's the working piece of example:
https://codepen.io/prathameshkoshti/pen/KKMYoWY?editors=0100

Pure CSS: centering vertically and horizontally an absolute positioned element with width depending on children

So... I got this code: https://jsfiddle.net/jmg63s3e/1/
The code actually works fine if you resize the browser window until you have the text inline with the image and that's what I'm trying to achieve, but if you resize it down eventually the text drops below the image even if the wrapper width is a lot smaller than the window width.
My only purpose is to have:
the whole wrapper centered both vertically and horizontally in the browser window. Its total width and height unknown, depending on its children
row1 and row2 must not be inline: row2 must be below row1
All the elements inside row1 (the image and the text containing 2 spans) must be inline with each other
And well, the spinner inside row2 must also be centered inside the row but that was never a problem whatever solution I tried
As a matter of fact the only dynamic element in the whole code is the first span which in the example contains Player #1, since it should be the name of the player and it can be anything, any length.
Of course if I wanna make it responsive I will have to use media queries or dynamically change widths and heights and font-sizes with JS, and I'm willing to do so. My problem here is only the wrapper itself and the text that drops below the image even if the wrapper width is a lot smaller than the window width, so I'm asking for a solution that works as long as the wrapper width is smaller than the window width. When the wrapper width drops below the window width, I will handle the style with responsive media queries or JS. I would just like to have the wrapper to be centered both vertically and horizontally in the window, and its size to be dynamic and depending on children.
I've already tried any solution I could think of, but with an unknown wrapper width I just can't figure it out. Can someone help me please? I'm open to any suggestion and any solution, as long as it's pure CSS and it doesn't involve JS. Thanks everyone in advance
You can use flexbox to fix these problems.
Here's an updated fiddle with old CSS commented out: https://jsfiddle.net/jmg63s3e/3/
First, to align the wrapper both horizontally and vertically you need to make the parent container a flex container with display: flex and use justify-content: center and align-items: center. You also need to set a height or else it will wrap to the height of the child and not give you the centering effect. I used the following. The height can be whatever you need it to be.
.trump-waiting {
display: flex;
justify-content: center;
align-items: center;
font-size: 0;
overflow: hidden;
height: 100vh;
}
Next, I used display: flex on the wrapper and flex-direction: column to make sure they are all lined up like we want them to be.
.trump-waiting .wrapper {
display:flex;
flex-direction:column;
To fix row1, again I used flexbox and removed the inline-block and the set height. You could set the height as long as you take care of resizing the font in the text divs, with media queries for instance. Otherwise, with an explicit height, the font at the size it's at now will break out of their containers. Without explicitly setting the height, the containers will adjust in size.
.trump-waiting .row1 {
display: flex;
flex-direction: row;
/* display: inline-block; */
/* height: 60px; */
background-color: yellow;
}
I also added flex-shrink:0 to .image to keep it from shrinking on resize.
To keep Player #1 and 'is choosing the trump suit' inline, I also added display: flex and flex-direction: row to .row keep them on the same line.
Finally, to align the loader, I did the vertical/horizontal alignment trick used above, plus added some padding to the div to give it some space and removed the old css.
.trump-waiting .row2 {
display: flex;
justify-content: center;
align-items: center;
padding: 16px 0 16px 0;
/* display: block; */
/* margin-top: 50px; */
The last step would be to use media queries to adjust the font-sizes on .text spans so the font doesn't expand their container on resize.
Many ways to skin a cat and I'm sure others will have different perhaps better solutions, but hope this helps. There's a great summary of flexbox here if you need it. I may have left out a change in this summary, but it should all be in the fiddle.
EDIT: Realized I made a mistake summarizing the css in the jsfiddle and also removed a redundant css property. Now updated.

Flexbox not wrapping items as expected

I need to create a drop down navigation menu which wraps onto two lines when it is really long.
By setting the following CSS properties on the menu I can achieve the desired result.
.dynamic {
position: absolute;
max-height: 80px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
This, however, does not work on Internet Explorer 11. The items do not wrap onto the next line as it does on Chrome.
Here is a jsFiddle
It will work if I use height: 80px instead of max-height: 80px; but that does not work for me as I want the menu to grow with the items.
Does anyone know how I can get IE to wrap the items properly?
Since CSS Flexbox is not fully supported to provided a wrapping menu when the items pass a maximum height I have created a workaround using the height attribute.
As #Michael_B pointed out, the container doesn't wrap around the wrapped items.
A solution to this is apply the background style to the flex items instead of the container like this
This allows the container 'to appear' to grow with the items. Then using the nth-child pseudos I can allow the last item to span the full height of the container.
.dynamic > li:nth-child(4n),
.dynamic > li:last-child:nth-child(n+4) {
flex: 1 0 auto;
}

Exclude element with fixed positioning from justify-content in flex layout [duplicate]

This question already has answers here:
Absolutely positioned flex item is not removed from the normal flow in IE11
(4 answers)
Closed 6 years ago.
I'm currently trying to build a responsive website layout with flexbox.
Depending on the screen size I want an element to have position: fixed; This itself is working. But when I use justify-content: space-between; on a column that contains an element that gets moved out of the of column itself with position: fixed; the space distribution uses this element as an 0 height element.
For the sake of demonstration I set up two examples. Both do not use media queries because they are not the problem.
In the first example I created what I want the final result to look like. I had to move #fixed outside of .column in order for the space distribution to work properly.
In the second example I created the desired HTML markup. When you compare both example side by side you will notice that the spacing looks odd in the second. The browser is not making an error here because there is an element it has to respect when distributing the space. I (in a nutshell) would like the browser to pretend #fixed is not inside the container and therefore not consider it when distributing space.
This is how the result should look: https://jsfiddle.net/5nu9nsyL/3/
And this is how the html should look: https://jsfiddle.net/5nu9nsyL/4/
(Only Chrome and Safari renders it correctly. So if both look the same to you have a look at it with a different browser like Firefox or IE)
I hope I made my it clear what I want.
(Note I must use display: flex on the container .column)
(I also need a JavaScript free, CSS only solution)
This is Firefox bug 874718. The spec says
The justify-content property aligns flex items along the
main axis of the current line of the flex container.
Since an absolutely (including fixedly) positioned element is out-of-flow, is not a flex item (this is fully defined in Absolutely-Positioned Flex Children). So justify-content should ignore it.
But Firefox wraps it inside an anonymous flex item, according to an old spec:
Absolutely positioned children of a flex container are not themselves
flex items, but they leave behind "placeholders" in their normal
position in the box tree. These placeholders are anonymous inline
boxes with a width, height, and line-height of ‘0’, and they interact
normally with the flexbox layout algorithm. In particular, they'll
trigger the creation of anonymous flex items, or join neighboring
inline elements in their anonymous flex items.
To fix that, instead of using justify-content, I recommend aligning with auto margins:
.column > div:not(:first-child) {
margin-top: auto;
}
That will distribute free space equally before the children of the flex container, except the first one. The effect should be like justify-content: space-between.
In the case of the fixed element, that auto margin will just compute to 0.
.column {
display: flex;
flex-flow: column nowrap;
height: 300px;
float: left;
margin: 10px;
border: 3px solid black;
}
.column > div:not(:first-child) {
margin-top: auto;
}
.column > div,
#fixed {
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 50px;
background-color: red;
}
#fixed {
position: fixed;
top: 0;
right: 0;
}
<div class="column">
<div>Element 1</div>
<div id="fixed">Element 2</div>
<div>Element 3</div>
<div>Element 4</div>
<div>Element 5</div>
</div>
Update
Upon reviewing the OP once more, this is the objective:
When the screen width is at a certain size (I determined 720px+), #fixed(col2 ele2) is position: fixed, if it's at a smaller width, it will be position: static. When #fixed is "fixed" it is no longer in col2, therefore the spacing between col2's children increase. What is desired is a consistent spacing between all divs (ie col2 spacing must coincide with col1 spacing).
The OP did not provide a means to show both states: fixed and static; of which static needed to be established. I have added two media queries that will insure both static and fixed states of #fixed will be triggered at 720px.
#media screen and (min-width: 721px) {
.spacer {
display: none;
}
#fixed {
position: fixed;
}
.column.column {
justify-content: space-between !important;
}
}
#media screen and (max-width: 720px) {
.spacer.spacer {
display: none !important;
}
#fixed {
position: static;
}
.column.column {
justify-content: space-between !important;
}
}
For some reason, when applying just the properties display and position, the justify-content: space-between would break. So I included justify-content: space-between to both media queries, unfortunately that didn't work either. So then I added !important, and it still failed. So then I used my secret ninja technique and doubled the class selector .column.column and I was victorious! Doubling up on a selector will increase it's specitivity to trump anything.
Plunker in Full Screen Mode Resize the browser to see the magic.
Plunker in Preview Mode
I don't understand what you want to with #fixed. But I do understand the problem described in the demo:
The space between Element 1 and Element 3 in the second column should be the same height as the other spaces.
Since the second column cannot arbitrarily space it's content by a predetermined length due to the nature of justify-content: space-between, you'll need just as many divs as the first column in order to obtain the same spacing as the first column. As I understand it, you cannot hard code layout (HTML), so I wrote a little JS to create an invisible div and append it to the second column thereby making the space between element 1 and 3 the same as the spaces between the children of the first column.
Fiddle

How to center things - display:block/inline-block

When centering things in html and css, I find two approaches - either applying on the element :
display:block;
margin:0 auto;
or using:
display:inline-block;
text-align:center; (on the parent element)
I always wonder which is better and why. Thanks!!
This is a classic and important question.
Elements can either be inline (meaning they all sit next to each other - like a span tag) or they can be block (meaning the stack up on top of each other - like a div tag).
Margin: auto, while a bit odd when you first see it, is the best and only way to center a block level (position static), element.
For anything that is display: inline (like a span tag) - the only way to center it is if you specify text-align: center on the parent. This will center everything display: inline inside it that is position: static;
Display: inline-block is a hybrid of the two that is relatively new (but supported as far back as ie7 if you use the hack mentioned in another answer). With inline-block, you get the benefits of inline, in that you can you stick a bunch of things next to each other and have them all be centered (think of a nav where all nav items are all centered), but ALSO have each item take advantage of some of the stuff you get with display: block - the most important one being HEIGHT.
Imagine a scenario where each nav item has a background image that is 80px tall - you can't make an inline element have a height of 80 - so you'd have to make each element display: block - only then can you give it a height. So to make them all appear next to each other, you'd float them. The problem is if you float them, you can't have them all be centered on the page unless you give a fixed width to the nav and margin: auto THAT. This means the nav has a fixed width - might be okay, but there are times when the nav has to have dynamic elements, different widths for different languages, etc.
Enter display: inline-block.
Block elements should always be centered using
.block {
margin-left: auto;
margin-right: auto;
width: 600px;
}
as stated by the w3c: http://www.w3.org/Style/Examples/007/center.en.html#block
text-align: center;
is well-named: use it to center texts.
Update
You can also use display: flex now:
.parent {
display: flex;
justify-content: center;
}
.block {
width: 200px;
}
There is no better way in this situation both approach will work and both are corrected. Just one thing display:inline-block doesn't work on IE7 (if you support this browser) you will need a hack to make it work
display: inline-block;
*display: inline;
zoom: 1;