Make two elements to have the same width with CSS - html

I have two elements (a paragraph and a img) inside a link element and i want the paragraph to be the same width as the img, i tried doing display: inline-block; and a couple other things but cant seem to get it to work. can anyone help?
<li>
<a href="https://store.steampowered.com/app/4000/Garrys_Mod/" target="_blank" >
<img src="/Photos/garrysmod.jpg">
<p>Garrys Mod is a physics sandbox game in which you can do allmost anything you want, including playing hide and seek, fighting monster, fighting eachother, escape from jail, and much more</p>
</a>
</li>

Edited/changed after comment (the question wasn't clear about this):
Apply display: flex and flex-direction: column; to the link, plus an optional width setting to the parent container (ul), and (also optionally) text-align: justify to the p tag to make the text align also to the right border:
ul {
list-style-type: none;
width: 400px; /* any value here, or no value to fill the horizontally available space */
}
li a {
display: flex;
flex-direction: column;
}
li a p {
text-align: justify;
}
<ul>
<li>
<a href="https://store.steampowered.com/app/4000/Garrys_Mod/" target="_blank">
<img src="/Photos/garrysmod.jpg">
<p>Garrys Mod is a physics sandbox game in which you can do allmost anything you want, including playing hide and seek, fighting monster, fighting eachother, escape from jail, and much more</p>
</a>
</li>
</ul>

I have given you an example below to learn from.
You should look into flex. It's just an easy way to control content. There is no actual purpose for it here, but I still gave the link container the flex property, because you would probably want to align the content later (e.g. align-items: center).
Read up on flexbox, good luck!
.link {
display: flex;
}
.link img {
width: 50%;
}
.link p {
width: 50%;
}
<div>
<a class="link" href="https://store.steampowered.com/app/4000/Garrys_Mod/" target="_blank" >
<img src="https://cdn.cloudflare.steamstatic.com/steam/apps/4000/ss_ff27d52a103d1685e4981673c4f700b860cb23de.600x338.jpg?t=1663621793">
<p>Garrys Mod is a physics sandbox game in which you can do allmost anything you want, including playing hide and seek, fighting monster, fighting eachother, escape from jail, and much more</p>
</a>
</div>

Related

Why flexbox code is not applying and text does not wrap?

I'm using flexbox to style my content. It worked on my first three divs, but on my third one, it is not working. I tried to apply things like flex-wrap to get my img and text to be side by side but they do not change and just stay stacked.
I've tried various flex tags, but it doesn't change. I want to use flexbox only.
#content {
background: #ccc;
padding: 30px 30px 30px 0;
display: flex;
flex-wrap: wrap;
}
#content article img {
margin-right: 30px;
}
#content h1, #middle h1 {
font-family: FuturaStdBoldCondensed;
font-size: 30px;
margin-bottom: .5em;
color: #5c5c5c;
}
#content p,
#middle p {
margin-bottom: 1em;
line-height: 1.5em;
}
<section id="content">
<article>
<img src="images/frontPagePhoto.jpg" alt="photo">
<h1>PROJECT: Cellular Network</h1>
<p>In Kenya we are creating a cellular network, which poses several challenges, but will also come with many rewards. We are hoping that by the end of the year, all areas of this country will have coverage. We are working with local authorities to put
service in reach of every villiage and community.</p>
<p>Read more about it, or get involved...</p>
</article>
</section>
The text continues to show below the image.
Move the image out of the article element. Put it in a figure element instead, giving it semantic value and making it a flex item in the primary container.
#content {
display: flex;
}
<section id="content">
<figure>
<img src="http://i.imgur.com/60PVLis.png" width="150" height="150" alt="">
</figure>
<article>
<h1>PROJECT: Cellular Network</h1>
<p>In Kenya we are creating a cellular network, which poses several challenges, but will also come with many rewards. We are hoping that by the end of the year, all areas of this country will have coverage. We are working with local authorities to put
service in reach of every villiage and community.</p>
<p>Read more about it, or get involved...</p>
</article>
</section>
You're not getting your text <h1> and <img> in same line because default display style property of h1 tag is block.
As per your existing code, making parent element flex container does not affect it. While there are many ways to fix this, simplest will be adding display: inline-block; to your h1.
You can read more about block and inline style properties here CSS display: inline vs inline-block
#content {
//background:#ccc;
padding: 30px 30px 30px 0;
display: flex;
flex-wrap: wrap;
}
#content article img {
margin-right:30px;
}
#content h1, #middle h1 {
display: inline-block; // <-- THIS
font-family:FuturaStdBoldCondensed;
font-size:30px;
margin-bottom:.5em;
color:#5c5c5c;
}
#content p, #middle p {
margin-bottom:1em;
line-height:1.5em;
}
<section id="content">
<article>
<img src="https://via.placeholder.com/100" alt="photo">
<h1>PROJECT: Cellular Network</h1>
<p>In Kenya we are creating a cellular network, which poses several challenges, but will also come with many rewards. We are hoping that by the end of the year, all areas of this country will have coverage. We are working with local authorities to put service in reach of every villiage and community.</p>
<p>Read more about it, or get involved...</p>
</article>
</section>
Alternatively, if you wish to achieve this using flexbox, you can give flex: 1 to img and h1 and wrap them in a flex container. Also, better give img flex-grow: 0 too.
You're applying flex to section tag which is not the immediate parent of the h1, p and img tags hence the flex property is not affecting any tags except the article tag. So, you must apply flex to article tag, which in this case is the immediate parent and it must work.
Hope this helps. Thanks.

Position two block elements side by side

I am trying to create a restaurant menu. I would like each menu item to be formatted as such:
Mozzarella Sticks ($9.95)
To do this I have the following html:
<h3 class="menu-item">Mozzarella Sticks</h3><p class="price">5.95</p>
I have the item name and price in different elements because I would like to make the price smaller, change the color, etc...
My problem is getting both elements to appear next to each other since h3 and p are both block elements. Here are the solutions I have come up with. Solution one:
.menu-item{
display: inline;
}
.price{
display: inline;
}
And adding a line break at the end of each entry:
<h3 class="menu-item">Mozzarella Sticks</h3><p class="price">5.95</p>
<br />
This works however I feel this is not the proper way to do this and that it should be done with CSS.
I have also considered the following, solution two:
<h3 class="menu-item">Mozzarella Sticks <span class="price">5.95</span></h3>
This would allow me style the price separate from the menu item, but including the price in the h3 still feels like an odd way to go about this.
Lastly, I have seen that you can set a width on both elements and then apply float: left; and float: right; but this messes up the spacing, as I would like the elements to appear right next to each other.
Any suggestions? Were any of the ways I listed a good way to about this or is there a better solution?
Try this grid layout. You can customize each block to your own liking.
You can add another column by inserting 1fr
.menu{
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
grid-template-areas: 'a b';
}
.menu-item{
grid-area: a;
text-align: center;
font-size: 20px;
}
.price{
grid-area: b;
text-align: center;
font-size: 18px;
}
<div class="menu">
<div class="menu-item">Mozzarella Sticks</div>
<div class="price"><i>($9.95)</i></div>
</div>
You can set widths as a percentages, let's say 80% and 20% respectively.
If you set display: inline-block you don't need to set any float. The elements keep having block properties but are kept inside the text flux like they were actual text.
Even though this works alone, i would suggest to also keep a better and cleaner semantic html division, like the ul showdev mentioned or at least a containing div for each couple.
You might consider creating an element for each item with children for the name and price.
Below, I'm using flexbox for item layout.
#menuItems {
margin: 0;
padding: 1em;
}
.menuItem {
margin: 0 0 1em;
display: flex;
}
.menuItemTitle {
flex: 0 0 150px;
margin: 0 1em 0 0;
font-size: 1em;
}
.menuItemPrice::before {
content: "$";
}
<ul id="menuItems">
<li class="menuItem">
<h3 class="menuItemTitle">Mozzarella Sticks</h3>
<span class="menuItemPrice">5.95</span>
</li>
<li class="menuItem">
<h3 class="menuItemTitle">Another Item</h3>
<span class="menuItemPrice">10.50</span>
</li>
<li class="menuItem">
<h3 class="menuItemTitle">Third Item with a Longer Name</h3>
<span class="menuItemPrice">10.50</span>
</li>
</ul>
My problem is getting both elements to appear next to each other since
h3 and p are both block elements. Here are the solutions I have come
up with. Solution one:
In general, if you want two block elements to appear next to each other without using the newer layout methods (flexbox and css grids). You can float the elements and then add a "clear fix" to those elements and here are two ways you do that.
Float the elements, Add an extra div, Add the clearfix
Float the elements, Add a CSS pseudo element "after", Add the clearfix
Method 1: Add extra div
<style type="text/css">
.clearfix{
display: block;
clear: both;
}
h3{
float:left;
}
p{
float:left;
}
</style>
<div class="my-container">
<h3>Hello</h3><p>World</p>
<div class="clearfix"></div>
</div>
Method 2: Add pseudo elem after
<style type="text/css">
.clearfix::after {
display: block;
clear: both;
}
h3{
float:left;
}
p{
float:left;
}
</style>
<div class="my-container clearfix">
<h3>Hello</h3><p>World</p>
</div>
Please note that on method 2, clearfix class was added to the container. Also, notice that a pseudo CSS element ::after was added to .clearfix.
This would allow me style the price separate from the menu item, but including the price in the h3 still feels like an odd way to go about this.
I think you are right. Building HTML should be semantic. Which basically means that your markup/code must be self-explaining or have meaning. In the context of what you are trying to achieve, h3 here (IMHO) doesn't suit what you are really trying to express or do. The reason I say that is because you are to display a list of "menu-items" and h3 by definition is a header so the element doesn't fit what it is trying to display. My recommendation is, instead of using h3, use a list instead, similar to the answer above. This would make your HTML code a lot more semantic and you can now use the other method you've mentioned without making it look weird (because span is inside of h3). It would look similar to the code below instead...
<ul id="menuItems">
<li class="menuItem">Mozzarella Sticks<span class="menuItemPrice">5.95</span</li>
</ul>
Btw, my recommendation above is just my opinion so please take it with a grain of salt. For more info about semantic HTML. You can check the links below
https://www.lifewire.com/why-use-semantic-html-3468271
https://www.w3schools.com/html/html5_semantic_elements.asp
Hope this helps! :)

Align elements inside an <a> tag vertically

I have an <a> tag (which is part of multiple <li> tags). In the <a> tag I have an <i> tag and some text - the text of the link.
What I would like to achieve is to have the icon on top and the text under it (and then centered). So it would look like:
ICON
MYTEXTHERE
However they are always placed next to each other. I tried using display: inline-block - because my <a> is inline and the content inside should be block but without success.
The fiddle is here: https://jsfiddle.net/6mg4vt77/5/
Edit: Thanks for the answers but sadly I forgot to mention that I must support IE9.
try this
<a href="/items/bluetooth" style="display: inline-block; text-align:center">
<i class="fa fa-bluetooth"></i>
<br>
BLUETOOTH
</a>
https://jsfiddle.net/6mg4vt77/7/
Quick answer, set the icon to 100% wide and center everything in the anchor.
a{
text-align: center;
}
a .fa {
width: 100%;
}
JSfiddle Demo
Modern Method
Flexbox:
a {
border: 1px solid grey;
display: inline-flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<a href="/items/bluetooth">
<i class="fa fa-bluetooth"></i> BLUETOOTH
</a>
In your test case I'll use two nested <span> within the anchor, one for the icon and the second for the text. Then I'll give them both display:block. That way one should position itself on top of the other. Finally you can nest the <i> tag within the first <span>, like so:
<a href="/items/bluetooth" style="display: inline-block;">
<span style="display:block;"></span>
<i style="width:100%;text-align:center;" class="fa fa-bluetooth"></i>
</span>
<span style="display:block;">BLUETOOTH</span>
</a>
Live demo here: https://jsfiddle.net/6mg4vt77/10/
Wrap your code in a div like so:
<div class="link" style="width:90px;text-align:center;">
<a href="/items/bluetooth" style="display: inline-block;">
<i class="fa fa-bluetooth" style="text-align:center;"></i><br> BLUETOOTH
</a>
<ul class="dropdown-menu ddcolumns">
<li>Main3</li>
</ul>
<div class="clearfix"></div>
</div>
That should fix your problem.
PS: You can always change the width in the div to your liking, even with % :-).
To answer the question as titled, "Align elements inside an <a> tag vertically", this https://jsfiddle.net/cdLp61ad/1/ is what I use to:
middle-align linktext vertically
and horizontally
Keep the clickable area under control (full height and width)
(don't be fooled by tabley-looking stuff, it's not tables!)
ul {
display: table;
table-layout: fixed; /* all cells same width */
margin: 0 auto; /* Optional */
}
a {
display: block; /* Makes line-height work */
line-height: 4em; /* Control HEIGHT of clickable area here */
padding: 0 16px; /* Control WIDTH of clickable area here */
}
li {
display: table-cell;
text-align: center;
background: bisque; /*just for visualisation*/
border: 1px dashed orange; /*just for visualisation*/
}
HTML nesting is done the 'usual' way:
<ul>
<li>
<a ... >
Multiple-lines in linktext leaves a gap, sorry
I'm still working on this...
Negative margin doesn't seem to help
The technique uses display: heavily so playing further with that 'may cause unexpected behaviour'
I'd probably try relative positioning next but I sure did give up last time, All my horizontal menus are on-liners!
See also:
OLD tech: Alignment how-to and how-not-to at phrogz.net
NEW tech: Promising info at sitepoint.com re Giving Floasts the Flick and Migrating to Flexbox
You CAN wrap A-tags round block elements in HTML5
Put the text you want to display into another HTML element, e.g. <p>. To center the icon, wrap it into an element and style it with text-align.
<p style="text-align: center">
<a href="/items/bluetooth" style="display: inline-block;">
<i class="fa fa-bluetooth" ></i>
<p>BLUETOOTH</p>
</a>
</p>

How to vertical-align text that runs multiple lines

I realise there have probably been a few questions with a title similar to this, but I think my question is a little different, I've tried to do some background reading and can't seem to find an elegant solution to this anywhere (although that's possibly because one doesn't exist)
Basically, I have three boxes, each with an image to the left, and some text in them, the problem is getting the text to vertical-align, having done some background reading on how vertical-align actually works (I wasn't entirely sure before) I tried implementing it to solve the problem, and it works perfectly well on all but one of the boxes, you'll see what I mean in the demo below:
http://jsfiddle.net/5vxSP/1/
The last box has a second line of text, and this line just ends up below the image, there are a few ways I can think of doing this, but most involve using a float for the image, and margins for the text of the last box, which, whilst working isn't a particularly nice way of doing it (well, I think so anyway . . .)
Is there an elegant way of doing this, so that the text will remain in the middle of the box regardless of the number of lines / font-size that I decide on using?
If I have to use my original solution I'm happy doing that, I was just interested to see if there was a better way of doing this that I have yet to discover.
HTML is very shoddy when it comes to vertical-align. The only way I've found to reliably do this is to do as follows...
<div>
<span style="display: inline-block; vertical-align: middle; height: [The height of your box here]"></span>
<span style="display: inline-block; vertical-align: middle;">Put your multi-line content here</span>
</div>
vertical-align in CSS aligns the inline element it is applied to with other inline elements around it. Only on tables does it align within the table cell.
Based on a proposed a solution for a similar problem here, you can do something like this.
Put the link texts inside spans.
Give these spans display:inline-block and the proper widths; which are the original widths of the li items minus the images and the paddings.
.main-services {
overflow: auto;
padding: 17px 0 9px 0;
}
.main-services li {
list-style: none;
float: left;
border-right: 1px dashed #E53B00;
padding-right: 14px;
}
.main-services li a {
display: block;
height: 78px;
color: #ED5D04;
text-decoration: none;
}
.main-services li a img {
vertical-align: middle;
}
.main-services li a span {
display: inline-block;
vertical-align: middle;
}
.service-1 span { width: 85px; }
.service-2 span { width: 131px; }
.service-3 span { width: 151px; }
<ul class="main-services border-common">
<li class="service-1">
<a href="#">
<img src="http://farm8.staticflickr.com/7177/6928101513_9288b942e8_t.jpg" alt="blah" />
<span>Some text goes here</span>
</a>
</li>
<li class="service-2">
<a href="#">
<img src="http://farm8.staticflickr.com/7177/6928101513_9288b942e8_t.jpg" alt="blah" />
<span>More text here</span>
</a>
</li>
<li class="service-3">
<a href="#">
<img src="http://farm8.staticflickr.com/7177/6928101513_9288b942e8_t.jpg" alt="blah" />
<span>More text goes here but this text overruns</span>
</a>
</li>
</ul>
Or check out the update to the fiddle (including the original reset stylesheet): http://jsfiddle.net/MrLister/5vxSP/15/
Note: this won't work in IE8.

How to make an inline element appear on new line, or block element not occupy the whole line?

I can't figure out how to do this with CSS. If I just use a <br> tag, it works flawlessly, but I'm trying to avoid doing that for obvious reasons.
Basically, I just want the .feature_desc span to start on a new line, but:
If I make it an inline element, it won't have a line-break.
If I make it a block element, it will expand to fit the entire line, putting each of these icons on its own line, and wasting tons of space on the screen (each .feature_wrapper will be a slightly different size, but none will ever be as wide as the entire screen.)
Example code: This works, but uses a br tag:
<li class='feature_wrapper' id='feature_icon_getstart'>
<span style='display: none;' class='search_keywords'>started</span>
<span class='feature_icon spriteicon_img' id='icon-getstart'><a href='getstarted/index.html' class='overlay_link'></a></span><br/>
<span class='feature_desc'><a href='getstarted/index.html' >Getting Started Wizard</a></span>
</li>
I want to style this with CSS to achieve the same result:
<li class='feature_wrapper' id='feature_icon_getstart'>
<span style='display: none;' class='search_keywords'>started</span>
<span class='feature_icon spriteicon_img' id='icon-getstart'><a href='getstarted/index.html' class='overlay_link'></a></span>
<span class='feature_desc'><a href='getstarted/index.html' >Getting Started Wizard</a></span>
</li>
Any ideas? Or am I going about this the wrong way?
You can give it a property display block; so it will behave like a div and have its own line
CSS:
.feature_desc {
display: block;
....
}
Even though the question is quite fuzzy and the HTML snippet is quite limited, I suppose
.feature_desc {
display: block;
}
.feature_desc:before {
content: "";
display: block;
}
might give you want you want to achieve without the <br/> element. Though it would help to see your CSS applied to these elements.
NOTE. The example above doesn't work in IE7 though.
I think floats may work best for you here, if you dont want the element to occupy the whole line, float it left should work.
.feature_wrapper span {
float: left;
clear: left;
display:inline
}
EDIT: now browsers have better support you can make use of the do inline-block.
.feature_wrapper span {
display:inline-block;
*display:inline; *zoom:1;
}
Depending on the text-align this will appear as through its inline while also acting like a block element.
For the block element not occupy the whole line, set it's width to something small and the white-space:nowrap
label
{
width:10px;
display:block;
white-space:nowrap;
}
Using a flex parent works too.
Setting flex-direction to column will put each child on a new line and setting align-items will make them not take up the whole width.
Here is a small example:
<div class="parent">
<a>some links</a>
<a>that should be on their own lines</a>
<a>but not take up the whole parent width</a>
</div>
.parent {
display: flex;
flex-direction: column;
align-items: flex-start;
}
span::before { content: "\A"; white-space: pre; }
I was running into a similar situation on our WooCommerce site. The "Add to cart" button was right next to a custom product field, and I needed to drop the product field below the button. This is the CSS that ended up doing the trick for me
#product-57310 label[for="wcj_product_input_fields_local_1"] { display: -webkit-box!important; margin-top: 80px; }
where "#product-57310" is the ID of the product in woocommerce, so that it only applies to the specific product page and not every product page, and where "label[for="wcj_product_input_fields_local_1"]" is targeting the first label specifically to get under the "Add to cart" button.
I had a similar issue where I had something like this:
<span>
<input>
<label>
<input>
<label>
...
</span>
I didn't wanna mess with the source html generator (even tho this html is pretty bad). So the way I fixed it is use a display: grid on the top span. Then grid-template-columns: auto auto;
Anyone looking to do something similar, grid is a good solution now (in 2021).
For example, for this particular problem, applying
display: grid; grid-template-columns: auto auto; to li and grid-column: 1 / 3; to last span will do it.
Use two CSS rules
word-break: break-all;
display: list-item;
inside of a CSS selector and body
Note:
If only dealing with text that needs to be put on separate lines.
Try using word-break like so (note stack overflow code automatically does this but I included it to help clarify usage in other environments:
word-break: break-all;
If only dealing with in-line HTML elements like a <span>
Then see this answer as to how to convert non text elements (like an anchor tag) to line separated elements using a display: list-item also on the html tag
Link
How to make text in <a> tag wordwrap
Example (For HTML inline elements like span)
span {
display: list-item;
word-break: break-word;
}
<span>Line 1</span>
<span>Line 2</span>
<span>Line 3</span>
<span>Line 4</span>
<span>Line 5</span>
Example (For Text Content)
function makePerson(name, age) {
// add code here
let person = Object.create({});
person.name = name;
person.age = age;
return person;
}
const person = makePerson('Vicky', 24);
const outputDiv = document.querySelectorAll("body .output");
const keys = Object.keys(person);
outputDiv.forEach((div,key) => {
div.innerHTML = person[keys[key]];
});
body #output{
word-break: break-all;
}
<div>
<div class="output"></div>
<div class="output"></div>
</div>