How to align rotated text and icons in CSS - html

I am trying to teach myself CSS and I am struggling with alignment. What I want to achieve is to have a fixed sidebar that has some icons and a rotated text, all of them should be in a column.
My code:
HTML:
<div class="Sidebar">
<div id="S1" class="SBlock">
<img src="Twitter_Logo.png" width=10px height=10px>
</div>
<div id="S2" class="SBlock">
<img src="Linkedin_Logo.png" width=10px height=10px>
</div>
<div id="Follow" class="SBlock">
Follow Us
</div>
</div>
CSS:
.Sidebar {
position: fixed;
top: 50%;
height: 300px;
}
#S1 {
position: absolute;
left: 20%;
top: 10%;
}
#S2 {
position: absolute;
left: 20%;
top: 20%;
}
#Follow {
transform: rotate(-90deg);
font-size: 12px;
position: absolute;
left: 20%;
top: 50%;
font-family: Montserrat;
text-transform: uppercase;
overflow: hidden;
white-space: nowrap;
}
Which produces this:
Result:
It works fine for the icons, I assume that is because they are the same size, but the text is way further to the right. Any ideas?

.Sidebar {
position: fixed;
top: 50%;
display: flex;
flex-direction: column;
align-items: center;
}
.SBlock {
margin: 10px 0;
}
#Follow {
transform: rotate(-90deg);
font-size: 12px;
font-family: Montserrat;
text-transform: uppercase;
white-space: nowrap;
writing-mode: vertical-rl;
text-orientation: mixed;
}
Try this...

Try to use writing-mode: sideways-lr instead of transform: rotate(-90deg) to avoid the extra space. And you don't need position: absolute to get all items align in the sidebar.
Read more about writing-mode.
.Sidebar {
position: fixed;
height: 300px;
display: flex;
flex-direction: column;
background: red;
align-items: center;
width: 50px;
}
#Follow {
font-size: 12px;
font-family: Montserrat;
color: blue;
writing-mode: sideways-lr;
}
<div class="Sidebar">
<div id="S1" class="SBlock">
<img src="Twitter_Logo.png" width=10px height=10px>
</div>
<div id="S2" class="SBlock">
<img src="Linkedin_Logo.png" width=10px height=10px>
</div>
<div id="Follow" class="SBlock">
Follow Us
</div>
</div>

I'd suggest you use Flexbox which is so nice for designing layouts also, alignment is so easy using it.
This article is a good point to start:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Related

trying to put two stacked images to align right to a lone image in css

i'm trying to two pictures that are stacked upon each other to lay beside a full picture like the image below - i'm trying to get those two images that are stacked on each other to align next to the other lone image.
can anyone help me with this. i don't know if its flexbox or i should use positioning to solve the problem because the image is stuck below and i'm trying to make the images go up and also make them align right next to the lone image (p.s i have tried positioning but does not work for some reason)
.lone-image {
display: flex;
}
.images {
background-size: cover;
background-image: url(xii.jpg);
width: 45%;
height: 520px;
position: relative;
left: 50px;
}
.Xiaomi h1 {
position: absolute;
color: white;
font-weight: normal;
font-size: 40px;
bottom: 70%;
right: 60%;
}
.xiaomi-text {
color: white;
position: absolute;
top: 25%;
left: 6%;
font-size: 12px;
}
.Buy-now button {
background-color: #706c6c;
color: white;
font-size: 16px;
padding: 6px 12px;
border: none;
position: absolute;
bottom: 60%;
right: 76%;
}
.images2 {
background-image: url(canon.jpg);
background-size: cover;
width: 37%;
height: 280px;
position: relative;
margin-bottom: 10px;
}
.Canon h1 {
font-weight: normal;
font-size: 40px;
position: absolute;
top: 40px;
left: 15px;
}
.button2 button {
color: white;
background-color: #706c6c;
padding: 6px 12px;
border: none;
position: absolute;
font-size: 16px;
top: 150px;
left: 15px;
}
.images3 {
background-image: url(dell.jpg);
background-size: cover;
width: 37%;
height: 280px;
flex-wrap: wrap;
}
.stacked-image {
display: flex;
flex-flow: column;
align-items: flex-end;
}
<div class="lone-image">
<div class="images">
<div class="Xiaomi">
<h1> Xiaomi X15</h1>
</div>
<div class="Buy-now">
<button> BUY NOW</button>
</div>
<div class="xiaomi-text">
<p> Discover your passion in the phone of dreams so order now</p>
</div>
</div>
</div>
<div class="stacked-image">
<div class="images2">
<div class="Canon">
<h1>CANON MP56 </h1>
</div>
<div class="button2">
<button> BUY NOW</button>
</div>
</div>
<div class="images3">
<div class="Dell">
<h1>Dell X5-MWS</h1>
</div>
<div class="button3">
<button> BUY NOW</button>
</div>
</div>
</div>
If I'm understanding you correctly, you are looking for flexbox. Here is a basic example:
JSFiddle
<div class="parent">
<img src="" alt="left"/>
<div class="child">
<img src="" alt="hi"/>
<img src="" alt="hi"/>
</div>
</div>
.parent {
display: flex;
}
.child {
display: flex;
flex-direction: column;
}
If you want the change how they vertically align, you can just play around with the align-items CSS property on the parent class.

Duplicating Youtube's navigation bar, but, I have a habit of using position: absolute; I need a more effective way of doing this

This is the epitome of DRY code, I need to find an effective way of writing this code. I am currently using The Odin Project and the guidelines were to Duplicate Youtube's video section. I completed the navigation bar, but I am unhappy with it since I am just using position: absolute all the time. I was about using Grid or flexbox but I do not really know if it will help.
* {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
body {
background-color: #f8f8f8;
}
.navigation {
height: 70px;
width: 100%;
background-color: #fff;
box-shadow: 0px 1px 4px #ebebeb;
}
.menu {
position: absolute;
left: 30px;
top: 22px;
opacity: .4;
cursor: pointer;
}
.menu:hover {
opacity: 1;
}
.youtube-logo {
width: 90px;
position: absolute;
left: 70px;
top: 10px;
}
.search-bar {
position: absolute;
top: 21px;
left: 390px;
width: 600px;
height: 33px;
background: url(images/search.svg) no-repeat 95% 50%;
background-size: 16px;
border-radius: 2px;
border: 1px solid #b3b3b3;
padding-left: 20px;
box-sizing: border-box;
outline: none;
}
::placeholder {
font-family: Arial, Helvetica, sans-serif;
font-size: 1.2em;
padding-left: 3px;
}
.video {
position: absolute;
left: 1150px;
top: 25px;
cursor: pointer;
opacity: .4;
}
.stack {
position: absolute;
left: 1210px;
cursor: pointer;
width: 18px;
opacity: .4;
top: 27px;
}
.message {
position: absolute;
left: 1265px;
top: 24px;
;
opacity: .4;
cursor: pointer;
}
.bell {
position: absolute;
left: 1320px;
top: 23px;
opacity: .4;
cursor: pointer;
}
.icon {
position: absolute;
top: 16px;
left: 1374px;
cursor: pointer;
width: 36px;
opacity: .4;
}
<nav class="navigation">
<img src="images/menu.svg" alt="menu for the top left, shaped like a hamburger" class="menu">
<img src="images/youtube.logo.png" alt="youtube logo" class="youtube-logo">
<input type="text" name="searchbar" placeholder="Search" class="search-bar">
<img src="images/video.svg" alt="video icon" class="video">
<img src="images/google-app-button.png" alt="square stacks" class="stack">
<img src="images/message-square (1).svg" alt="message forr youtube" class="message">
<img src="images/bell.svg" alt="bell for top right bar" class="bell">
<img src="images/icons8-male-user-512.png" alt="profile picture for the bar" class="icon">
</nav>
Flexbox is pretty straight forward. You only need to set display: flex; on the parent element and the children elements will be affected.
.parent-flex {
display: flex;
}
<h2>Without Flexbox</h2>
<div>
<div>Child 1</div>
<div>Child 2</div>
<div>Child 3</div>
</div>
<h2>With Flexbox</h2>
<div class="parent-flex">
<div class="child-1">Child 1</div>
<div class="child-2">Child 2</div>
<div class="child-3">Child 3</div>
</div>
Since you are trying to replicate the youtube navbar, I'd recommend using flexbox to setup the "regions" of the navbar and then applying justify-content: space-between; to space out the regions equally.
.flex {
display: flex;
}
.parent {
justify-content: space-between;
}
.child-1 {}
.child-2 {}
.child-3 {
justify-content: flex-end;
}
<div class="flex parent">
<div class="flex child-1">
<div class="menu">[Menu Icon]</div>
<div class="logo">[Logo]</div>
</div>
<div class="flex child-2">
<div class="search-box">[search box]</div>
<div class="search-button">[search button]</div>
</div>
<div class="flex child-3">
<div class="user-photo">[the user's photo]</div>
<div class="etc">[whatever other icons...]</div>
</div>
</div>
You can check out this great article on css-tricks to learn more about the ins and outs of flexbox.
https://css-tricks.com/snippets/css/a-guide-to-flexbox/

CSS arrange two divs next to each other

I have following HTML:
<div className={`page-header-profile-photo-container`}>
<div className="user-picture">
</div>
<div className="user-name">
<p>Sample GmbhH</p>
</div>
</div>
And my css:
.page-header-profile-photo-container{
position: absolute;
top: 10%;
right: 130px;
width: 200px;
}
.user-picture {
position: relative;
top: 10%;
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #787567;
}
.user-name{
position: absolute;
top: 5%;
}
This renders like following:
I want to have some space between circular div and text. page-header-profile-photo-container's position has to be absolute.
How can I fix this?
First of all correct your syntax like className to class and try the following code. No need to position:absolute in user-name class
.page-header-profile-photo-container{
width: 200px;
position: absolute;
top: 10%;
right: 130px;
}
.user-picture {
position: relative;
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #787567;
display: inline-block;
vertical-align: middle;
}
.user-name{
display: inline-block;
vertical-align: middle;
}
<div class=page-header-profile-photo-container>
<div class="user-picture">
</div>
<div class="user-name">
<p>Sample GmbhH</p>
</div>
</div>
Don't use absolute positioning in user name. Absolute positioning puts an item in a particular position no matter what (doesn't care if it gets overlapped)
Using flex-box it will work good for me. Hope this help.
.page-header-profile-photo-container{
background-color: #f5f5f5;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
position: absolute;
height: 50px;
top: 10%;
right: 130px;
padding: 5px 10px;
width: 200px;
}
.user-picture {
position: relative;
width: 40px;
height: 40px;
border-radius: 50%;
/*background-color: #787567;*/
}
.user-picture img{
border-radius: 50%;
display: block;
height: auto;
max-width: 100%;
}
.user-name{
font-size: 15px;
}
<div class=page-header-profile-photo-container>
<div class="user-picture">
<img src="http://placehold.it/40x40" alt="Profile Picture" />
</div>
<div class="user-name">
<p>Sample GmbhH</p>
</div>
</div>

How can my title be centered without "padding-cheat"?

How can I center my h1 tag into the middle of my banner without setting a padding?
HTML
<div class="banner">
<div class="bannerContainer">
<h1>Group Title</h1>
</div>
</div>
CSS
.banner {
height: 500px;
width: 100%;
background-color: #000;
}
.bannerContainer {
}
Can you do something with vertical-align: middle; and display: table-cell; etc?
There's several options, I recommend looking through this - https://css-tricks.com/centering-css-complete-guide/
One option would be: http://jsfiddle.net/dtq7fed3/ which uses a line-height on the container that is the same of the height of the banner.
.banner {
height: 500px;
width: 100%;
background-color: #000;
}
.bannerContainer {
text-align: center;
line-height: 500px;
color: #fff;
}
This only works if the banner height is going to remain stagnant
Using transform, you can position in centrally like so: http://jsfiddle.net/otghf6zo/1/
adding this code will position the title in the exact middle of the containing div regardless of size.
h1 {
color: #fff;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
You can use CSS table like this
.banner {
height: 500px;
width: 100%;
background-color: #000;
display: table;
text-align: center;
color: white;
}
.bannerContainer {
display: table-cell;
vertical-align: middle;
}
<div class="banner">
<div class="bannerContainer">
<h1>Group Title</h1>
</div>
</div>
Or Flexbox like this
.banner {
height: 500px;
width: 100%;
background-color: #000;
display: flex;
color: white;
align-items: center;
justify-content: center;
}
<div class="banner">
<div class="bannerContainer">
<h1>Group Title</h1>
</div>
</div>

How to center div vertically inside of absolutely positioned parent div

I am trying to get blue container in the middle of pink one, however seems vertical-align: middle; doesn't do the job in that case.
<div style="display: block; position: absolute; left: 50px; top: 50px;">
<div style="text-align: left; position: absolute;height: 56px;vertical-align: middle;background-color: pink;">
<div style="background-color: lightblue;">test</div>
</div>
</div>
Result:
Expectation:
Please suggest how can I achieve that.
Jsfiddle
First of all note that vertical-align is only applicable to table cells and inline-level elements.
There are couple of ways to achieve vertical alignments which may or may not meet your needs. However I'll show you two methods from my favorites:
1. Using transform and top
.valign {
position: relative;
top: 50%;
transform: translateY(-50%);
/* vendor prefixes omitted due to brevity */
}
<div style="position: absolute; left: 50px; top: 50px;">
<div style="text-align: left; position: absolute;height: 56px;background-color: pink;">
<div class="valign" style="background-color: lightblue;">test</div>
</div>
</div>
The key point is that a percentage value on top is relative to the height of the containing block; While a percentage value on transforms is relative to the size of the box itself (the bounding box).
If you experience font rendering issues (blurry font), the fix is to add perspective(1px) to the transform declaration so it becomes:
transform: perspective(1px) translateY(-50%);
It's worth noting that CSS transform is supported in IE9+.
2. Using inline-block (pseudo-)elements
In this method, we have two sibling inline-block elements which are aligned vertically at the middle by vertical-align: middle declaration.
One of them has a height of 100% of its parent and the other is our desired element whose we wanted to align it at the middle.
.parent {
text-align: left;
position: absolute;
height: 56px;
background-color: pink;
white-space: nowrap;
font-size: 0; /* remove the gap between inline level elements */
}
.dummy-child { height: 100%; }
.valign {
font-size: 16px; /* re-set the font-size */
}
.dummy-child, .valign {
display: inline-block;
vertical-align: middle;
}
<div style="position: absolute; left: 50px; top: 50px;">
<div class="parent">
<div class="dummy-child"></div>
<div class="valign" style="background-color: lightblue;">test</div>
</div>
</div>
Finally, we should use one of the available methods to remove the gap between inline-level elements.
use this :
.Absolute-Center {
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}
refer this link: https://www.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/
Use flex blox in your absoutely positioned div to center its content.
See example https://plnkr.co/edit/wJIX2NpbNhO34X68ZyoY?p=preview
.some-absolute-div {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -moz-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
-moz-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
-moz-align-items: center;
align-items: center;
}
Center vertically and horizontally:
.parent{
height: 100%;
position: absolute;
width: 100%;
top: 0;
left: 0;
}
.c{
position: absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
}
For only vertical center
<div style="text-align: left; position: relative;height: 56px;background-color: pink;">
<div style="background-color: lightblue;position:absolute;top:50%; transform: translateY(-50%);">test</div>
</div>
I always do like this, it's a very short and easy code to center both horizontally and vertically
.center{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="center">Hello Centered World!</div>
EDIT: 10/22 as nowdays, display flex or grid is widely implemented i would suggest to use one or the other (display:table/table-cell will still work if you need compatibility with old or exotic browsers , like my TV...)
flex
.a{
position: absolute;
left: 50px;
top: 50px;
}
.b{
display:flex;
align-items:center;
background-color: pink;
height: 56px;
}
.c {
background-color: lightblue;
}
/* move the flex demo aside */
.a.b{left:100px}
You even need less markup
<div class="a">
<div class="b">
<div class="c">test</div>
</div>
</div>
<div class="a b">
<div class="c">test</div>
</div>
grid (similar at that point)
.a{
position: absolute;
left: 50px;
top: 50px;
}
.b{
display:grid;
align-items:center;
background-color: pink;
height: 56px;
}
.c {
background-color: lightblue;
}
/* move the grid demo aside */
.a.b{left:100px}
You even need less markup
<div class="a">
<div class="b">
<div class="c">test</div>
</div>
</div>
<div class="a b">
<div class="c">test</div>
</div>
Original answer 02/2015 (still efficient everywhere) use with very old or exotic browsers not implementing yet flex or grid
You may use display:table/table-cell;
.a{
position: absolute;
left: 50px;
top: 50px;
display:table;
}
.b{
text-align: left;
display:table-cell;
height: 56px;
vertical-align: middle;
background-color: pink;
}
.c {
background-color: lightblue;
}
<div class="a">
<div class="b">
<div class="c" >test</div>
</div>
</div>
Here is simple way using Top object.
eg: If absolute element size is 60px.
.absolute-element {
position:absolute;
height:60px;
top: calc(50% - 60px);
}
An additional simple solution
HTML:
<div id="d1">
<div id="d2">
Text
</div>
</div>
CSS:
#d1{
position:absolute;
top:100px;left:100px;
}
#d2{
border:1px solid black;
height:50px; width:50px;
display:table-cell;
vertical-align:middle;
text-align:center;
}
You can do it by using display:table; in parent div and display: table-cell; vertical-align: middle; in child div
<div style="display:table;">
<div style="text-align: left; height: 56px; background-color: pink; display: table-cell; vertical-align: middle;">
<div style="background-color: lightblue; ">test</div>
</div>
</div>