Welcome to WebmasterWorld Guest from 52.91.39.106

Forum Moderators: not2easy

Inline elements with percentage width and fixed padding

     
4:33 am on Apr 22, 2019 (gmt 0)

Senior Member

WebmasterWorld Senior Member 5+ Year Member Top Contributors Of The Month

joined:Mar 15, 2013
posts: 1095
votes: 103


I have a section like this:

<style>
.imgList {
float: left;
width: 150px;
height: 260px;
padding: 20px;
margin: 0 5px 10px 5px;
border: 1px solid #E3E3E3;
overflow: hidden
}

@media only screen and (max-width: 660px) {
.imgList { padding: 4px !important }
}
</style>

<div class="imgList">
<img src="image.jpg">
</div>


On my Galaxy S7 and my girlfriend's iPhone this always has 2 elements on each row, which is perfect. But recently her mom opened it on her iPhone 5s (resolution width of 320px), and it only put 1 element on each row with 152px of whitespace on the right.

Obviously, I COULD just make the .imgList width at 142px instead of 150, and that would solve the problem for that specific phone. But then when someone with, say, an iPhone 8 Plus comes on, with a resolution width of 414px, then there's 78px of whitespace on the right. So I'm not in love with that idea.

I tried this, which I thought would work, but didn't:

@media only screen and (max-width: 660px) {
.imgList {
box-sizing: border-box;
width: 50% !important;
padding: 4px !important
}
}


So for the @media only screen and (max-width: 660px) section, can you guys suggest a way that I can code .imgList to be 50% of the container, including the padding?
5:00 am on Apr 22, 2019 (gmt 0)

Administrator from US 

WebmasterWorld Administrator not2easy is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Dec 27, 2006
posts:4297
votes: 288


Padding is inside the container, it is deducted from the px size of the container so a padding of 4px reduces the available width by 8px.

I don't see any indication of the css for "img" but if the image size is not controlled using max-width: 100% then it may want to take more than the width you have allowed for it. Setting img: max-width to 100% insures that the image resizes to fit the container.
8:03 pm on Apr 22, 2019 (gmt 0)

Senior Member

WebmasterWorld Senior Member 5+ Year Member Top Contributors Of The Month

joined:Mar 15, 2013
posts: 1095
votes: 103


Padding is inside the container, it is deducted from the px size of the container so a padding of 4px reduces the available width by 8px.

I get that: if I made the whole element 50%, then the padding would be part of the 50%. But then the margin is outside of the element, right? So I have a left and right margin of 5px would make both elements combined 100% + 20px.

I think I've stumbled across a rather unattractive way that works, so now I'm hoping maybe you guys and gals can advise me on a way to make it cleaner?

<style>
.mobileFlex { display: inline }

.imgList {
float: left;
width: 150px;
height: 260px;
padding: 20px;
margin: 0 5px 10px 5px;
border: 1px solid #E3E3E3;
overflow: hidden
}

/* Mobile only */
@media only screen and (max-width: 660px) {
.mobileFlex {
display: flex !important;
box-sizing: border-box
}

.imgList {
width: auto !important;
flex-basis: 50%;
padding: 4px !important;
}
}
</style>

<div class="mobileFlex">
<div class="imgList">
<img src="image.jpg">
</div>

<div class="imgList">
<img src="image.jpg">
</div>
</div>

<div class="mobileFlex">
<div class="imgList">
<img src="image.jpg">
</div>

<div class="imgList">
<img src="image.jpg">
</div>
</div>


So here, if the width looks like a desktop then .mobileFlex just puts the elements inline. But if it looks like mobile then it changes to display: flex, then sets the width to auto and the flex-basis to 50%.

On the iPhone 5s this works, although it is still slightly wider than the screen and crops off a tiny bit on the right, as if I had set a fixed width to the container with overflow: hidden. My gf's mom didn't even notice that, but I did, so it's not quite perfect.

I also expected that, on desktop it would force the elements to wrap in groups of 2 instead of just wrapping wherever was correct, but on my Chrome it's wrapping properly (eg, not in groups of 2). I don't understand why, but it's what I wanted, so... good?

I also had to do some backend work in PHP to plug in the class="mobileFlex" container in the right places. They're being loaded in a while() loop, so the PHP turned in to:

$counter = 0;
$next_row = $sth->fetch();

while (list($foo, $bar) = mysqli_fetch_row($sth)) {
$mobileFlex = $counter / 2;

if ($mobileFlex == intval($mobileFlex))
echo <<<EOF
<div class="mobileFlex">

EOF;

echo <<<EOF
<div class="imgList">
<img src="image.jpg">
</div>

EOF;

$next_row = $sth->fetch();
if ($mobileFlex != intval($mobileFlex) || !$next_row)
echo <<<EOF
</div>

EOF;

$counter++;
}


It's definitely more complicated than I had originally anticipated, and still not exactly perfect :-(

I don't see any indication of the css for "img" but if the image size is not controlled using max-width: 100% then it may want to take more than the width you have allowed for it. Setting img: max-width to 100% insures that the image resizes to fit the container.

In the live code, I actually have a container around the image with a fixed width and height, and overflow: hidden. I just didn't want to throw a ton of unnecessary code at you :-)
9:02 pm on Apr 22, 2019 (gmt 0)

Senior Member

WebmasterWorld Senior Member Top Contributors Of The Month

joined:Apr 1, 2016
posts:2552
votes: 725


Padding is inside the container, it is deducted from the px size of the container so a padding of 4px reduces the available width by 8px.

This is not true (as I read it, the statement is somewhat ambiguous, what width exactly are you referring to?).

By default padding is added to the width of the container. If one sets the width to 100px and adds padding of 10px, then the container will rendered with a width of 120px but it's actual width will remain 100px. This can be seen by using dev-tools in Chrome (or other browsers) and clicking on the computed tab. The exact values for margin, padding, border, and the element are all shown.

If one sets the box-sizing attribute to border-box, then padding is included in the width such that an element with a width of 100px and padding of 10px, will be rendered as 100px with the actual width being 80px.

Regarding the rest of the code I have two suggestions:
1- If you use display:flex, then stick with flex. Don't jump between flex, and block. Instead you can play with the layout using flex-direction: row or column. "Row" for desktop and "column" for mobile or you can also try "wrap".

2- Do not mix float and flex. If you decide to stick with flex, then use "justify-content", to align the elements as desired, "start" for left-align, or "space-evenly" to have elements equally spaced.

Also note that with flex you can nest containers, so you can put a parent set to column with a two children set to row. See the demo:
[jsfiddle.net...]
12:06 am on Apr 23, 2019 (gmt 0)

Senior Member

WebmasterWorld Senior Member 5+ Year Member Top Contributors Of The Month

joined:Mar 15, 2013
posts: 1095
votes: 103


But on desktop I still have to allow for IE9, which doesn't recognize flex:

[caniuse.com...]

If I'm understanding correctly then it would be OK on most mobile browsers, with the exception of old Opera mobile which is virtually nonexistent in my Analytics. I'm not sure how to code it with the -webkit prefix or the "old flexbox specifications", though.
12:29 am on Apr 23, 2019 (gmt 0)

Senior Member

WebmasterWorld Senior Member Top Contributors Of The Month

joined:Apr 1, 2016
posts:2552
votes: 725


Have you thought about using a conditional style sheet?
[css-tricks.com...]
12:51 am on Apr 23, 2019 (gmt 0)

Senior Member

WebmasterWorld Senior Member 5+ Year Member Top Contributors Of The Month

joined:Mar 15, 2013
posts: 1095
votes: 103


Hmm. No, I honestly had not. Where were you about a year ago when I got in to this mess? lol
12:23 pm on Apr 23, 2019 (gmt 0)

Senior Member

WebmasterWorld Senior Member Top Contributors Of The Month

joined:Apr 1, 2016
posts:2552
votes: 725


I really don't know why I hadn't thought of this earlier either. I suppose it is because it is something that I have never done myself.
 

Join The Conversation

Moderators and Top Contributors

Hot Threads This Week

Featured Threads

Free SEO Tools

Hire Expert Members