I found many ui library or framework's grid system has no easy way to merely center vertically a block with width. I just want says a block with max-width of 200px in the center, how can I avoid using custom css to style it?
https://codesandbox.io/s/antd-layout-ch745
doc: https://ant.design/components/grid/
To achieve the centering is easy. In a 24 column grid you can use the Col component and play around the span numerics to make sure width is same left and right. For example, these are all column settings that would get you centering:
<Col span={12} offset={6}>
<Col span={10} offset={7}>
<Col span={8} offset={8}>
<Col span={6} offset={8}>
Simply pick a span that is an event number, and the offset equals (24 - span) / 2.
The problem is the max-width: 200px. To restrict the max width to a value no matter what screen size it is, I am afraid you're going to have to write custom CSS for it, simply because there is nothing that will get you a specific value without you specifying what that value is.
In that case, I suggest creating one row and one column that spans that entire row, and use flex to center your element:
<Col span={24}>
<div style="display: 'flex'; justify-content: 'center';">
<div style="flex: 1; max-width: '200px'">
</div>
</div>
</Col>
Related
So basically I am using material ui to set up a grid system to display videos in 2 rows. I have achieved the general layout but I can't seem to remove the white space/padding between the elements. I tried nowrap as the docs suggest but it doesn't work as intended. Here is my component:
<Grid
container
spacing={1}
direction="row"
justify="center"
alignItems="center"
>
{media.map((media) => (
<Grid item xs={6} key={Math.random()}>
<video
className="media__object"
autoPlay
loop
src={media.mp4}
/>
</Grid>
))}
</Grid>
Here is some of the css of media__object
.gif__object {
border-radius: 5px;
height: 100%;
width: 100%;
object-fit: cover;
}
Here is what the current situation looks like. I added some background color to make the space easily visible.
Thank You!
As far as I'm aware, you're not going to be able to get rid of that vertical space with CSS alone - you'll need some JS. The design style I understand you want is called 'masonry'.
What you're seeing is two rows with two columns in each. The row will be the height of the tallest column within it, then after the page width is filled (two half-width columns), it drops down to a new row. That's a limitation of CSS (there are some CSS-only workaround attempts for the desired layout, but they're not well supported). An alternative would be to create two columns and fill them separately, then they're not occupying the same 'row' as the item next to it. But I don't think that's what you want to do either since the order of elements will be off and you'll have to work out how to fill them evenly.
Try something like this JS masonry library.
I am using react bootstrap, I am trying to align items vertically within a row but with no luck. My problem is I have a button in one of the columns, so for the other columns all the texts are shifted up a bit while the button and its content have a larger height.
My question is how can I make all columns within a row to have the same height and to all align in the middle vertically?
The only solution I managed to find so far is using CSS:
tranform: translateY(-50%)
this does the trick, but I was looking for a better more dynamic solution as this needs to be applied for every column excepts for the button column
EDIT: When I say columns and rows, I'm talkign about bootstrap's Col and Row, not actually a table or rows and columns; sorry for the misunderstanding
You can apply any of Bootstrap's classes to a React Bootstrap component. So, per the Grid System docs, the following columns will both be centered vertically:
<Row className="align-items-center">
<Col>
<h1>{title}</h1>
<p>{details}</p>
</Col>
<Col>
<button>{callToAction}</button>
</Col>
</Row>;
If you are using table rows, you can wrap contents within a <div>..</div>
like:
<tr>
<div classname="align-me"></div>
</tr>
and then you can use flexbox to align them dynamically:
tr .align-me {
display: flex;
align-items: center;
}
I had the same problem, and I found this:
<td className="align-middle"></td>
ref: https://www.codegrepper.com/code-examples/html/bootstrap+table+text+vertical+align+center
I tried the snippet in #kburgie's answer, but it did not work for me, my Row wouldn't budge an inch. So, I drew a border around that Row, to figure out what was happening.
Seems that Row has just enough height to fit its children, not an inch more, and that's why it can't move vertically. Gave the row some height, and it worked effortlessly.
.viewport-height {
height: 100vh;
}
<Row className="align-items-center viewport-height">
<Col>
<h1>{title}</h1>
<p>{details}</p>
</Col>
<Col>
<button>{callToAction}</button>
</Col>
</Row>
Could've added this as a comment to #kburgie, but I lack reputation.
Prompt
Suppose we want to distribute a row of inline-block elements inside a div of flexible width, we consider the spaces on the far end of the first and last elements to be significant and should be part of the spacing.
Mark-up
<div id="whole-thing">
<!-- inline-block element, width shrinks to widest row -->
<div id="row1" class="row">
<!-- block element (100% width) -->
<div id="box1" class="box">
<div id="box2" class="box">
..
</div>
<div id="row2" class="row">
..
</div>
..
</div>
Picture
I.e. Turn something like this
into this:
In this case, the width of the whole thing shrinks up to the 2nd row (widest) so there's no spacing between any of the boxes on that row.
But the content in each boxes may vary, and the spacing should adjust accordingly if necessary:
Attempts
justify-content: space-between (or other styling/work-arounds to the same effect):
Is not what we want.
justify-content: space-around should be it apart from the fact that it distribute the spaces with half-size spaces on either end, which, again, is not what we want, but almost..
Compare:
js hack. Well, it works, but I am still hanging on to the hope that there's a clean way to go about implementing this.
Adding an empty div at the beginning and the end of every row div and then use space-between.
Also works, and it's how I got the above pictures of the solution. But then I would end up with a bunch of empty divs.
Should I use table layout for this (in css, not in mark-up)? If so, how?
This is making me weep. I would be thankful for any help towards a clean solution to this.
Here's a link to fiddle
Solution
Fiddle
Placing content:'' ::before and ::after the rows (these pseudo-elements are direct children of the selected) effectively implements the 4th point above (space-between + empty elements at both ends) without redundant mark-up.
I agree this should be covered by flexbox itself.
Currently we only have space-around but it's just incomplete.
ATM the best solution for you is to wrap rows inside two pseudo elements. Basically it's your solution, but you won't need to touch the actual markup since it's generated content.
http://jsfiddle.net/5rmUj/
.row::before, .row::after
{
content:'';display:block;
width:0;height:0;
overflow:hidden;
}
I have a 2-column fluid Twitter bootstrap layout, and want an iframe in one of the panes (it will contain the Google tasks widget -- https://mail.google.com/tasks/ig). How do I set the width properly? I figured out how to set the style so it has a border (to distinguish it as external page content), but I can't make it fill one of the columns properly. This is what I currently have:
<iframe class="container well well-small"
style="width: 80%; height: 400px; background-color: #f5e5c5;"
src="https://mail.google.com/tasks/ig">
</iframe>
Full example (save as an HTML file): http://pastebin.com/1u2QeuZk
Use the row-fluid class to define a row, and spanX classes to define columns. Like so:
<div class="row-fluid">
<iframe class="container well well-small span6"
style="height: 400px; background-color: #f5e5c5;"
src="https://mail.google.com/tasks/ig">
</iframe>
</div>
However: The Xs in the spanX need to add up to 12 for each row. So in the above example you would need to wrap the content of the other column in a tag with a span6 class as well, or you can use the offset6 class on the iframe if it is the only content on that particular row in order to make it align to the right.
To have one column be wider than the other you can change it up by changing the X in spanX, just make sure they add up to 12 for a row.
In case you were wondering how to make a column a specific width: The whole point of a fluid grid is to not use specific widths. You set the width of the container (preferably with relative units as well, in order for the content to adapt to the size of the viewport), and each column will be 1/12th the width of the container. So if you do want to control the width exactly, then you could always make the container a specific width so that the column you want can have a width that's a multiple of 1/12th the container's width. I.e. if you want the column to be 400px wide you could make the container 800px wide and use the class span6 on the column. Or use span3 to make it 200px wide etc.
I's all explained very well in the docs: http://twitter.github.com/bootstrap/scaffolding.html#fluidGridSystem
From my reading of the documentation, it seems that .container is the "parent" wrapper for the .row and the divs that contain the .spanX (where the x totals 12). However, it doesn't seem like there is a .row in their navigation example.
Also, on their documentation site, the .container is wrapped by a couple of navbar related divs.
Can anyone elaborate a bit on how the framework should work? I'm new to it.
The .row class is not required inside a .container, but it is a good idea to include it anyways when you start incase you want multiple rows later on.
All that .row really does is make sure that all of the divs inside of it appear on their own line, separated from the previous and the following .rows.
For the .container inside of the .navbar divs, that is a separate thing that is required to make the navbar line up with the rest of the page. If you look further down in the rendered HTML, you'll see that there is another .container that is not inside any .navbar divs, and that is the one with all of the main content.
A Complete Example
<div class="container">
<div class="row">
<!-- These divs are inline and do NOT fill up the full 12 columns -->
<div class="span4">...</div>
<div class="span4">...</div>
</div>
<!-- This is a automatically a new line of divs -->
<div class="row">
<!-- This div will appear below the previous row, even though it
would fit next to the other divs -->
<div class="span4"></div>
</div>
<!-- These will appear in their own row, but may act
unexpectedly in certain situations -->
<div class="span4"></div>
<div class="span4"></div>
</div>
In Short
.row defines a row of divs, like the name implies. Each one indicates a new line of divs, no matter if the above line is full or not.
The answer is much simpler than those given. No, .container does not have to contain any specific code, and it has no encumbrances on what contains it...
What .container does is serve as a "wrapper" to "contain" the size of any and all elements wrapped inside of it. And .container can wrap pages or components. So, if you want a page similar to those Twitter Bootstrap's docs, with a "fixed" width and equal margin on both sides, then only a single .container is necessary to wrap all of the content on the page.
There are other uses for .container as well; have you noticed how the top navbar in Bootstrap's docs (.navbar-fixed-top) spans the full width of the screen, but the nav items inside the navbar are "contained" to the width of the content? This is because the .navbar-fixed-top is not inside a .container but the .nav inside it is.
The bootstrap grid is composed of 12 columns that can be adjusted in any combination within a row as long as they add up to 12. You can think of them as containment rows such as the likes of table rows, which are meant to separate different rows of content. Within the grid, the .row container has a separate task and is there (and required) to readjust the last grid columns gutter width, which varies depending on screen size (if the responsive sheet is included). If you look at the css behind the .row class you will notice that it has a property of margin-left:-30px by default (once again it can be greater or less depending on screen size), a property which is meant to "remove" the gutter from the last column in the row; without it the grid would not readjust the gutter and it would break onto a second line.
Now, the reason why the .row container is a child of the .container container is because the .row container is only meant to separate "lines" of content, not to contain sections and more over center content in a page. As such, the reason why the navigation example did not have one was probably due to the fact that the nav elements is lacking in gutter width, since it was meant to be a full block element and not a grid, so there was no need to reset that last loose gutter.