2014-09-14 17 views
8

Il mio problema è molto specifico e perseguiterò qualsiasi sviluppatore web dal momento in cui lo leggerà. Quindi stai attento!Elementi flottanti sul fondo

Ho pianificato un layout per un sito Web che sto costruendo. L'idea è che non c'è sono inclinate <hr/> elementi della pagina, che il testo scorrerà intorno al (vedi immagine qui sotto. La linea nera rappresenta la <hr/>)

the way it should be

Quello che vedete sono alcune strisce arancioni. Ognuno di questi è un elemento flottante con larghezze di 10px, quindi 20px, quindi 30px ecc. La linea nera rappresenta il punto in cui si fermano, e quindi dove hanno interrotto il testo.

La grande zona arancione è, come potete immaginare, un elemento galleggiante con una larghezza pari a 0 e un'altezza di 100% del suo genitore meno l'altezza degli altri 70 elementi galleggianti (le strisce), che è 70px.

Il problema: questo non sembra possibile. Quello che ottengo è questo:

what actually happens

Da queste piccole strisce sono ogni 1px alta, riveleranno, non importa quale. Ma il grande dipende dall'altezza dei suoi genitori. Se dovessi correggere l'altezza del genitore, funzionerebbe. Ma voglio che la scatola sia dinamica. Questo significa che dovrei essere in grado di cambiare il testo all'interno. Inoltre, se dovessi aggiustare la sua altezza, scalare la pagina su e giù sembra disastrosa.

Quello che devo succedere è questo: il primo, grande elemento fluttuante dovrebbe occupare lo spazio di cui ha bisogno (100% - 70px), senza dare al genitore un'altezza fissa, pur mantenendo il float.

Ho intenzione di premiare la persona che risolve questo con tutta la reputazione che posso mettere, dal momento che questo mi ha tormentato per mesi.

Per le persone che cercano di risolvere il problema. Ci sono alcuni pensieri che possono aiutare:

  1. Le celle di tabella possono allineare gli elementi ad esso è inferiore
  2. Ho provato a rotazione in un sacco di modi. Peccato che non ci sia testo capovolto.
  3. Ho provato ad aggiungere margini, paddings e bordi al primo div floating. Nessuna combinazione ha funzionato finora.
  4. In realtà non voglio che gli elementi galleggiano. Questo è il modo in cui ho scelto di provare, perché non conosco un altro modo per avvolgere il testo attorno a un elemento. Sei libero di provare QUALSIASI cosa tu voglia, purché il testo all'interno possa essere cambiato, e sembra buono se ingrandito o abbassato, come fa normalmente.
  5. Penso che l'unica soluzione sia usare Javascript per calcolare quale altezza sarebbe necessaria al div.

Qui è tutto il codice imballato in un Fiddle

EDIT: Penso che so la soluzione. Non so come programmarlo.

Con Javascript, il browser deve calcolare l'altezza del contenuto (testo, immagini, margini, ecc.) All'interno del contenitore. Quindi, #lw dovrebbe passare a quell'altezza. Dopo che è successo, #lw dovrebbe essere ridotto di 1px. Dopo che è successo, dovrebbe essere fatto un controllo per vedere se il contenuto è cambiato in altezza. Se ciò è accaduto, il browser dovrebbe verificare se l'altezza dell'altezza del contenuto è maggiore dell'altezza di #lw + 70px. Se non dovesse essere più alto, il processo dovrebbe ripetersi. Se così fosse, #lw dovrebbe ridursi di 1px e il processo dovrebbe fermarsi. Durante il ridimensionamento della finestra, il processo dovrebbe iniziare dall'inizio.

Questo sembra un inferno di lavoro, e sarei grato di accettare la sfida se dovessi conoscere JS. Immagino di essere in Codecadamy.

EDIT:

Nel frattempo, sono venuto su con una versione meno complessa di questo problema. Ho esaminato le forme di css e ho scoperto che queste mi consentiranno di fare ciò che hanno fatto gli 70 elementi mobili, con un elemento. Ho creato un altro set di file, MA È necessario un file js per farlo funzionare. Quello che farò qui è incollare l'HTML e il CSS come codice e collegarlo al codice js.

Proprio come nella versione precedente, il codice dovrebbe misurare l'altezza ottimale. Nel mio codice, ho aggiunto un tag <script> con una descrizione esatta di cosa dovrebbe accadere.

Penso di iniziare a sembrare pigro, dal momento che non posso dare alcun input riguardante il codice Javascript reale.

HTML

<!doctype html> 
    <html> 
     <head> 
      <meta charset="utf-8"> 
      <link rel="stylesheet" type="text/css" href="css/stylesheet.css"> 
      <script src='js/shapes.polyfill.min.js'></script> 
     </head> 
     <body> 
      <div id="container"> 
       <div id="polybreak"></div> 
       <p> 
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus enim arcu, porttitor vitae hendrerit euismod, efficitur pretium nulla. Sed a justo nulla. Aenean vel erat purus. In velit arcu, lacinia in justo in, vestibulum pellentesque mauris. Phasellus quis eros nunc. Vivamus fringilla euismod est, eget consectetur lacus cursus et. Fusce at arcu ac turpis laoreet feugiat nec a nulla. 
       </p> 
       <p> 
        Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Quisque vehicula mollis leo non tempus. Praesent scelerisque dui felis. Suspendisse tristique, sapien egestas semper cursus, elit quam facilisis sapien, sit amet ornare odio nibh sed nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum libero nisi, efficitur id felis non, maximus ultricies sapien. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce rhoncus nibh enim, eget dignissim neque placerat et. Nam sit amet placerat sapien. Quisque vitae risus ac dolor porttitor tincidunt. 
       </p> 
       <p> 
        Nullam volutpat, lorem vitae ultricies lobortis, ligula ligula posuere erat, sed gravida sapien nisi non ante. Aliquam tellus sapien, placerat mollis tempor quis, consequat imperdiet magna. Etiam cursus ornare mauris sit amet varius. Sed dignissim euismod felis, at aliquet est fringilla at. Duis lorem nunc, imperdiet nec rhoncus et, egestas quis nunc. Nulla imperdiet elementum libero consequat tempor. Donec ante nunc, pellentesque nec ex dapibus, auctor sagittis ipsum. Phasellus ut est ex. 
       </p> 
      </div> 
      <script src='js/shapes.polyfill.min.js'></script> 
      <script type="text/javascript"> 
       On load and on resize: 
       Make #polybreak the same height as #container + 60px. 

       Subtract 1px off #polybreak''s height and check: is #container higher than #polybreak? If so, add 1px and stop. If not, repeat. 
      </script> 
     </body> 
    </html> 

CSS

html, body{ 
    margin: 0; 
    padding: 0; 
    height: 100%; 
} 

p{ 
    text-align: justify; 
} 

#container{ 
    width: 700px; 
    margin: 0 auto; 
} 

#polybreak{ 
    width: 100%; 
    float: left; 
    shape-outside: polygon(0 calc(100% - 100px), 700px calc(100% - 1px), 700px 100%, 0 calc(100% - 99px)); 
} 

link al codice js grezzo https://raw.githubusercontent.com/adobe-webplatform/css-shapes-polyfill/master/shapes-polyfill.min.js

+1

'Calc (100% - 70px)' non può funzionare, perché l'elemento genitore non ha un 'height' set di basare il 100% su per cominciare. Usare JS è la tua unica opzione in questo momento, credo - fino a quando [CSS Shapes] (http://dev.w3.org/csswg/css-shapes/) non viene implementato. – CBroe

+0

@CBroe: Esattamente i miei pensieri, solo l'opzione potrebbe usare SVG in qualche modo, ma io sono meno esperto in questi, quindi sto esaminando alcune specifiche ora ~ Modifica: Sembra che richiederebbe anche javascript anche se ovviamente a causa dell'altezza dinamica Requisiti. –

+0

Grazie a @CBroe per il collegamento alle forme CSS. Queste cose sono ESATTAMENTE quello che mi serve –

risposta

0

Dare il div superiore altezza fissa (temporaneo), che è l'altezza si desidera che il testo non angolato per apparire. Sembra che tu abbia già un'altezza fissa per il fondo a 70 px.

<style type="text/css"> 
    #topPart { height: 600px } 
</style> 

Al fine di accogliere diverse altezze dello schermo avremo per calcolare la dimensione giusta per la parte superiore div e sottrarre tutto ciò che serve sul fondo.

Eseguiremo il ridimensionamento ogni volta che cambia la finestra del browser. In questo modo il div principale e il basso saranno sincronizzati.

Nella add pagina html (di base)

<div id="topPart"> 
<p>Some text or other divs whatever you like in here</p> 
</div> 
<div> 
The bottom part - add your staggered divs here 
</div> 

Non è possibile utilizzare al 100% e si aspettano di lavorare, basta tenere a mente che è necessario sottrarre la parte inferiore. Vorrei iniziare sottraendo circa 150 - 200 px per iniziare in modo da non incappare nella parte inferiore dello schermo e incasinare. La pagina agirà dinamicamente e potrai ridimensionare la pagina in su e in giù.

E' il mio pugnalata a cercare di capire questo ...

+0

Anche se questo si aggiornerebbe perfettamente, c'è un problema con questo. Non voglio dividere il testo manualmente. Ciò comporterebbe anche un layout interrotto durante il ridimensionamento della pagina, poiché la parte con le scostanti div non ha ancora nulla di dinamico. Penso davvero che la topPart, come hai chiamato tu, debba ridimensionarsi. Ho un'idea, comunque, su come risolverlo. Ho intenzione di aggiornare la mia domanda –

1

moderna CSS dispone di un modulo speciale per tali compiti: CSS Shapes. C'è uno polyfill creato da Adobe. Forse aiuta?

+0

Non ho intenzione di utilizzare le forme CSS perché non è supportato nella maggior parte dei browser. Guarderò in questo polyfill (non ho idea di cosa sia o mezzi, ancora) Grazie! –

2

Poiché tutti inviano risposte JavaScript in entrambi i casi, inseriamo una soluzione reale nel gruppo. Il problema anche nell'utilizzare Javascript è che non esiste un modo definito per "calcolare" l'altezza finale di #lw poiché è impossibile prevedere il comportamento del text wrapping.

//Get a nice starting point 
Zepto(".lW").hide(); 
var sh = document.getElementById("wrapper").scrollHeight; 
document.getElementById("lw").style["height"] = sh - 60 + "px"; 
Zepto(".lW").show(); 

//Start the search 
var height = parseInt(document.getElementById("lw").style["height"]); 
var difference = Infinity; 
var bestheight = 0; 
var i = 0; 
var checker = setInterval(function(){ 
    i++; 
    height += 1; 
    document.getElementById("lw").style["height"] = height + "px"; 
    var sh = document.getElementById("wrapper").scrollHeight; 

    //Now the interesting part, we don't want to get the first situation 
    // where the #lw is greater than the floats, what we want is the most 
    // optimal part, which we are going to search over a certain pixel range. 
    // In this case that pixel range is hardcoded as 30 pixels. 
    if(Math.abs(height + 70 - parseInt(sh)) < difference){ 
     difference = Math.abs(height + 70 - parseInt(sh)); 
     bestheight = height; 
    } 
    if(i>30){ 
     clearInterval(checker); 
     document.getElementById("lw").style["height"] = bestheight + "px"; 
    } 
},0); 

Ecco JSFiddle del solution.

enter image description here

+0

E per quanto riguarda l'ultima parola che viene spinto fuori dalla scatola a destra dal float ... dovrai fare una domanda diversa, temo perché non sta andando sotto i galleggianti come mi sarei aspettato. –

+0

Ehi, David. Grazie per l'aiuto. All'inizio sembrava funzionare. Sebbene, mentre stavo giocando con la quantità di testo all'interno, ho notato che non solo l'ultima parola salterebbe occasionalmente, ma a volte persino intere righe di testo! Quello che ho fatto nel frattempo è provare e pensare a un'alternativa un po 'più semplice che richiede meno JavaScript. Aggiornerò di nuovo la mia domanda In 8 ore posso aggiungere la mia taglia (che sarà almeno 160) Grazie per la risposta! Bedankt –

+0

@GustvandeWal: Le linee/parole che vengono espulse è una conseguenza delle stesse caselle fluttuanti, vedi ad esempio questo caso non JS: http://jsfiddle.net/d5o1uja0/9/ (e prova ad aumentare da 443 a 444 per confermare che 443 è in realtà il miglior numero assoluto) –

Problemi correlati