I'm currently trying to figure out a way with CSS to layout semantically-defined multi-image figures, each image possibly with their own subcaptions. The semantic for this kind of figure is an outer <figure> div containing multiple <figure class=subfigure> divs. Each of the .subfigure divs contains exactly one <img> followed by a <figcaption class=subfigcaption>.
Here is a minimal working example on JSFiddle
Goal: I'm trying to achieve a kind of layout that is common in print media; each .subfigure is vertically aligned by the baseline of its unique <img> element, while its own .subfigcaption can run as long as it needs without affecting the relative positions of the <img> amongst each subfigure.
However, with my current layout code, I can only relatively align each .subfigure as a whole: the <img> and .subfigcaption is treated as an aggregate block. The result is, as can be seen in my working example, that a long subcaption can ruin the image alignments between the subfigures.
I'd really like to find a CSS solution that does not require me to change the semantically-relavant HTML. I've considered using the table layout format, but I don't see how to place the table rows correctly given the way my html is currently organized. Also, this style would be applied to a large number of content, so I can't exactly tweak each specific figure by hand.
Note: doing figure>figure {vertical-align: top;} looks okay for this example but isn't what I'm looking for. The goal is to mimic a print convention, that we align at the bottom of the images, not the top. In fact, the more exact goal is to have all the .subfigcaptions start at a common baseline, regardless of the relative size of the images.
Current layout
Desired layout
Err, am I missing something, or does just removing the vertical-align: middle give you the desired results:
http://jsfiddle.net/LzUaC/9/
Here is the demo:
http://jsfiddle.net/salman/LzUaC/29/
And the idea:
Use display: inline-block for sub figures so that:
They stack sideways
Their baselines align
Place images with width: 100%; height: auto; inside sub figures
Optionally set vertical-align: bottom; to remove those few pixels at the bottom
Place captions with float: left; inside sub figures so that:
They move out of the flow and do not affect the height of sub figure
Set width: 100%; to make them stretch all the way across sub figure
Use clear: both on the last figure caption (I think you should however it does not seem to have any effect)
The CSS:
figure {
margin: 1em 0;
text-align: center;
background-color: #CCC;
}
figure > figure {
display: inline-block;
background-color: #AAA;
}
figure > figure > img {
width: 100%;
height: auto;
vertical-align: bottom;
}
figure > figure > figcaption {
float: left;
width: 100%;
background-color: #999;
}
figure > figure + figcaption {
clear: both;
background-color: #666;
}
/*
* for testing
*/
figure > figure:nth-child(1) {
width: 31%;
}
figure > figure:nth-child(2) {
width: 31%;
}
figure > figure:nth-child(3) {
width: 25%;
}
I know this might scare you at first but give it a chance :-P You can always replace the tables with divs contenting display:table and table-cell.
This is about the only way I could think of to achieve this effect.
http://jsfiddle.net/LzUaC/5/
CSS
.fig-img{width:40%; text-align:center; vertical-align:bottom;}
.fig-img img{width:100%;}
.fig-caption{vertical-align:top;}
.fig-summary{text-align:center; padding-top:40px;}
Removing
figure>figure {
vertical-align : middle;
}
figure>figcaption {
display : -webkit-box;
display : -moz-box;
display : -ms-flexbox;
display : -webkit-flex;
display : flex;
}
and Adding
figure>figure>figcaption {
vertical-align : top;
display : inline-block;
}
figure>figcaption {
text-align : center;
}
does the magic: running demo
Not using flex, and works everywhere... except that in IE (what a surprise...)
Related
So I am designing a website right now (pretty nooby at HTML and CSS) but I made a design on Photoshop beforehand so that I could go right through the coding and make the website how I wanted. Well I have an issue. I have two DIV elements inside of a bigger container DIV that won't line up side-by-side, despite using inline-block. Here is the css code:
.contentContainer {
display: block;
width: 700px;
height: 250px;
margin: 20px auto;
}
.topContainer {
height: 230px;
padding: 10px;
background-color: white;
}
.topThumbnail {
display: inline-block;
width: 370px;
height: 230px;
}
.topThumbnail img {
width: 370px;
height: 230px;
}
.topInfo {
display: inline-block;
margin-left: 10px;
width: 300px;
height: 230px;
}
.topInfo p {
width: 300px;
height: 230px;
background-color: pink;
}
The contentContainer is the highest DIV holding my topContent and topThumbnail so I thought I'd throw it into the provided code.
And the HTML code:
<div class="topContainer">
<div class="topThumbnail">
<img src="YT.png" />
</div>
<div class="topInfo">
<p>Testing the information area of the top container or something along those lines</p>
</div>
</div>
Can't post pictures to explain the issue.. need 10 reputation.. will make it hard to describe.
In the design the two containers for the Thumbnail and the Info are supposed to be side-by-side and aligned at the top. The thumbnail is supposed to be on the left of the topContainer and the Info is supposed to be to the right of the thumbnail with a margin of 10. For some reason the info is not going to the right-side of the thumbnail but rather going under it. I have ALREADY set the margin to 0 to fix the default margin issues.
display: inline-block is working correctly in your example. What you need to add is vertical-align: top to your .topInfo div, and get rid of the default margin on your .topInfo p tag. Also, you need to make sure that there is enough room for the .topInfo div to sit to the side of the .topThumbnail div, otherwise it will wrap to the next line.
Like this:
http://jsfiddle.net/hsdLT/
A cleaner solution: I would look at ditching the display:inline-block CSS proporties on these elements altogether and just float them to the left. Then clear the floats by assigning clear:both to the .topInfo css property.
It's less code then your route will be and it's more structurally sound. :D.
.topThumbnail,
.topInfo {
float:left;
}
.topInfo {
clear:both;
}
Other people have already answered this with the solution, but I think it is important to understand why inline-block elements behave this way. All inline, table, and in this case, inline-block elements have the vertical-align property. The default value is set to baseline, hence the need to set vertical-align: top;.
See the docs here: https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align.
This other discussion is also helpful: Vertical alignment for two inline-block elements not working as expected
I'm trying to create some evenly spaced columns (an ol), with the columns themselves being fixed width.
So far, I've managed to achieve the desired effect by using table layout, and nesting an additional element inside the list item.
HTML:
<ol>
<li><div></div></li>
<li><div></div></li>
<li><div></div></li>
<li><div></div></li>
<li><div></div></li>
</ol>
CSS:
ol {
display: table;
width: 100%;
}
li {
display: table-cell;
}
div {
margin: 0 auto;
width: 100px;
height: 250px;
}
This works great, but has the following 2 shortcomings:
As you can see in the demo, the first & last columns don't line up flush with the parent's outer edges.
This can't really be used responsively. The only thing you can do at smaller widths is stack them, but I'd like to split them (2 or 3 per row).
Is what I'm after even possible in CSS alone? I know there are a plethora of ways to accomplish this in JS, but I'm after a CSS-only solution.
P.S. I don't care about IE7-, but I do need to support IE8. CSS3 selectors are OK though, since I'm anyhow using selectivizr in the project (I know that's JS ;-)).
It seems appropriate for you to recycle "how to *really* justify a horizontal menu". Basically the behaviour you're describing is that of inline-block elements of identical width having text-align:justify applied:
ol {
/*force the desired behaviour*/
text-align: justify;
/*remove the minimum gap between columns caused by whitespace*/
font-size: 0;
}
li {
/*make text-align property applicable*/
display: inline;
}
/*force "justify" alignment that requires text to be at least over 2 lines*/
ol:after {
content: "";
display: inline-block;
position: relative;
width: 100%;
height: 0;
}
div {
display: inline-block;
width: 100px;
height: 250px;
}
Working fiddle.
NB: you may have to re-apply desired font-size and text-align to descendants of ol depending on the reset you're using (i.e. to prevent these properties from being inherited)
Ok my first thought would be to use media queries to gain a responsive approach for how many you want to show per row on differing screen sizes and my second would be to use
box-sizing:border-box;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
this will stop the paddings you may put in later adding onto the box model size.
Hope this is close to what you are after.
I have problem to make layout as figured at image below:
I need decorate H2 by horizontal lines. Size and position of lines depends on content of H2. The backround of H2 has to be transparent because background behind hasn't solid color.
Do you have any idea how to style this? Any HTML and CSS is allowed, no restrictions.
This can be achieved using HTML and CSS only, but you may want to think about browser compatibility. This website shows some great HTML/CSS only solutions and their compatibility with multiple browsers. There is also a method that uses jQuery (on the website).
I came to this pure css solution involving both display: table and display: table-cell (all modern browser and IE > 7, see http://www.quirksmode.org/css/display.html)
HTML
<h2><span>An example of title</span></h2>
CSS
h2 {
display: table;
width: 100%;
text-align: center;
}
h2 span {
display: table-cell;
padding: 0 15px;
white-space: nowrap;
}
h2:before, h2:after {
content : "";
width : 50%;
display : table-cell;
}
h2:before { background: ... /*a line background in position center right; */ }
h2:after { background: ... /*a line background in position center left; */ }
Since your lines end with a very small vertical line you should create two different backgrounds (or a sprite) each one wide at least 50% of your maximum layout width and insert them as background of before and after pseudoelements of <h2>
jsFiddle example (tested on FX9 and CH16): http://jsfiddle.net/PsCrk/2/
this is the layout I'm working with. what I'm trying to achieve is that as the window is collapsed I want the div on the right to collapse allowing the inner elements to be pushed down.
my css is as follows:
#left-div {
display: block;
float: left;
}
#right-div {
display: block;
float: left;
}
#right-div elements {
display: inline-block;
}
I basically want to achieve what's going on in the last photo without the right div getting moved down first. any ideas?
Edited to remove pictures as I've come to an answer and I'm not sure if I was supposed to post them.
After taking various stabs at it, appears that JavaScript/jQuery may be your only solution...
Hey guys I have an interesting set up going on. I'm working on creating SOME mobile support for an existing site. Basically when the window is brought to a certain size or the page is opened up on a phone I want to the header to do something different. That part is easy the only thing I'm running into is this.
The basic structure of my header is this
[logo][user-stuff][right-side][1][2][3][/right-side]
These elements are all in a nice line in my header. My problem is that in mobile I need one of the elements from inside the containing div on the right to float underneath the header. So I either need it to pop outside of its container or I need its container to take up with the width of the screen. The idea is that it will end up looking like this.
[logo][user-stuff][right-side][1][2][/right-side]
[ 3 ]
any ideas how this can be done? If I have to use some Javascript to make this possible that's fine, but the markup needs to be minimal as per my bosses instruction. Just a little stumped on the direction.
current html
<div id="header">
<div id="logo"></div>
<div id="user-stuff"></div>
<div id="right-side">
<div id="1" class="right-side-section"></div>
<div id="2" class="right-side-section"></div>
<div id="3" class="right-side-section"></div>
</div>
</div>
current css
#header {
height: 48px;
width: 100%;
}
#logo {
display: inline-block;
vertical-align: top;
}
#user-stuff {
display: inline-block;
vertical-align: top;
}
#right-side {
display: block;
float: right;
}
.right-side-section {
display: inline-block;
vertical-align: top;
}
Of course this is just a little bit of mockup code to give you an idea of the structure i'm working with and how everything is laid out. I just need to figure out a way to have div#3 drop underneath everything and take up the width of the screen when the screen is a certain size. Not sure how to have it breaks it's flow.
Since the header has a defined height this will be easy. Just add position: relative so that you can absolutely position child elements relative to itself.
Then you can set the css for div#3 to use absolute positioning as in the following example.
#header {
height: 48px;
width: 100%;
position: relative;
}
#3 {
position: absolute;
top: 48px;
left: 0;
width: 100%;
text-align: center;
}
See working Demo here: http://jsfiddle.net/Cce9n/
Please note that it is not valid to assign an ID starting with a number.
You may use Javascript to edit other div definitions,
E.G. changing the text-align style
document.getElementById("right-side").style.text-align = "center";