Center a vertical span within an a element - html

I have a layout that looks sort of like a bookshelf, see my jsfiddle example. The bookshelf is responsive so no fixed widths. The issue I'm faced with is that I cannot center the text within the panels, "horizontally" within the books sides. It's extra tricky since the text is transformed to be displayed vertically. Does anyone have any ideas of how to make this work?
HTML
<div class="panel">
<a href="#first">
<span>first</span>
</a>
</div>
CSS
.panel {
float: left;
height: 100%;
width: 15%;
margin-right: 5%;
}
.panel a {
text-align: right;
background: green;
padding: 20px 10px;
height: 100%;
display: block;
white-space: nowrap;
color: white;
float: left;
width: 100%;
text-decoration:none;
}
.panel a span {
white-space: nowrap;
color: white;
text-transform: lowercase;
-ms-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
transform-origin: top right;
display: block;
width: 300px;
margin-left: -300px;
letter-spacing: 1px;
font-size: 20px;
}

you have 2 easy options, with either display:flex or table :
display:table example:
body,
html,
.panel-wrapper {
height: 100%;
width: 100%;
}
.panel-wrapper {
display: table;
border-collape: collapse;
table-layout: fixed;
background: white;
}
.panel {
display: table-cell;
height: 100%;
width: 20%;/* you have five here*/
}
.panel a {
display: block;
text-align: center;
background: green;
padding: 20px 10px;
box-sizing:border-box;/*includes padding and borders */
height: 100%;
width: 75%;/* each is 15% width */
text-decoration: none;
white-space: nowrap;
}
.panel a:before {
content: '';
height: 100%;
display: inline-block;
vertical-align: middle;/*inline content will vertical-align middle aside it */
}
.panel a span {
display: inline-block;/* triggers transform*/
color: white;
text-transform: lowercase;
transform: rotate(-90deg);
letter-spacing: 1px;
font-size: 20px;
vertical-align: middle;
}
<div class="panel-wrapper">
<div class="panel"><span>first</span>
</div>
<div class="panel"><span>second</span>
</div>
<div class="panel"><span>third</span>
</div>
<div class="panel"><span>fourth</span>
</div>
<div class="panel"><span>fifth</span>
</div>
</div>
http://codepen.io/gc-nomade/pen/JGEbLX
or flex:
body,
html,
.panel-wrapper {
height: 100%;
width: 100%;
margin: 0;
}
.panel {
float: left;
height: 100%;
width: 15%;
margin-right: 5%;
}
.panel a {
text-align: right;
background: green;
padding: 20px 10px;
height: 100%;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
;
white-space: nowrap;
color: white;
text-decoration: none;
}
.panel a span {
white-space: nowrap;
color: white;
transform: rotate(-90deg);
letter-spacing: 1px;
font-size: 20px;
}
<div class="panel-wrapper">
<div class="panel"><span>first</span>
</div>
<div class="panel"><span>second</span>
</div>
<div class="panel"><span>third</span>
</div>
<div class="panel"><span>fourth</span>
</div>
<div class="panel"><span>fifth</span>
</div>
</div>
http://codepen.io/gc-nomade/pen/obBYyY

Do the following:
.panel a span {
white-space: nowrap;
color: white;
text-transform: lowercase;
-ms-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
transform-origin: top right;
display: block;
width: 300px;
margin-left: -300px;
letter-spacing: 1px;
font-size: 20px;
position:relative;
left: 45%;
}
See my demo here or your jfiddle
You may need a small adjustment at tiny smartphones with a media query, but other than that it works
Add this to the responsive css:
#media (max-width: 560px){
.panel a span {
left: 25%;
}
}

Add these lines to your code :
.panel a{
position:relative;
}
.panel a span {
position:absolute;
left:40%;
/* top:50%; */
}
Here is the fiddle

I f you want center the text vertically use the below property below the text-align: center in .panel a span make the text in corner center of a panel
.panel a span {
text-align: center;
}
and if you want center text in the middle of the panel not in corner
.panel a span {
text-align: center;
margin-left: -260px;
}

Related

Float left, right with flexbox while vertical aligned width 100%

I'm trying to vertically align my 3 items, that the reason why I use
display: flex;
align-items: center; /* center items vertically, in this case */
Not sure If it is good to practise, but now that my items are aligned correctly I cant spread the items to the left corner (menu), right corner (about), and the middle (logo). How can I do this?
Are there other alternatives to align items without flex, I have tried a lot and none of them worked so far.
canvas {
position: absolute;
background: black;
width: 100%;
height: 100%;
}
#moveItem {
z-index: 1;
opacity: 0.85;
filter: alpha(opacity=85); /* For IE8 and earlier */
}
body, html{
font-family: Arial;
margin: 0px;
height: 100%;
width: 100%;
overflow-y: hidden;
background: black;
}
#navigator {
z-index: 2;
position: relative;
padding: 0.5rem;
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
display: flex;
align-items: center; /* center items vertically, in this case */
}
#navIcon{
float: left;
color: white;
font-size: 30px;
cursor:pointer;
}
.about {
float: right;
color: white;
font-size: 30px;
cursor: pointer;
}
#navigator a {
text-decoration: none;
color: white;
}
.logo {
display: inline;
}
.logo img {
vertical-align: middle;
height: 50px;
width: auto;
}
.logoheader{
background: rgba(0, 0, 0, 0.5);
display: inline-block;
border-radius: 20px;
}
.logoText {
letter-spacing: 2px;
text-transform: uppercase;
vertical-align: middle;
display: inline;
font-size: 1.3rem;
margin-left: -12px;
}
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div id="navigator">
<div id="navIcon" onclick="openNav()"> ☰</div>
<div class="logoheader">
<a href="/price/">
<div class="logo"><img src="/images/logo.png"></div>
<div class="logoText">Title</div>
</a>
</div>
<div class="about">
About
</div>
</div>
</body>
Don't use float with flexbox, use justify-content and align-items instead. float should only be used for images in a text paragraph, nothing else.
Also, there are many options to align your content like that, but most of them only exist because flex wasn't always a thing, and the old ways are usually extremely hacky. grid and flex are the modern ways for CSS layouting.
Example: (you can use justify-content: space-between; on the container to achieve the desired alignment, or experiment with margin-right: auto and margin-left: auto)
canvas {
position: absolute;
background: black;
width: 100%;
height: 100%;
}
#moveItem {
z-index: 1;
opacity: 0.85;
filter: alpha(opacity=85); /* For IE8 and earlier */
}
body, html{
font-family: Arial;
margin: 0px;
height: 100%;
width: 100%;
overflow-y: hidden;
background: black;
}
#navigator {
z-index: 2;
position: relative;
padding: 0.5rem;
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
display: flex;
align-items: center; /* center items vertically, in this case */
justify-content: space-between;
}
#navIcon{
color: white;
font-size: 30px;
cursor:pointer;
}
.about {
color: white;
font-size: 30px;
cursor: pointer;
}
#navigator a {
text-decoration: none;
color: white;
}
.logo {
display: inline;
}
.logo img {
vertical-align: middle;
height: 50px;
width: auto;
}
.logoheader{
background: rgba(0, 0, 0, 0.5);
display: inline-block;
border-radius: 20px;
}
.logoText {
letter-spacing: 2px;
text-transform: uppercase;
vertical-align: middle;
display: inline;
font-size: 1.3rem;
margin-left: -12px;
}
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div id="navigator">
<div id="navIcon" onclick="openNav()"> ☰</div>
<div class="logoheader">
<a href="/price/">
<div class="logo"><img src="/images/logo.png"></div>
<div class="logoText">Title</div>
</a>
</div>
<div class="about">
About
</div>
</div>
</body>

padding-top "bigger" than padding-bottom

I don't understand why in this setup the padding-top is various times bigger than the padding-bottom. Tried tweaking stuff around to find the culprit property but so far nothing. I did notice, that I accidentally left a " after the spans, the issue was gone, but not sure how that relates.
https://jsfiddle.net/3n0yuzs3/1/
body
{
font-family: sans-serif;
}
#window
{
background-color: black;
color: white;
display: flex;
flex-direction: column;
opacity: 1;
left: 50%;
bottom: 0px;
position: fixed;
width: auto;
height: auto;
min-width: 600px;
min-height: auto;
max-width: 80vw;
max-height: 80vh;
transform: translateX(-50%);
outline: 0px;
cursor: default;
z-index: 5000002;
zoom: 1;
}
#container
{
overflow-y: auto;
overflow-x: hidden;
border: none;
outline: 0;
margin: 0;
flex-grow: 1;
}
#content
{
font-size: 22px;
text-align: center;
overflow-wrap: break-word;
padding-top: 1.6em;
padding-bottom: 1.6em;
padding-left: 1.6em;
padding-right: 1.6em;
}
.snack_msg
{
padding-right: 200px;
float:left;
}
.snack_btn
{
color:#5fce49;
text-transform: uppercase;
letter-spacing:3px;
cursor:pointer;
float:right;
}
<div id='window'>
<div id='container'>
<div id='content'>
<span class='snack_msg'>New message arrived</span>
<span class='snack_btn' onclick='open_snack_message()'>open</span>
</div>
</div>
</div>
The issue is with floating elements and not padding. As you can see below, you have equal padding in all the sizes :
And if you check well you will see also that you have a height equal to 0 because you have floating element and since the parent is not floating it will collapse (which means no height). To fix this you need to add oveflow:auto to #content.
body {
font-family: sans-serif;
}
#window {
background-color: black;
color: white;
display: flex;
flex-direction: column;
opacity: 1;
left: 50%;
bottom: 0px;
position: fixed;
width: auto;
height: auto;
min-width: 600px;
min-height: auto;
max-width: 80vw;
max-height: 80vh;
transform: translateX(-50%);
outline: 0px;
cursor: default;
z-index: 5000002;
zoom: 1;
}
#container {
overflow-y: auto;
overflow-x: hidden;
border: none;
outline: 0;
margin: 0;
flex-grow: 1;
}
#content {
font-size: 22px;
text-align: center;
overflow-wrap: break-word;
padding-top: 1.6em;
padding-bottom: 1.6em;
padding-left: 1.6em;
padding-right: 1.6em;
overflow: auto;
}
.snack_msg {
padding-right: 200px;
float: left;
}
.snack_btn {
color: #5fce49;
text-transform: uppercase;
letter-spacing: 3px;
cursor: pointer;
float: right;
}
<div id='window'>
<div id='container'>
<div id='content'>
<span class='snack_msg'>New message arrived</span>
<span class='snack_btn' onclick='open_snack_message()'>open</span>
</div>
</div>
</div>
Here is some usefull questions where you can gather more information and more ways to prevent this behavior:
How do you keep parents of floated elements from collapsing?
Why does 'overflow: auto' clear floats? And why are clear floats needed?

Using two divs with overlfow: hidden then overflow-y: scroll not working as expected

I am trying to use the trick of two nested elements to make content scroll without the scrollbar being visible.
To illustrate what I mean:
<div class="outer">
<div class="inner">
//content here
</div>
</div>
The content is higher than the outer div, so I want it to scroll. However I don't want a visible scrollbar. So I set the following CSS:
.outer {
overflow: hidden;
}
.inner {
overflow-y: scroll;
width: 110%;
}
However this is behaving quite oddly. It works to an extent - the content scrolls slightly. However it doesn't scroll as far as it needs to to be visible, and the inner div seems to ignore the padding on the outer div.
This is my full CSS. The relevant bits are .section and .innerSection
/* Eric Meyer's Reset CSS v2.0 - http://cssreset.com */
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0}
html, body {
background-color: #330033;
height: 100%;
width: 100%;
color: #FFFFCC;
font-family: 'Andika', sans-serif;
font-size: 20px;
font-weight: 400;
text-align: center;
}
a:link{text-decoration: none; color: #FFFFCC;}
a:visited{text-decoration: none; color: #FFFFCC;}
a:hover{text-decoration: none; color: white; font-weight: bold;}
form {
margin: 0 auto;
max-width: 500px;
padding-bottom: 1em;
text-align: left;
}
h1 {
font-size: 72px;
}
h2 {
font-weight: 600;
}
h3 {
font-size: 64px;
}
.imgLink {
border-radius: 5px;
margin: 1%;
max-width: 50%;
}
.innerSection {
height: 100%;
overflow-y: scroll;
width: 110%;
}
.section {
background-color: rgba(51,51,51,0.5);
border-radius: 5px;
display: inline-block;
margin: 1%;
max-height: 42%; /*simplifies responsive height lower down*/
min-height: 42%;
overflow: hidden;
padding: 1%;
vertical-align: top; /*otherwise sections move down when content added*/
width: 28%;
}
#desktopTitle {
background-color: #330033;
}
#tabletTitle {
display: none;
}
#media screen and (max-width: 1020px), screen and (max-height: 925px) {
.section {
display: block;
max-height: fit-content;
min-height: 25%;
width: 94%;
}
#contact {
margin-top: 5%;
}
#desktopTitle {
display: none;
}
#resources {
display: none;
}
#tabletTitle {
display: block;
}
#twitter {
display: none;
}
}
#media screen and (max-width: 600px) {
#tabletTitle {
font-size: 48px;
}
}
Try this (modifications are commented):
.innerSection {
height: 100%;
overflow-y: auto; /*instead of scroll*/
width: 110%;
padding: 20px; /*add padding here*/
}
.section {
background-color: rgba(51,51,51,0.5);
border-radius: 5px;
display: inline-block;
margin: 1%;
height: 100%; /*It does not seem to work without specifying a height.*/
max-height: 42%;
min-height: 42%;
overflow: hidden;
padding: 1%;
vertical-align: top;
width: 28%;
}

Why isn't this absolute positioned div vertically centering?

I need multi-line text to be centered vertically within a parent. I need the child to be position: absolute; because it will have other items in there behind it. I cannot figure out how to make the child (a div containing text) vertically centered. (I also tried doing it with display: table-cell but couldn't get that working either)
https://jsfiddle.net/t7q1ffm2/
HTML:
<div class="box">
<div class="text">This has some text in it that's long</div>
</div>
<div class="box">
<div class="text">Short text</div>
</div>
CSS:
.box
{
position: relative;
top: 0em;
left: 0em;
width: 125px;
height: 125px;
-webkit-flex-grow: 1;
-moz-flex-grow: 1;
-ms-flex-grow: 1;
flex-grow: 1;
margin-right: .625em;
margin-bottom: .5em;
text-decoration: none;
overflow: hidden;
display: table;
background-color: red;
}
.box .text
{
position: absolute;
top: 0;
bottom: 0;
left:0;
right:0;
margin: auto;
width:100%;
height: 50%;
font-family: Arial, Helvetica;
font-size: 1em;
font-weight: normal;
line-height: 1.125em;
color: #ffffff;
text-align: center;
z-index: 2;
}
If you want to use position relative/absolute, you have to add transform: translate(-50%, -50%); on absolute element for center align.
.box{
position: relative;
top: 0em;
left: 0em;
width: 125px;
height: 125px;
margin-right: .625em;
margin-bottom: .5em;
text-decoration: none;
overflow: hidden;
background-color: red;
}
.box .text {
position: absolute;
top: 50%;
left:50%;
width: 100%;
font-family: Arial, Helvetica;
font-size: 1em;
font-weight: normal;
color: #ffffff;
text-align: center;
z-index: 2;
transform: translate(-50%, -50%);
}
<div class="box">
<div class="text">This has some text in it that's long</div>
</div>
<div class="box">
<div class="text">Short text</div>
</div>
Using flexbox is your best bet. Here is my fiddle, and here is the CSS I used (I cut out some unnecessary CSS):
.box {
position: relative;
top: 0em;
left: 0em;
width: 125px;
height: 125px;
display: flex;
align-items: center;
margin-right: .625em;
margin-bottom: .5em;
text-decoration: none;
overflow: hidden;
background-color: red;
}
.box .text {
margin: auto;
width:100%;
font-family: Arial, Helvetica;
font-size: 1em;
font-weight: normal;
line-height: 1.125em;
color: #ffffff;
text-align: center;
z-index: 2;
}
CSS attribute table-cell does work:
HTML:
<div class="box">
<div class="text">This has some text in it that's long</div>
</div>
<div class="box">
<div class="text">Short text</div>
</div>
CSS:
.box {
width: 130px;
height: 130px;
display: table;
}
.text {
display: table-cell;
vertical-align: middle;
text-align: center;
}
However, you need to wrap that inside another box.
This fiddle illustrates your exact use case: https://jsfiddle.net/stgermaniac/qdc84bxo/

Target element outside onclick event?

I'm doing a page for someone. I toggled the visibility of a div with a checkbox however, he wants to change the height of the header which comes before the content div which has the onclick event. Could anyone help me out? either css or js/jquery.
What I want:
checkbox off: div hidden & header height 412px.
checkbox checked: div showed & header height 212px.
header {
width:100%;
height:412px;
text-align:center;
background:#1f1f1f;
margin: 0;
padding: 0;
border: 0;
position:relative;
}
#wrapper td {
vertical-align: middle;
text-align: center;
}
#wrapper td img {
position: absolute;
top: 50%;
left: 50%;
width: 736px;
height: 105px;
margin-top: -52px; /* Half the height */
margin-left: -368px; /* Half the width */
}
div.content {
background:#ebebec;
position:relative;
top:100px;
color: white;
width: 100%;
text-align: center;
font-family: BlueHighway, Arial Black, sans-serif;
top:0;
}
div.content label {
display: block;
width:80px;
height:88px;
background:url(http://i.imgur.com/Buvp49A.png) no-repeat;
background-position: center top;
margin:0 auto;
margin-bottom:30px;
}
div.content label:hover {
cursor: pointer; background-position: center bottom;
}
div.button {
display:block;
position:relative;
top:-67px;
padding-top:22px;
background:url(http://i.imgur.com/Gf3QAxt.png) no-repeat;
background-position: center top;
}
input.toggle ~ div.description {
height: 0px;
overflow: hidden;
transition: .6s all cubic-bezier(0.730, -0.485, 0.145, 1.620)
}
input.toggle:checked ~ div.description { height: 530px; }
input.toggle:checked + label { background-position: center bottom; }
input.toggle { display: none; }
<header>
<table id="wrapper">
<tr>
<td><img src="http://i.imgur.com/vE3KBOv.png" alt="Santos#imvu"/></td>
</tr>
</table>
</header>
<div class="content">
<div class="button">
<input type="checkbox" id="punch" class="toggle">
<label for="punch"></label>
<div class="description">
<img src="http://i.imgur.com/8sY0E5c.gif" style="max-width:100%;height:auto" alt="bla">
</div>
</div>
</div>
Demo
Something like this?
I've set the initial height to 212px and added a new class to CSS header.expand where you set the height to 412px. After that you trigger the click() event for the checkbox in jQuery and toggle the expand class with toggleClass(...)
SNIPPET
$('#punch').click(function() {
$('header').toggleClass('expand');
});
html {
background: grey;
font-family: Arial, Helvetica, sans-serif;
font-size: 100%;
}
body {
background: #ebebec;
width: 926px;
margin: 0 auto;
padding: 0;
color: grey;
}
header {
width: 100%;
height: 212px;
text-align: center;
background: #1f1f1f;
margin: 0;
padding: 0;
border: 0;
position: relative;
transition: height .8s ease-out;
}
header.expand {
height: 412px;
}
#wrapper td {
vertical-align: middle;
text-align: center;
}
#wrapper td img {
position: absolute;
top: 50%;
left: 50%;
width: 736px;
height: 105px;
margin-top: -52px;
/* Half the height */
margin-left: -368px;
/* Half the width */
}
.image {
width: 500px;
height: 500px;
margin: 0 auto;
position: relative;
margin-bottom: 94px;
}
footer {
width: 100%;
text-align: center;
padding: 20px 0;
font-size: 12px;
background: #1f1f1f;
margin-top: 28px;
color: #fff;
clear: both;
}
a {
color: #0082ff;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
p {
width: 870px;
margin: 0 auto;
}
div.content {
background: #ebebec;
position: relative;
top: 100px;
color: white;
width: 100%;
text-align: center;
font-family: BlueHighway, Arial Black, sans-serif;
top: 0;
}
div.content label {
display: block;
width: 80px;
height: 88px;
background: url(http://i.imgur.com/Buvp49A.png) no-repeat;
background-position: center top;
margin: 0 auto;
margin-bottom: 30px;
}
div.content label:hover {
cursor: pointer;
background-position: center bottom;
}
div.button {
display: block;
position: relative;
top: -67px;
padding-top: 22px;
background: url(http://i.imgur.com/Gf3QAxt.png) no-repeat;
background-position: center top;
}
input.toggle ~ div.description {
height: 0px;
overflow: hidden;
transition: .6s all cubic-bezier(0.730, -0.485, 0.145, 1.620)
}
input.toggle:checked ~ div.description {
height: 530px;
}
input.toggle:checked + label {
background-position: center bottom;
}
input.toggle {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<header>
<table id="wrapper">
<tr>
<td>
<img src="http://i.imgur.com/vE3KBOv.png" alt="Santos#imvu" />
</td>
</tr>
</table>
</header>
<div class="content">
<div class="button">
<input type="checkbox" id="punch" class="toggle">
<label for="punch"></label>
<div class="description">
<img src="http://i.imgur.com/8sY0E5c.gif" style="max-width:100%;height:auto" alt="bla">
</div>
</div>
</div>